Solo developers wire Cursor to MCP with a local mcp.json and a few npx commands. That breaks the moment a second engineer needs the same Postgres bridge, your security lead asks who holds the production GitHub PAT, and half the team works over SSH on remote VMs where stdio subprocesses spawn on the wrong machine. The fix is an MCP gateway: one governed HTTP front door that fans out to multiple MCP servers, attaches authentication, and gives you logs that answer "which tool call just deleted that row?"
This is an implementation guide, not a product pitch. You can build the pattern with open-source bridges like Supergateway, a reverse proxy, and discipline about secrets. Enterprise vendors sell managed gateways with RBAC dashboards; the architecture is the same either way.
Problem statement
Cursor (and most IDE agents) want either:
- A local command (stdio transport) spawning a server process, or
- A remote URL (Streamable HTTP) with optional headers
Your organization has:
- Five to fifteen specialized MCP servers—git, tickets, warehouse SQL, observability, docs
- Credentials that must not live on every laptop
- A 40-tool practical ceiling in Cursor before tools silently drop from context
- Compliance asking for audit trails on production data access
Without a gateway, each developer becomes a bespoke integration bus. With a gateway, Cursor talks to https://mcp.internal.example/mcp and the platform team decides what sits behind it.
Reference architecture
Think in three layers:
- Client layer — Cursor on the developer machine. Minimal secrets; ideally a short-lived user token only.
- Gateway layer — Authenticates the client, routes sessions, enforces allowlists, logs tool calls. Often nginx or Envoy plus an MCP router, or Supergateway instances per upstream.
- Server layer — Individual MCP servers (stdio) with narrowly scoped service credentials stored in a vault or Kubernetes secrets.
Traffic flow: Cursor → HTTPS → gateway → local stdio server → corporate API/DB. Developers never see the warehouse password. They see a tool that fails closed when their token lacks scope.
Step 1: Expose one stdio server with Supergateway
Supergateway wraps a stdio MCP command and publishes Streamable HTTP—exactly what Cursor remote configs expect.
Example: filesystem server for a monorepo (development only—never point this at / in prod):
npx -y supergateway \
--stdio "npx -y @modelcontextprotocol/server-filesystem /workspace/myapp" \
--port 8000 \
--outputTransport streamableHttp
Docker equivalent (pinned image):
docker run -it --rm -p 8000:8000 supercorp/supergateway \
--stdio "npx -y @modelcontextprotocol/server-filesystem /workspace" \
--port 8000 \
--outputTransport streamableHttp
Verify with curl against the Streamable HTTP endpoint before touching Cursor. If the bridge cannot serve a health check, Cursor will fail silently and you will blame the model.
Step 2: Point Cursor at the remote endpoint
In .cursor/mcp.json (project) or ~/.cursor/mcp.json (global):
{
"mcpServers": {
"platform-gateway": {
"url": "https://mcp.internal.example:8000/mcp",
"headers": {
"Authorization": "Bearer YOUR_USER_TOKEN"
}
}
}
}
Cursor docs support OAuth flows for servers that advertise them; for internal gateways, machine-to-user JWTs or SSO-backed tokens are common. Cursor quirk: when passing bearer tokens via CLI bridges, prefer --oauth2Bearer "token" over complex --header strings with spaces—Cursor has misparsed spaced headers in some setups.
Restart Cursor or reload MCP from Settings → Tools & MCP. You should see one server with the aggregated tools from whatever sits behind the gateway.
Step 3: Orchestrate multiple servers
Supergateway runs one stdio upstream per process. Real teams run multiple containers:
services:
mcp-github:
image: supercorp/supergateway
command: >
--stdio "npx -y @modelcontextprotocol/server-github"
--port 8001 --outputTransport streamableHttp
environment:
GITHUB_PERSONAL_ACCESS_TOKEN: ${GITHUB_MCP_TOKEN}
mcp-postgres:
image: supercorp/supergateway
command: >
--stdio "npx -y @modelcontextprotocol/server-postgres postgresql://..."
--port 8002 --outputTransport streamableHttp
mcp-router:
image: your-org/mcp-router:latest
ports: ["443:8080"]
environment:
UPSTREAMS: "github=http://mcp-github:8001,postgres=http://mcp-postgres:8002"
The mcp-router image here is conceptual—some teams use a thin Node service that mounts multiple MCP sessions and merges tool namespaces; others expose separate URLs per domain (/mcp/github, /mcp/db) and add multiple entries in Cursor. Pick one pattern; do not expose twelve unauthenticated ports on localhost and call it platform engineering.
Tool budget tip: merge only the tools each role needs. Hitting Cursor's ~40-tool cap causes silent omissions—worse than disabling servers intentionally.
Step 4: Add authentication and TLS
Never ship Streamable HTTP bare on the internet. Terminate TLS at nginx, Caddy, or a cloud load balancer. Validate JWTs or session cookies before traffic hits Supergateway.
Minimal nginx sketch:
location /mcp/ {
auth_request /auth/verify;
proxy_pass http://mcp-github:8001/;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
Issue per-developer tokens from your SSO (OIDC) with claims like mcp:github:read vs mcp:warehouse:query. Map claims to upstreams at the router. Shared service accounts defeat the point of the gateway.
Step 5: Logging and audit
Stdio MCP alone logs to nowhere useful. At the gateway, log:
- Authenticated subject
- Tool name and server
- Timestamp and latency
- Argument hashes (not raw secrets or full SQL with PII)
- Allow/deny decision
Send logs to SIEM. When someone asks "did an agent export the customer table," you need rows—not a shrug about non-deterministic models.
Step 6: Roll out to the team
- Publish a golden
mcp.jsontemplate in your developer portal with only the gateway URL. - Document which tools exist and who may enable them—tie to role groups.
- Pin server versions in container images; upgrades go through CI, not automatic
npx -ypulls. - Stage changes in a shared dev gateway before prod credentials.
- Pair with MCP-Scan or internal review when adding community servers—tool poisoning is real (see our MCP security guide).
Remote dev and SSH gotchas
If developers code on a remote VM via SSH, local stdio MCP servers spawn on the remote box while Cursor UI runs locally—stdio transport mismatches cause "tools not found" heisenbugs. A gateway on the remote host (or a sidecar in your dev container) eliminates that class of pain: Cursor always speaks HTTP to a stable URL.
When not to gateway
Solo side projects with a filesystem MCP and no production credentials? Local stdio is fine. The gateway pays off when credentials outlive one laptop and more than one human needs the same tools. If you are not there yet, keep configs simple—but still pin packages and read tool descriptions.
Putting it together
Cursor stays the client. Supergateway (or equivalent) translates stdio servers to Streamable HTTP. Your router + auth layer turns a pile of integrations into something security can reason about. The goal is not more tools—it is fewer secrets on disks and one place to cut access when someone leaves or an incident fires.
References: Supergateway, Cursor MCP docs, MCP Streamable HTTP transport spec, TrueFoundry Cursor MCP setup notes.