Skip to content

Commit 0c3fe34

Browse files
committed
docs(mcp): restructure MCP docs and add OAuth 2.1 authorization (ENG-9125)
Restructure MCP docs from single page into multi-page architecture (overview, quickstart, operations, configuration, oauth, ide-setup). Add OAuth 2.1 scope enforcement docs with JWKS config, multi-level scope gates, step-up authorization, and RFC 9728 metadata discovery. Reference @requiresScopes federation docs instead of re-explaining.
1 parent 2c12f78 commit 0c3fe34

7 files changed

Lines changed: 1064 additions & 377 deletions

File tree

docs/docs.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,18 @@
9898
"router/configuration/template-expressions"
9999
]
100100
},
101-
"router/mcp",
101+
{
102+
"group": "MCP Gateway",
103+
"icon": "robot",
104+
"pages": [
105+
"router/mcp",
106+
"router/mcp/quickstart",
107+
"router/mcp/operations",
108+
"router/mcp/configuration",
109+
"router/mcp/oauth",
110+
"router/mcp/ide-setup"
111+
]
112+
},
102113
{
103114
"group": "Custom Modules",
104115
"icon": "cubes",

docs/router/mcp.mdx

Lines changed: 57 additions & 376 deletions
Large diffs are not rendered by default.

docs/router/mcp/configuration.mdx

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
---
2+
title: "Configuration"
3+
description: "Complete reference for all MCP Gateway configuration options, including session handling, storage providers, and environment variables."
4+
icon: "sliders-up"
5+
---
6+
7+
## Basic Configuration
8+
9+
To enable MCP in your Cosmo Router, add the following to your `config.yaml`:
10+
11+
```yaml
12+
mcp:
13+
enabled: true
14+
server:
15+
listen_addr: "localhost:5025"
16+
graph_name: "my-graph"
17+
exclude_mutations: true
18+
storage:
19+
provider_id: "mcp"
20+
21+
storage_providers:
22+
file_system:
23+
- id: "mcp"
24+
path: "operations"
25+
```
26+
27+
## Configuration Options
28+
29+
| Option | Description | Default |
30+
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
31+
| `enabled` | Enable or disable the MCP server | `false` |
32+
| `server.listen_addr` | The address and port where the MCP server will listen for requests | `localhost:5025` |
33+
| `server.base_url` | The public base URL of the MCP server. **Required when OAuth is enabled.** Used for the RFC 9728 metadata endpoint and `resource_metadata` in `WWW-Authenticate` headers. Set this to your externally-reachable URL when behind a reverse proxy or load balancer. | - |
34+
| `router_url` | Custom URL to use for the router GraphQL endpoint in MCP responses. Use this when your router is behind a proxy. | - |
35+
| `storage.provider_id` | The ID of a storage provider to use for loading GraphQL operations. Only `file_system` providers are supported. | - |
36+
| `session.stateless` | Whether the MCP server should operate in stateless mode. When `true`, no server-side session state is maintained between requests. | `true` |
37+
| `graph_name` | The name of the graph this router exposes via MCP. Converted to kebab-case and used to build the MCP server name (`wundergraph-cosmo-<kebab-case-name>`) and for logging; it does not select a different graph. For example, `MyGraph` becomes `wundergraph-cosmo-my-graph`. | `mygraph` |
38+
| `exclude_mutations` | Whether to exclude mutation operations from being exposed | `false` |
39+
| `enable_arbitrary_operations` | Enables the `execute_graphql` built-in tool, allowing clients to run arbitrary GraphQL operations beyond the pre-defined operation set. | `false` |
40+
| `expose_schema` | Enables the `get_schema` built-in tool, exposing the full GraphQL schema to MCP clients. | `false` |
41+
| `omit_tool_name_prefix` | When enabled, MCP tool names omit the `execute_operation_` prefix. For example, `GetUser` becomes `get_user` instead of `execute_operation_get_user`. See [Operations — Omitting the Tool Name Prefix](/router/mcp/operations#omitting-the-tool-name-prefix). | `false` |
42+
43+
For OAuth-specific configuration, see [OAuth 2.1 Authorization](/router/mcp/oauth).
44+
45+
## Environment Variables
46+
47+
All MCP options can also be set via environment variables:
48+
49+
| Environment Variable | Configuration Path |
50+
| -------------------------------- | ------------------------------------ |
51+
| `MCP_ENABLED` | `mcp.enabled` |
52+
| `MCP_SERVER_LISTEN_ADDR` | `mcp.server.listen_addr` |
53+
| `MCP_SERVER_BASE_URL` | `mcp.server.base_url` |
54+
| `MCP_ROUTER_URL` | `mcp.router_url` |
55+
| `MCP_STORAGE_PROVIDER_ID` | `mcp.storage.provider_id` |
56+
| `MCP_SESSION_STATELESS` | `mcp.session.stateless` |
57+
| `MCP_GRAPH_NAME` | `mcp.graph_name` |
58+
| `MCP_EXCLUDE_MUTATIONS` | `mcp.exclude_mutations` |
59+
| `MCP_ENABLE_ARBITRARY_OPERATIONS`| `mcp.enable_arbitrary_operations` |
60+
| `MCP_EXPOSE_SCHEMA` | `mcp.expose_schema` |
61+
| `MCP_OMIT_TOOL_NAME_PREFIX` | `mcp.omit_tool_name_prefix` |
62+
63+
When OAuth is enabled, the following additional environment variables are available:
64+
65+
| Environment Variable | Configuration Path |
66+
| ------------------------------------------------- | --------------------------------------------------- |
67+
| `MCP_OAUTH_ENABLED` | `mcp.oauth.enabled` |
68+
| `MCP_OAUTH_AUTHORIZATION_SERVER_URL` | `mcp.oauth.authorization_server_url` |
69+
| `MCP_OAUTH_SCOPE_CHALLENGE_INCLUDE_TOKEN_SCOPES` | `mcp.oauth.scope_challenge_include_token_scopes` |
70+
71+
## Storage Providers
72+
73+
MCP loads operations from a configured file system storage provider. This allows you to centralize the configuration of operation sources:
74+
75+
```yaml
76+
storage_providers:
77+
file_system:
78+
- id: "mcp"
79+
path: "operations" # Relative to the router binary
80+
```
81+
82+
Then reference this storage provider in your MCP configuration:
83+
84+
```yaml
85+
mcp:
86+
storage:
87+
provider_id: "mcp"
88+
```
89+
90+
A storage provider **must** be specified to load GraphQL operations. See [Storage Providers](/router/storage-providers) for more details on configuring storage providers.
91+
92+
## Session Handling
93+
94+
The MCP server uses the Streamable HTTP transport and maintains per-session state via the `Mcp-Session-Id` header. When deploying multiple Router instances, you need **sticky sessions** to ensure all requests for a session reach the same instance.
95+
96+
To configure sticky sessions:
97+
98+
1. The Router returns a unique `Mcp-Session-Id` response header when a session is established
99+
2. Clients must include that value in subsequent requests as the `Mcp-Session-Id` request header
100+
3. Your load balancer or reverse proxy must route requests with the same `Mcp-Session-Id` to the same instance
101+
102+
For details, see your load balancer or reverse proxy documentation (e.g., [F5 NGINX Plus — MCP Session Affinity](https://community.f5.com/kb/technicalarticles/mcp-session-affinity-with-f5-nginx-plus/341961)).
103+
104+
<Info>
105+
The `session.stateless` configuration option is reserved for future use. Currently, the MCP server always operates in stateful mode regardless of this setting.
106+
</Info>
107+
108+
## CORS
109+
110+
The MCP server automatically configures CORS to allow cross-origin requests from MCP clients. It sets `Access-Control-Allow-Origin: *` and allows the required MCP headers (`Mcp-Protocol-Version`, `Mcp-Session-Id`, `Authorization`, `Last-Event-ID`). The `Mcp-Session-Id` and `WWW-Authenticate` headers are exposed in responses. If you have additional CORS headers configured on the router, they are merged with the MCP-specific headers.
111+
112+
## Full Configuration Example
113+
114+
```yaml
115+
mcp:
116+
enabled: true
117+
server:
118+
listen_addr: "localhost:5025"
119+
router_url: "https://your-public-router-url.example.com/graphql"
120+
graph_name: "my-graph"
121+
exclude_mutations: true
122+
enable_arbitrary_operations: false
123+
expose_schema: false
124+
omit_tool_name_prefix: false
125+
storage:
126+
provider_id: "mcp"
127+
128+
storage_providers:
129+
file_system:
130+
- id: "mcp"
131+
path: "operations"
132+
```

docs/router/mcp/ide-setup.mdx

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
---
2+
title: "IDE & AI Tool Setup"
3+
description: "Connect Claude Desktop, Cursor, Windsurf, VS Code, and other AI tools to your MCP Gateway. Includes header forwarding for authentication and tracing."
4+
icon: "display-code"
5+
---
6+
7+
This guide covers how to connect popular AI tools to your Cosmo Router MCP server and configure header forwarding for authentication, tracing, and custom headers.
8+
9+
## Header Forwarding
10+
11+
<Info>
12+
Available since Router [0.260.0](https://github.com/wundergraph/cosmo/releases/tag/router%400.260.0)
13+
</Info>
14+
15+
The MCP server forwards **all headers** from MCP clients to the Router, including authorization headers, custom headers, and tracing headers. This allows you to:
16+
17+
- Leverage all authentication and authorization capabilities of your Cosmo Router
18+
- Pass custom headers for tracing, debugging, or application-specific purposes
19+
- Maintain consistent security and observability across all API consumers
20+
21+
<Info>
22+
All headers sent by MCP clients are forwarded through the complete chain: MCP Client → MCP Server → Router → Subgraphs. The router's [header forwarding rules](/router/proxy-capabilities/subgraph-request-header-operations) determine what ultimately reaches your subgraphs.
23+
</Info>
24+
25+
## IDE Setup Guides
26+
27+
### Cursor
28+
29+
<Note>Requires Cursor v0.48.0+ for Streamable HTTP support.</Note>
30+
31+
Go to **Settings** > **Tools & Integrations** > **MCP Servers** and add the following to the `mcp.json` file:
32+
33+
```json
34+
{
35+
"mcpServers": {
36+
"my-graph": {
37+
"url": "http://localhost:5025/mcp",
38+
"headers": {
39+
"Authorization": "Bearer YOUR_API_KEY",
40+
"X-Trace-Id": "cursor-session-123",
41+
"X-Client": "cursor"
42+
}
43+
}
44+
}
45+
}
46+
```
47+
48+
All `headers` fields are optional — include only what your setup requires.
49+
50+
### Claude Desktop
51+
52+
Requires the latest version of Claude Desktop. Go to **Settings** > **Developer** and click on **Edit Config**. Add the following to the `claude_desktop_config.json` file:
53+
54+
```json
55+
{
56+
"mcpServers": {
57+
"my-graph": {
58+
"command": "npx",
59+
"args": ["-y", "mcp-remote", "http://localhost:5025/mcp"]
60+
}
61+
}
62+
}
63+
```
64+
65+
After saving, **restart Claude Desktop** for changes to take effect.
66+
67+
### Windsurf
68+
69+
Windsurf supports Streamable HTTP servers with a `serverUrl` field:
70+
71+
```json
72+
{
73+
"mcpServers": {
74+
"my-graph": {
75+
"serverUrl": "http://localhost:5025/mcp",
76+
"headers": {
77+
"Authorization": "Bearer YOUR_API_KEY",
78+
"X-Trace-Id": "windsurf-session-456",
79+
"X-Client": "windsurf"
80+
}
81+
}
82+
}
83+
}
84+
```
85+
86+
### VS Code
87+
88+
Click **View** > **Command Palette** > **MCP: Add Server** and use the URL `http://localhost:5025/mcp` to complete the configuration.
89+
90+
For more information, see the [VS Code MCP Servers documentation](https://code.visualstudio.com/docs/copilot/chat/mcp-servers).
91+
92+
### Other MCP-compatible Tools
93+
94+
Other tools and AI models that support the MCP protocol typically provide similar ways to configure the server URL and authentication headers. Check the documentation for your specific AI tool for the exact configuration syntax.
95+
96+
## Common Header Patterns
97+
98+
### Authentication & Authorization
99+
100+
Pass authorization tokens to secure your GraphQL operations:
101+
102+
```json
103+
{
104+
"headers": {
105+
"Authorization": "Bearer YOUR_API_KEY"
106+
}
107+
}
108+
```
109+
110+
### Tracing
111+
112+
Include trace IDs for request correlation and debugging:
113+
114+
```json
115+
{
116+
"headers": {
117+
"X-Trace-Id": "trace-123",
118+
"X-Request-Id": "req-456"
119+
}
120+
}
121+
```
122+
123+
### Custom Headers
124+
125+
Pass application-specific headers for business logic:
126+
127+
```json
128+
{
129+
"headers": {
130+
"X-Tenant-Id": "tenant-abc",
131+
"X-Feature-Flag": "new-feature-enabled"
132+
}
133+
}
134+
```

0 commit comments

Comments
 (0)