Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
d85134c
feat(mcp): add mount path helpers for multi-server mounts
asoorm Aug 10, 2026
844d887
refactor(mcp): give the MCP server its own mount path and route regis…
asoorm Aug 10, 2026
ee8bbe9
fix(mcp): derive OAuth resource identifier and metadata path from the…
asoorm Aug 10, 2026
513d6b1
feat(mcp): add the mcp.servers config map
asoorm Aug 10, 2026
736064a
fix(mcp): correct mount path validation for short and double-slash paths
asoorm Aug 10, 2026
5a99bba
feat(mcp): validate mount paths across the servers map
asoorm Aug 10, 2026
78e8084
test(mcp): assert deterministic error order across map iterations
asoorm Aug 10, 2026
cdaeec8
refactor(mcp): move listener and mux ownership into a Host type
asoorm Aug 10, 2026
1385b18
feat(mcp): mount one server per mcp.servers entry on a shared listener
asoorm Aug 10, 2026
e39bcb1
fix(mcp): scope router_url to deprecated path and close partial builds
asoorm Aug 10, 2026
845d31a
fix(mcp): keep an unreadable collection from failing the whole reload
asoorm Aug 10, 2026
2f95ae7
test(mcp): assert bad server tools to give the reload isolation test …
asoorm Aug 10, 2026
359b5bb
docs(mcp): document the mcp.servers map and the migration path
asoorm Aug 10, 2026
0b7ce0a
fix(mcp): apply session and scope defaults to mcp.servers entries
asoorm Aug 10, 2026
b6d33fc
docs(mcp): correct review findings and style violations
asoorm Aug 10, 2026
29dd40e
fix(mcp): scope max scope combinations fallback to servers map
asoorm Aug 10, 2026
73878c5
fix(mcp): reject root mount path and unblock oauth scope limit
asoorm Aug 10, 2026
89ac4f5
docs(mcp): split compound sentences in the failure isolation section
asoorm Aug 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs-website/router/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,12 @@ introspection:

The Model Context Protocol (MCP) server allows AI models to discover and interact with your GraphQL API in a secure way.

