You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Browse filesBrowse the repository at this point in the historyBrowse files
authored
Enable feature flags via URL query parameter (?features=) for headerless hosted connections (#3146)
* fix(http): preserve feature query across OAuth resource metadata
Review on #3146 identified that a query-bearing MCP server URL breaks
OAuth protected-resource metadata discovery: go-sdk v1.7.0 validates
metadata.resource with exact string equality against the full server
URL, but BuildResourceMetadataURL and buildResourceURL dropped the
request's RawQuery, so clients connecting to e.g.
/mcp/x/issues?features=issue_dependencies
received challenge and metadata URLs without the query and could reject
the metadata as belonging to a different resource (RFC 9728).
- Preserve r.URL.RawQuery in both the advertised resource_metadata URL
and the metadata document's resource via a shared AppendQuery helper.
- Make feature selection presence-based: the features query parameter
and the X-MCP-Features header are separate channels that are never
combined; query wins when both are present.
- Extend TestOAuthChallengeMetadataRouteContracts with a query-bearing
MCP URL round-trip (challenge URL + metadata.resource exact match).
- Add TestWithRequestConfigFeatureSelection covering all four channel
combinations, plus unit tests for query preservation in
TestBuildResourceMetadataURL.
* fix(http): give feature header precedence over query
* fix(http): harden URL feature flag handling
Preserve exact OAuth resource queries across route variants, retain presence-based header precedence, and mark feature-dependent responses with Vary.
Expand request, allowlist, metadata, route, and cache behavior coverage.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Shurong Cao <170531907+CAOShurong@users.noreply.github.com>
Co-authored-by: Sam Morrow <sammorrowdrums@github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- HTTP server: `X-MCP-Features: <flag>,<flag>` request header or a
204
+
`?features=<flag>,<flag>` server URL. Header presence takes precedence,
205
+
and the two request channels are never combined.
204
206
2.**Allowlist filter.** User-supplied flags are filtered against [`AllowedFeatureFlags`](../pkg/github/feature_flags.go). Anything not on the allowlist is silently dropped — flags missing from the allowlist can only be turned on by remote-server feature management, not by end users.
205
207
3.**Insiders expansion.** If insiders mode is on (`--insiders`, `/insiders` route, or `X-MCP-Insiders: true`), every flag in [`InsidersFeatureFlags`](../pkg/github/feature_flags.go) is unioned in. The insiders expansion is **not** re-validated against the allowlist — insiders is a server-controlled switch that can reach internal-only flags.
206
208
4.**Server-side fallback (remote server only).** Any flag not yet decided falls back to the remote server's feature manager, which can roll a feature out independently of user input or insiders membership.
@@ -214,7 +216,8 @@ Insiders is a **meta feature flag** — the same shape as `default` or `all` for
214
216
### Adding a new feature flag
215
217
216
218
1. Add a constant in `pkg/github/feature_flags.go`.
217
-
2. Add it to `AllowedFeatureFlags` if end users should be able to opt in via `--features` / `X-MCP-Features`.
219
+
2. Add it to `AllowedFeatureFlags` if end users should be able to opt in via
220
+
`--features`, `X-MCP-Features`, or the `features` URL query parameter.
218
221
3. Add it to `InsidersFeatureFlags` if insiders mode should turn it on automatically.
219
222
4. Gate the behavior on the concrete flag (`deps.IsFeatureEnabled(ctx, FeatureFlagX)`), never on `cfg.InsidersMode`. There is a `TestGitHubPackageDoesNotReadInsidersMode` guard test that fails if `pkg/github` reads `InsidersMode` directly.
220
223
5. The MCP-diff CI workflow picks up new entries in `AllowedFeatureFlags` automatically — see `.github/workflows/mcp-diff.yml`.
0 commit comments