| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
There was a problem hiding this comment.
Adds MCP Server Card discovery support for the GitHub MCP Server.
Changes:
| File | Description |
|---|---|
| pkg/http/servercard/card.go | Defines card types and construction. |
| pkg/http/servercard/card_test.go | Tests card metadata and serialization. |
| pkg/http/servercard/handler.go | Implements HTTP serving and negotiation. |
| pkg/http/servercard/handler_test.go | Tests handler behavior and caching. |
| pkg/http/server.go | Registers the card endpoint. |
| pkg/http/server_test.go | Tests router and CORS isolation. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Sorry, something went wrong.
There was a problem hiding this comment.
pkg/http/servercard/handler.go:181
if i := strings.IndexByte(mediaRange, ';'); i >= 0 {
mediaRange = strings.TrimSpace(mediaRange[:i])
}
switch strings.ToLower(mediaRange) {
case MediaType, "*/*", "application/*":
return true
pkg/http/servercard/handler.go:63
if !acceptsCard(r.Header.Get(headers.AcceptHeader)) {
Sorry, something went wrong.
There was a problem hiding this comment.
pkg/http/servercard/handler.go:112
if ifNoneMatchSatisfied(r.Header.Get("If-None-Match"), etag) {
pkg/http/servercard/handler.go:204
// parseMediaRange splits one Accept media range into its lowercased media type
// and quality value. The quality defaults to 1.0 when no valid q parameter is
// present; only the q parameter is interpreted and other parameters are ignored.
func parseMediaRange(part string) (mediaType string, quality float64) {
Sorry, something went wrong.
There was a problem hiding this comment.
Accept parsing mishandles quoted commas and can ignore an explicit q=0.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Balanced
Findings: 1
| Severity | Finding |
|---|---|
| pkg/http/servercard/handler.go — strings.SplitSeq(accept, ",") does not parse a valid HTTP list when a media parameter contains a… |
Sorry, something went wrong.
There was a problem hiding this comment.
Accept parameter matching and destructive Vary handling can produce incorrect cache and negotiation behavior.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Balanced
Findings: 3
| Severity | Finding |
|---|---|
| pkg/http/servercard/handler.go — Using Set here discards any existing Vary values added by the remote deployment's middleware.… | |
| pkg/http/servercard/handler.go — Accept media parameters before q participate in matching under RFC 9110; they cannot be… |
| Severity | Finding |
|---|---|
| pkg/http/servercard/handler.go — strings.SplitSeq(accept, ",") does not parse a valid HTTP list when a media parameter contains a… View comment |
Sorry, something went wrong.
There was a problem hiding this comment.
Conditional ETag matching mishandles valid backslashes, and the stated diff size is inaccurate.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Balanced
Findings: 1 · 1
| Severity | Finding |
|---|---|
| pkg/http/servercard/handler.go — splitList applies quoted-string backslash escaping, but RFC 9110 entity-tags use opaque-tag,… | |
| pkg/http/servercard/card_test.go — The validation summary says this PR contains 780 additions across these four files, but the… |
| Severity | Finding |
|---|---|
| pkg/http/servercard/handler.go — Accept media parameters before q participate in matching under RFC 9110; they cannot be… View resolved comment | |
| pkg/http/servercard/handler.go — Using Set here discards any existing Vary values added by the remote deployment's middleware.… View resolved comment | |
| pkg/http/servercard/handler.go — strings.SplitSeq(accept, ",") does not parse a valid HTTP list when a media parameter contains a… View resolved comment |
Sorry, something went wrong.
There was a problem hiding this comment.
Accept extensions named q can override an earlier explicit zero-quality refusal.
Review tier: Balanced
Findings: 1 · 1
| Severity | Finding |
|---|---|
| pkg/http/servercard/handler.go — splitList applies quoted-string backslash escaping, but RFC 9110 entity-tags use opaque-tag,… View comment | |
| pkg/http/servercard/card_test.go — The validation summary says this PR contains 780 additions across these four files, but the… View comment |
pkg/http/servercard/handler.go:208
if strings.EqualFold(strings.TrimSpace(name), "q") {
Sorry, something went wrong.
Define the GitHub MCP Server's Server Card (SEP-2127, in review) and a public no-auth HTTP handler that serves it at the canonical /server-card backend path. OSS owns all stable identity/metadata and serving behavior; the remote server only supplies an environment-specific remote URL. Negotiate Accept and If-None-Match as RFC 9110 list values across repeated header field-lines. Accept honors quoted commas, media-range parameters, and q-values (q=0 rejects); entity-tag lists split on quoted commas without backslash escaping, since an opaque-tag treats a backslash literally. Vary lists Accept and X-Forwarded-Host and is appended rather than set: it composes with values added by deployment middleware and, since the response is publicly cacheable and multi-tenant deployments derive the remote URL from the trusted X-Forwarded-Host, it keeps a shared cache from serving one tenant's card to another. Refs github/copilot-mcp-core#1855, epic github/copilot-mcp-core#1853 Spec: modelcontextprotocol/experimental-ext-server-card Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4a9f522f-6942-4b77-98a4-b2d42f19625d
There was a problem hiding this comment.
The implementation matches the stated remote-only design and is thoroughly covered by focused tests.
Review tier: Balanced
Findings: 1
| Severity | Finding |
|---|---|
| pkg/http/servercard/card_test.go — The validation summary says this PR contains 780 additions across these four files, but the… View comment |
| Severity | Finding |
|---|---|
| pkg/http/servercard/handler.go — splitList applies quoted-string backslash escaping, but RFC 9110 entity-tags use opaque-tag,… View resolved comment |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
What & why
Makes the GitHub MCP Server discoverable via an MCP Server Card. Adds a new OSS-owned package pkg/http/servercard with:
Ownership: this package owns the Server Card implementation and all stable GitHub MCP identity/metadata, but the card is mounted and hosted only by the remote deployment (github/github-mcp-server-remote), which supplies the environment-specific remote URL and reuses this serving logic verbatim. The standalone OSS server does not advertise the card, so self-hosted binaries never falsely claim the dotcom remote.
Card shape (remote-only, minimal)
The card is deliberately remote-only and minimal — it advertises identity + a single streamable-http remote and omits tools/resources/prompts and installable packages (those stay in the registry server.json). This is the exact JSON emitted for github.com:
{ "$schema": "https://static.modelcontextprotocol.io/schemas/v1/server-card.schema.json", "name": "io.github.github/github-mcp-server", "version": "<build version>", "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" }, "remotes": [ { "type": "streamable-http", "url": "https://api.githubcopilot.com/mcp/" } ] }The name is locked to io.github.github/github-mcp-server, matching the registry server.json. It is the stable Server Card / registry server identity; the AI Catalog identifier is assigned independently and is not derived from the card name.
Serving behavior (per discovery.md)
RegisterRoutes mounts the card at the single reserved /server-card path. A composition test guards that route against being shadowed by an MCP catch-all mount (r.Mount("/", h)), so the remote can register both on one router.
Reuse by the hosted/remote deployment
The hosted deployment is multi-tenant, so the remote URL (and therefore the card body + ETag) varies per request. To keep header/ETag logic byte-for-byte identical across OSS and the remote, the handler exposes:
Deliberately omitted (kept minimal)
Validation
Refs: github/copilot-mcp-core#1855 · epic github/copilot-mcp-core#1853