modelcontextprotocol / modelcontextprotocol/ext-server-card
Reference implementation showcase: GitHub MCP Server card + AI/MCP catalog (live wire formats & routes)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 8
- Forks
- 5
- PR merge metrics
- No merged PRs in 30d
Description
Reference implementation showcase — GitHub MCP Server
A working reference implementation of SEP-2127 (Server Card) + AI Catalog discovery for the GitHub MCP Server is now wired end-to-end across three documents. This issue captures the live wire formats and routes so the WG can sanity-check the shape against the spec. Values below were captured from a running build with dev hostnames substituted for production (github.com, api.githubcopilot.com); icon data: URIs are elided for readability.
Discovery flow
flowchart LR
C[Client] -->|GET /.well-known/ai-catalog.json| A[github.com]
A -->|entry.url| SC[api.githubcopilot.com/mcp/server-card]
C -->|GET server-card| SC
SC -->|remotes0.url| M[api.githubcopilot.com/mcp/]
C -->|connect streamable-http| M
Routes
| Document | Route | Served by | Media type |
|---|---|---|---|
| AI Catalog | GET https://github.com/.well-known/ai-catalog.json |
github.com | application/ai-catalog+json |
| MCP Catalog (transitional) | GET https://github.com/.well-known/mcp/catalog.json |
github.com | application/json |
| Server Card | GET https://api.githubcopilot.com/mcp/server-card |
hosted GitHub MCP Server | application/mcp-server-card+json |
Per-environment hosts (same shapes, host varies):
| Env | Catalog host | Card host |
|---|---|---|
| github.com (dotcom) | github.com |
api.githubcopilot.com |
| Proxima / data-residency | {tenant}.ghe.com |
copilot-api.{tenant}.ghe.com |
| GHES | not served | not served |
The card host is derived per-request (e.g. from X-Forwarded-Host) so a single implementation serves every tenant; GHES is deliberately excluded.
Shared HTTP behavior (all three endpoints)
- CORS (read-only):
Access-Control-Allow-Origin: *,Access-Control-Allow-Methods: GET,Access-Control-Allow-Headers: Content-Type - Caching:
Cache-Control: public, max-age=3600 - Conditional requests: strong/weak
ETag+If-None-Match→304 Not Modified(this is exactly the SHOULD proposed in #33) - Content negotiation on
Accept - No authentication — all three are public metadata
1. Server Card — application/mcp-server-card+json
GET https://api.githubcopilot.com/mcp/server-card
{
"$schema": "https://static.modelcontextprotocol.io/schemas/v1/server-card.schema.json",
"name": "io.github.github/github-mcp-server",
"version": "1.4.0",
"description": "Connect AI assistants to GitHub - manage repos, issues, PRs, and workflows through natural language.",
"title": "GitHub",
"websiteUrl": "https://github.com/github/github-mcp-server",
"repository": {
"url": "https://github.com/github/github-mcp-server",
"source": "github",
"id": "942771284"
},
"icons": [
{ "src": "data:image/png;base64,iVBORw0KGgoAAAANSUh…(GitHub mark, light)", "mimeType": "image/png", "sizes": ["24x24"], "theme": "light" },
{ "src": "data:image/png;base64,iVBORw0KGgoAAAANSUh…(GitHub mark, dark)", "mimeType": "image/png", "sizes": ["24x24"], "theme": "dark" }
],
"remotes": [
{
"type": "streamable-http",
"url": "https://api.githubcopilot.com/mcp/",
"headers": [
{
"description": "Authorization header with authentication token (PAT or App token)",
"isRequired": true,
"isSecret": true,
"name": "Authorization"
}
],
"supportedProtocolVersions": ["2025-11-25", "2025-06-18", "2025-03-26", "2024-11-05"]
}
]
}
Notes:
- Remote-only: no
packages, no enumerated primitives (tools/resources/prompts) — those stay in the MCP Registryserver.jsonand runtime listing, per the card/remote-only shape. name,title,description,repositoryare kept identical to the Registry document so the card and registry entry describe the same server.versionmirrors the runtimeserverInfo.version.- Icons are embedded as self-contained
data:URIs (no external image dependency) and emitted in a fixed order so the body — and therefore the ETag — is deterministic. - For Proxima the single remote
urlbecomeshttps://copilot-api.{tenant}.ghe.com/mcp/.
2. AI Catalog — application/ai-catalog+json (spec_version 1.0)
GET https://github.com/.well-known/ai-catalog.json
{
"spec_version": "1.0",
"entries": [
{
"identifier": "urn:air:github.github.io:github-mcp-server",
"display_name": "GitHub MCP Server",
"media_type": "application/mcp-server-card+json",
"url": "https://api.githubcopilot.com/mcp/server-card",
"description": "Connect AI assistants to GitHub - manage repos, issues, PRs, and workflows through natural language."
}
]
}
identifieris the AIR URN derived deterministically from the canonical card nameio.github.github/github-mcp-server→ reverse namespaceio.github.github→github.github.io→urn:air:github.github.io:github-mcp-server.urlequals the Server Card URL above (the integration contract), andmedia_typeadvertises what the client will receive there.
3. MCP Catalog (transitional subset) — application/json (specVersion draft)
GET https://github.com/.well-known/mcp/catalog.json
{
"specVersion": "draft",
"entries": [
{
"identifier": "urn:air:github.github.io:github-mcp-server",
"displayName": "GitHub MCP Server",
"mediaType": "application/mcp-server-card+json",
"url": "https://api.githubcopilot.com/mcp/server-card",
"description": "Connect AI assistants to GitHub - manage repos, issues, PRs, and workflows through natural language."
}
]
}
- This is a structural subset of the AI Catalog entry (camelCase,
displayNameinstead ofdisplay_name), served alongside the forwardai-catalog.jsonfor present-day clients. The forwardapplication/ai-catalog+jsondocument is the primary; the MCP Catalog is transitional — relevant to the direction in #26.
Relation to open WG threads
- #11 (slash path): the card is reachable at the slash form
…/mcp/server-card. - #16 (reference implementation): complements the python-sdk reference; a go-sdk convenience helper ports the same
build_server_card/mount_server_cardAPI. - #33 (ETag SHOULD): implemented on all three endpoints (strong ETag, weak
If-None-Matchcomparison,304). - #14 (optional
displayName): entries currently setdisplay_name/displayName; happy to drop to track the AI Catalog upstream decision.
Happy to expose a live endpoint or share the full (un-elided) bodies if useful for conformance testing.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the three described discovery endpoints and comparing their live wire formats, routes, headers, caching, and host behavior with the referenced SEP-2127 and AI Catalog expectations. The issue names no source files or tests, so completion is a WG sanity check or conformance finding rather than a defined code change.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, python, typescript
- Domain
- api, documentation
- Issue type
- Documentation
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100