The shadow MCP server problem: when AI agents access APIs outside your gateway
AI agents using shadow MCP servers bypass your API gateway's controls. Here's how to bring all MCP traffic under the same auth, rate limits, and audit trail.
- mcp
- ai-agents
- security
- api-governance
When a developer connects Claude or Cursor to a company's internal API, they often reach for the simplest path: spin up a DIY MCP server that wraps the backend service and expose it directly. The agent works. The demo goes well. But the API call never touched the gateway. There was no token validation, no rate limiting, no audit log entry. From a security and compliance standpoint, that API call did not happen.
This is the shadow MCP server problem. It follows the same pattern as shadow IT: individuals solve a real need quickly, creating infrastructure outside the governance perimeter. But it moves faster, because standing up an MCP server is an afternoon's work and AI tool configuration is a single JSON block. A developer can create a new MCP server, give it direct access to a backend service, and hand out connection details to every AI tool they use before anyone in platform engineering or security has seen it.
The problem scales with AI adoption. Once Claude Desktop, Cursor, and in-house AI agents all become first-class engineering tools, the number of potential shadow MCP servers grows with them. Each one is a separate auth implementation, a separate credential management problem, and an entirely invisible request stream from your gateway's perspective.
Why shadow MCP servers bypass your existing controls
Traditional network controls cannot solve this. A firewall can block a port, but it cannot distinguish between a legitimate API call going through your gateway and an MCP execute_endpoint call going directly to the same backend service. Both use HTTPS. Both look like normal web traffic. The difference is what happens before the request reaches the backend — with the gateway in the path, you get auth validation, rate limit enforcement, and a log entry. Without it, you get none of those.
Existing API gateways built for REST are equally blind to traffic that routes around them. Kong, Apigee, AWS API Gateway, and Azure APIM are effective enforcement layers for REST clients. None of them include a native MCP server that AI tools can connect to directly. So teams build their own, and those DIY servers inevitably lack the client model, rate limits, and audit capabilities that a gateway provides.
The deeper problem is that each DIY MCP server becomes its own auth implementation. One might require a hardcoded API key. Another might accept any request. A third might implement OAuth but skip token expiry validation. There is no unified credential model, no per-agent scoping, no consistent audit trail, and no single revocation path. If a developer's credentials are compromised, you may not be able to revoke access because you may not even know the server exists.
How the Zerq Gateway MCP creates a single enforcement point
Zerq's gateway includes a native MCP server endpoint at the /mcp path, accessible at the same address as the REST gateway. AI agents connect to it using the same auth model as any other API client: two custom headers (X-Client-ID and X-Profile-ID) and a bearer token or OIDC credential. From the gateway's perspective, an MCP tool call is another authenticated API request. All the same controls apply.
The Gateway MCP surface exposes four tools: list_collections, list_endpoints, endpoint_details, and execute_endpoint. These are the only operations an AI agent can perform. The agent cannot reach backend services directly, enumerate credentials, or discover API endpoints outside its assigned collections. The gateway is not a proxy in front of an MCP server — it is the MCP server, with access control enforced at the collection level before any tool response is generated.
Creating a scoped client for an AI agent
Setting up an AI agent for gateway access follows the same flow as onboarding any other API consumer:
- Open the management UI and go to Clients → New Client.
- Name the client to match the agent — for example,
claude-support-botfor an internal customer support tool. - Under Collections, check only the API collections this agent needs. A customer support bot might need "Customer Support APIs" but not "Finance APIs" or "Admin APIs". Leave those unchecked.
- Attach a Policy if you want rate or quota limits on this client. A policy with
max_requests: 200andinterval: 1mensures an agent loop cannot saturate upstream services. - Click Create. A default profile is created automatically with token authentication.
- Open the profile and optionally set Allowed Methods to
GETonly for a read-only agent, and IP Restrictions to the IP of the host where the agent runs.
The collection assignment in step 3 is what makes the gateway the right enforcement layer. When this client calls list_collections, the response contains exactly the collections you checked — and nothing else.
Configuring an AI tool to use Gateway MCP
Add the gateway MCP endpoint to your AI tool's configuration file:
{
"zerq-gateway": {
"url": "https://gateway.example.com/mcp",
"transport": "streamableHttp",
"headers": {
"X-Client-ID": "cl_abc123",
"X-Profile-ID": "pr_xyz456",
"Authorization": "Bearer zerq_tok_xxxxxx"
}
}
}
The X-Client-ID and X-Profile-ID values come from the client and profile created in the management UI. The token is displayed once when the profile is created — copy it immediately. This is the complete configuration. The AI tool does not need to know about backend topology, internal routing, or API schemas beyond what the gateway exposes through the four MCP tools.
What a scoped MCP session returns
An agent authenticated as claude-support-bot calls list_collections. The gateway returns only the Customer Support APIs collection:
{
"result": {
"content": [{
"type": "text",
"text": "[{\"id\":\"coll_cs_001\",\"name\":\"Customer Support APIs\",\"published_endpoints\":12}]"
}]
}
}
Finance APIs, Admin APIs, and every other collection in the gateway are absent. The agent cannot discover them, list their endpoints, or call execute_endpoint against their paths. This restriction is enforced structurally: the collection assignment check runs at the gateway layer before any MCP response is generated, not in application code that could be misconfigured.
What appears in the request log
Every execute_endpoint call creates a request log entry with the same structure as a regular REST API call. A lookup of a support ticket through the MCP surface logs:
{
"request_id": "req_7f3a9d",
"timestamp": "2026-08-06T09:14:32Z",
"client_id": "cl_abc123",
"profile_id": "pr_xyz456",
"collection": "Customer Support APIs",
"target_endpoint": "GET /tickets/{id}",
"latency_ms": 47,
"status": 200,
"user_agent": "claude-desktop/1.0"
}
The client_id and profile_id fields identify the specific AI agent that made the call. Teams with the audit role can filter the request log by client_id to produce a complete record of what a given agent accessed, when, and with what response code. That log is generated by the same observability layer that logs human-initiated REST calls — no separate storage, no manual export step, no difference in retention policy.
What this looks like in practice
Consider a fintech team running a lending platform. Three developers had independently created MCP servers to connect their AI coding assistants to the loan origination API. Each worked differently: one used a shared service account key that would not expire, one required no authentication, and one implemented OAuth but accepted tokens without verifying the audience claim. All three pointed at the production service. None appeared in the gateway's request logs. The security team had no visibility until a developer mentioned them in a Slack thread.
They replaced all three with a single Zerq Gateway MCP client. The client was scoped to a read-only collection containing only the endpoints developers actually needed — not the full loan origination service, and not underwriting or disbursement endpoints. Allowed Methods was set to GET only. A rate limit policy was attached to prevent any agent loop from generating unexpected upstream load. The developers updated their AI tool configurations to point at the Zerq MCP endpoint, and the three shadow servers were shut down.
Every AI agent interaction with the lending API now appears in the same request logs as the production web application. The security team can filter by client ID to see exactly what AI tools accessed. If a developer's agent makes an unusual call pattern — high volume, repeated failures, unexpected endpoint combinations — it shows up in the same observability tooling used for every other API consumer.
What changes when the gateway becomes the enforcement point
Running AI agent access through the gateway rather than around it gives you three things that DIY MCP servers cannot provide.
Scoping is enforced structurally. Agents see only the collections assigned to their client. There is no trust that a DIY server will correctly implement its own scope checks.
Revocation is immediate. Deactivating a client or rotating its credential takes effect on the next request. There is no need to hunt down hardcoded keys across config files or track which developers have which connection details.
The audit trail is complete. Agent calls appear in the same request log as human-initiated REST calls. A compliance team reviewing API access for a regulatory audit looks in one place, with consistent log structure and retention across all traffic types.
The shadow MCP server problem is structural: teams take the fastest path to connect an AI tool to an API, and that path often bypasses the gateway. Making the gateway a native MCP server gives you a way to be that fastest path, so agent traffic flows through your controls rather than around them.
Zerq is an enterprise API gateway built for regulated industries — one platform for API management, AI agent access, compliance audit, and developer portal, running entirely in your own infrastructure. See how it works or request a demo to walk through your specific requirements.