[Ahmet Soormally](/content/people/ahmet-soormally/index.html)

Principal Solutions Engineer at WunderGraph

June 9, 2026·9min read

The Cosmo Router MCP Gateway exposes your federated GraphQL schema to AI agents as reviewed, OAuth-scoped MCP tools. This is the implementation companion to [Don't Let AI Agents Improvise Against Production GraphQL](/content/blog/governing-ai-agent-access-to-graphql-mcp-gateway/index.html), which makes the case for the pattern: let agents discover in development, but only let them execute reviewed operations in production. Here we build it on the [Cosmo Router](https://cosmo-docs.wundergraph.com/router) MCP Gateway, end to end: the two postures, how operations become tools, OAuth scopes, and what happens when your schema changes.

## One MCP server, two postures

The MCP Gateway is a feature of the Cosmo Router. It speaks the `2025-06-18` MCP specification over Streamable HTTP, and AI platforms like Claude, Cursor, and Windsurf connect to it directly. It operates on your composed supergraph, so a single tool call can resolve data across every subgraph in your federation. There is no separate service to deploy.

Two configuration flags define its posture:

- `expose_schema` controls whether agents can read your full schema.
- `enable_arbitrary_operations` controls whether agents can compose and run GraphQL you never reviewed.

Open both in development. Close both in production. The operations you safelist in between are the contract that survives the transition.

### Development posture

expose_schema  
true

enable_arbitrary_operations  
true

Agent reads full schema, drafts and runs any query

save the queries that matter as .graphql files

Reviewed operations directory

### Production posture

expose_schema  
false

enable_arbitrary_operations  
false

Agent may only call safelisted operations

## How it works

The gateway reads `.graphql` operation files from a storage provider directory, validates each one against your composed schema, generates a JSON Schema for its variables, and exposes it as a discrete MCP tool. It runs inside the router and executes operations against the same composed supergraph and federation engine that serves your GraphQL traffic, so there is no separate sidecar or translation service to deploy and keep in sync. Because operations are validated at load time and re-validated on hot reload, a malformed or stale operation is caught before an agent can ever call it.

AI Agent (Claude, Cursor, Windsurf)  
Tool calls over MCP  
Streamable HTTP  
Cosmo Router  
MCP Gateway  
safelisted operation  
Query Planner  
Federated Supergraph  
Accounts subgraph  
Payments subgraph  
Catalog subgraph

The tools an agent sees depend entirely on your configuration:

| Tool | When it exists | What it does |
| --- | --- | --- |
| `execute_operation_<name>` | One per safelisted `.graphql` file | Runs a single pre-approved operation. Inputs are typed from the operation's variables. |
| `get_operation_info` | Always | Returns an operation's input schema and execution guidance so the agent calls it correctly. |
| `get_schema` | Only when `expose_schema: true` | Returns the full GraphQL schema as a string for the agent to introspect. |
| `execute_graphql` | Only when `enable_arbitrary_operations: true` | Executes any query or mutation the agent composes. Marked as a destructive, open-world tool. |

`get_schema` and `execute_graphql` are the only two tools that open the graph beyond your safelist, and both are off by default. A production gateway with both disabled exposes nothing but the operations you placed in the directory.

## Development: design against the live schema

In development you want maximum leverage. Turn both flags on:

1
2
3
4

Now an agent connected through Cursor or Claude can call `get_schema`, understand your federated types, and use `execute_graphql` to draft, run, and refine queries against real data. You and the agent converge on the handful of operations that actually matter, and you save each one as a `.graphql` file.

## The promotion boundary: operations become software artifacts

A discovered query becomes a reviewed artifact when you save it as a named operation, with a triple-quoted block-string description that becomes the tool description the agent reads:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

That file is now a [persisted operation, a trusted document](/content/blog/graphql-persisted-operations-llms-mcp/index.html), and it goes through the same review as any other code: right fields, no unintended PII, the correct authorization scopes, safe for repeated execution, and query-only versus mutation-capable. The exploratory phase produces a tangible, reviewable artifact: a directory of operations. That directory is the contract.

## Production: collapse to the safelist

Close both flags and point the gateway at your reviewed operations:

1
2
3
4
5
6

In this posture the agent can only call `execute_operation_*` tools, one per file you approved. It cannot read the full schema. It cannot compose a query. Every tool maps to an operation a human reviewed, and GraphQL's type system guarantees the agent can only pass inputs your operation declares. This collapses the attack surface from "the whole schema" to the queries you ship, and production rejects anything not on the allowlist.

The safelist is not a proprietary artifact. It is nothing but standard GraphQL operations. Move off this router tomorrow and those `.graphql` files are still valid GraphQL against your schema. You are encoding your AI-facing surface in the same language as your API, not in a format you can only read with one vendor's tooling.

## OAuth: per-operation authorization

Layer OAuth 2.1 on top and the control becomes per-operation. The gateway enforces JWT-based authorization on the MCP methods `tools/list` and `tools/call`, and applies per-tool scope requirements for the built-in tools such as `get_schema` and `execute_graphql`. It honors `@requiresScopes` directives so that [each tool inherits the exact scopes its underlying GraphQL fields require](/content/blog/mcp-per-tool-oauth-scopes-graphql-schema/index.html). An agent does not just see fewer tools; it is authorized for exactly the ones its credentials permit. And because every agent presents its own JWT, each call carries an agent identity you can attribute in logs and traces, so machine-to-machine access stays investigable when an incident demands it.

Federated Supergraph Cosmo Router (MCP Gateway) AI Agent Federated Supergraph Cosmo Router (MCP Gateway) AI Agent Production posture — safelist + OAuth 2.1 alt[token lacks required scope][authorized]tools/list [Bearer token] only execute_operation_* tools (no get_schema, no execute_graphql) tools/call execute_operation_get_customer_orders validate scopes against @requiresScopes 403 Forbidden resolve reviewed operation approved fields only 200 OK

For operations that need a stronger bar at call time, the gateway supports [OAuth 2.1 scope step-up flows](/content/blog/mcp-scope-step-up-authorization/index.html).

There is also a recognized safe middle ground. Keep `expose_schema: true` in production while leaving `enable_arbitrary_operations: false`. Introspection stays on, so agents can reason about your API surface, but execution is still restricted to the operations you safelisted. This is safe precisely because only registered operations ever run: schema visibility grants no execution capability.

## Schema evolution does not become operation maintenance

The objection every platform team raises next is maintenance: if the schema changes, do I have to rewrite all my operations? No, not for additive changes, and that is the reason the model holds up over time.

Adding fields, types, or arguments to your schema does not break or require updating your safelisted operations. The Cosmo Router re-validates every operation against the new schema on each hot reload. Operations that still validate are re-registered automatically. Your safelisted queries keep working untouched; they simply do not use the new capabilities.

The maintenance contract is narrow and predictable:

- **Additive schema changes are free.** New fields, new types, new arguments. Existing operations are unaffected.
- **New capabilities are exposed only on purpose.** A new field becomes reachable by an agent only when you add or extend an operation that selects it. Nothing is auto-exposed. This is least-privilege as a default, not as a discipline you have to remember.
- **You touch an operation only when a change breaks it.** If a field an operation selects is removed or changes type incompatibly, the router logs the error and skips that one operation. The rest keep serving. You update the file to match and it re-registers on the next reload.

The hot-reload path means none of this requires a redeploy: push a new schema, the gateway re-validates and re-registers, and your scope requirements are recomputed from the current `@requiresScopes` directives automatically. This is governance as a guardrail rather than a review queue. The rule that new capabilities are exposed only on purpose cannot be quietly skipped by any team, so schema owners stop being the manual approval gate everyone routes around.

## Why not build a separate AI-safe API?

The reflex when you hit this problem is to build a second, "AI-safe" API: a curated REST surface that exposes only the approved slice of data. It works, and it is a trap. You now own two sources of truth that drift, and the curated one ages into exactly the legacy layer you will be migrating off in three years.

The safelist gives you the same safety without the second system.

|  | Parallel AI-safe API | Cosmo Router MCP Gateway |
| --- | --- | --- |
| Source of truth | A second API that drifts from the first | Your existing supergraph |
| Time to first safe operation | A new build-and-review cycle | Design in dev, save a `.graphql` file |
| Governance granularity | Whatever you hand-build | Per-operation, with OAuth scopes and `@requiresScopes` |
| Schema evolution | Manual sync across two surfaces | Automatic re-validation on hot reload |
| Federation support | Re-implement aggregation | Native; operations span subgraphs |
| Portability | Logic locked in a bespoke service | Standard `.graphql` persisted documents, valid against your schema anywhere |
| What the agent can reach | Whatever the second API exposes | Exactly the safelisted operations, nothing more |

You are not standing up infrastructure to make your API safe for AI. You are configuring a posture on infrastructure you already run.

## Get started

Start with the [MCP Gateway quickstart](https://cosmo-docs.wundergraph.com/router/mcp/quickstart) to have a server running in five minutes, then read the [operations guide](https://cosmo-docs.wundergraph.com/router/mcp/operations) to design your first safelist. For the reasoning behind this whole setup, read the companion: [Don't Let AI Agents Improvise Against Production GraphQL](/content/blog/governing-ai-agent-access-to-graphql-mcp-gateway/index.html).