<Info>
This table documents the deprecated, single-server options. Use `mcp.servers` to run one or more MCP servers from
one router. See [MCP Configuration](/router/mcp/configuration#running-multiple-mcp-servers) for the full
reference, including the migration path from these options.
</Info>

Comment on lines +332 to +337

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Correct the scope of the deprecation notice.

The block marks the whole table as deprecated. The table includes mcp.enabled (Line 340) and mcp.server.listen_addr (Line 341). docs-website/router/mcp/configuration.mdx Lines 249-250 state that mcp.server.listen_addr and mcp.server.base_url are not deprecated, and Lines 121-122 state that mcp.enabled still controls all servers. Name the exceptions here so the two pages agree.

📝 Proposed wording fix
 <Info>
-  This table documents the deprecated, single-server options. Use `mcp.servers` to run one or more MCP servers from
-  one router. See [MCP Configuration](/router/mcp/configuration#running-multiple-mcp-servers) for the full
-  reference, including the migration path from these options.
+  Most options in this table are deprecated single-server options. `mcp.enabled` and `mcp.server.listen_addr`
+  remain current. They control all MCP servers and the shared listener. Use `mcp.servers` to run one or more MCP
+  servers from one router. See [MCP Configuration](/router/mcp/configuration#running-multiple-mcp-servers) for the
+  full reference, including the migration path from these options.
 </Info>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Info>
This table documents the deprecated, single-server options. Use `mcp.servers` to run one or more MCP servers from
one router. See [MCP Configuration](/router/mcp/configuration#running-multiple-mcp-servers) for the full
reference, including the migration path from these options.
</Info>
<Info>
Most options in this table are deprecated single-server options. `mcp.enabled` and `mcp.server.listen_addr`
remain current. They control all MCP servers and the shared listener. Use `mcp.servers` to run one or more MCP
servers from one router. See [MCP Configuration](/router/mcp/configuration#running-multiple-mcp-servers) for the
full reference, including the migration path from these options.
</Info>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs-website/router/configuration.mdx` around lines 332 - 337, Update the
deprecation notice in the Info block before the single-server options table to
explicitly exclude mcp.enabled, mcp.server.listen_addr, and mcp.server.base_url
from the deprecated options. Keep the migration guidance for the remaining
single-server options and align the wording with the MCP Configuration page.

| Environment Variable | YAML | Required | Description | Default Value |
| ------------------------------- | ------------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------- |
| MCP_ENABLED | mcp.enabled | <Icon icon="square" /> | Enable or disable the MCP server | false |
Expand Down
280 changes: 279 additions & 1 deletion docs-website/router/mcp/configuration.mdx

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions docs-website/router/mcp/oauth/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,18 @@ GET /.well-known/oauth-protected-resource/mcp

This follows the [RFC 9728](https://datatracker.ietf.org/doc/rfc9728/) path-aware format. MCP clients use this endpoint to automatically discover the authorization server and all supported scopes.

<Info>
This example uses `mcp.server.base_url` and the default `/mcp` path from the deprecated single-server form. With
`mcp.servers`, each server publishes its own metadata at its own `base_url` and `path`. See
[Multiple Servers with OAuth Behind a Load Balancer](/router/mcp/configuration#multiple-servers-with-oauth-behind-a-load-balancer).
</Info>
Comment on lines +127 to +131

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect how the resource identifier and metadata path are derived from base_url and mount path.
set -uo pipefail

fd -t f 'paths.go|paths_test.go|server.go' router/pkg/mcpserver --exec rg -n -C 6 'oauth-protected-resource|Resource|base_url|BaseURL|MountPath'

Repository: wundergraph/cosmo

Length of output: 13681


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- OAuth configuration example ---'
sed -n '110,155p' docs-website/router/mcp/oauth/configuration.mdx

printf '%s\n' '--- Multiple-server configuration reference ---'
sed -n '220,245p' docs-website/router/mcp/configuration.mdx

printf '%s\n' '--- base_url and path references in the OAuth documentation ---'
rg -n -C 3 'base_url|oauth\.jwks|audiences|resource' docs-website/router/mcp/oauth/configuration.mdx docs-website/router/mcp/configuration.mdx

Repository: wundergraph/cosmo

Length of output: 29131


Include /mcp in the resource identifier examples. The server emits https://mcp.example.com/mcp for the default /mcp mount path. Update the resource response and oauth.jwks[].audiences values to match.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs-website/router/mcp/oauth/configuration.mdx` around lines 127 - 131, The
OAuth configuration examples must use the full resource identifier including the
default /mcp path. Update the resource response and oauth.jwks[].audiences
example values from the host-only URL to https://mcp.example.com/mcp, while
preserving the surrounding configuration and explanatory text.


<Warning>
Without a matching audience, the router accepts a token minted for one MCP server on every other server. When
you run more than one MCP server with OAuth, set `oauth.jwks[].audiences` on each server to that server's
resource identifier.
</Warning>

**Example response:**

```json
Expand Down
6 changes: 3 additions & 3 deletions router/core/graph_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -1610,9 +1610,9 @@ func (s *graphServer) buildGraphMux(
operationPlanner := NewOperationPlanner(executor, gm.planCache, gm.planFallbackCache, s.planningDurationOverride)

// We support the MCP only on the base graph. Feature flags are not supported yet.
if opts.IsBaseGraph() && s.mcpServer != nil {
if mErr := s.mcpServer.Reload(executor.ClientSchema, opts.EngineConfig.FieldConfigurations); mErr != nil {
return nil, fmt.Errorf("failed to reload MCP server: %w", mErr)
if opts.IsBaseGraph() && s.mcpHost != nil {
if mErr := s.mcpHost.Reload(executor.ClientSchema, opts.EngineConfig.FieldConfigurations); mErr != nil {
return nil, fmt.Errorf("failed to reload MCP servers: %w", mErr)
}
}

Expand Down
Loading
Loading