MCP Without Tool Bloat
Connect Jira, Notion, PostHog, Stripe and the rest through one gateway, so hundreds of endpoints cost a handful of tool definitions.
The one line: MCP tool definitions land in your context before you type a word, so route every service through one gateway instead of connecting ten servers.
The mechanics, in four steps
An MCP server exposes tools, resources and prompts over JSON-RPC. Your harness starts one client per server, asks what it has (tools/list), and puts those definitions in the model's context. The model emits a call, the harness routes it (tools/call), and the result comes back.
The spec lists two transports, stdio and Streamable HTTP; Claude Code also accepts legacy SSE. Add servers from the CLI:
claude mcp add --transport http <name> <url>
claude mcp add <name> -- <command> [args...]Scope decides who sees it: local (default, in ~/.claude.json), project (.mcp.json at the repo root, checked in, teammates approve it), user (every project of yours). Full reference: MCP in Claude Code.
Every connected server spends context before you type
Definitions load before the conversation starts, and that costs you accuracy: fetching them on demand instead took Opus 4 from 49% to 74% on Anthropic's tool-use eval (advanced tool use). Tool search is on by default (see Own Your Context Window), but a server can opt out with "alwaysLoad": true, which puts its whole catalog back in your startup context.
Claude Code sets no per-server tool limit; the practical limit is your context budget. Mine is about 40 tools live at once, and past that, picking the right tool gets sloppy.
One gateway instead of ten servers
I keep one MCP connection: Executor, a proxy holding all the others. Jira and Atlassian, Notion, Vercel, Google Workspace, PostHog, Langfuse, Resend, Stripe, Figma and Cloudflare sit behind it. A handful of tools sit in context; the rest of the catalog comes on demand.
Connections multiply with every parallel session
Every MCP server you configure opens one live client per session. A server on your own machine runs as a separate program until you quit; a remote one holds a connection your harness reconnects when it drops. Five servers means five of those in every session you have open.
A sub-agent reuses the parent's connections unless a server is defined inline in its frontmatter. But a background agent, a second terminal, a worktree per branch, a CI runner each open the full set again. Five servers across six sessions is thirty clients, and thirty programs running on the laptop you're compiling on.
A gateway makes it one connection per session, six instead of thirty, and does the fan-out to Jira and Notion itself. The MCP spec went stateless on 28 July, which solves part of this, but you still have to wait for that to reach everywhere, and it doesn't help servers on your own machine, since those start a separate program for every client either way.
The model writes code, not tool calls
The gateway hands the model a typed JavaScript sandbox built from the connected specs, and the model writes code against those types and runs it. Executor's docs describe a sandbox where a method that does not exist fails with a type error before it reaches the network, and the gateway attaches the secrets, so they never pass through the model.
Endpoints cost nothing until the code references them. Anthropic measured the same pattern at 150,000 tokens down to 2,000 (code execution with MCP). One run chains query, filter and follow-up without dragging each payload through context.
Not only MCP, and not forty tools
The gateway also takes OpenAPI specs, GraphQL endpoints and Google Discovery documents into the same catalog, so a service with an OpenAPI spec needs no MCP server at all. Point the gateway at the spec instead of waiting for someone to wrap it.
Cloudflare publishes its whole API as OpenAPI: 3,286 operations across 2,046 paths in cloudflare/api-schemas. Send all of those to a harness with no tool search and no on-demand loading, which is what Cursor's MCP page documents, and the session is broken. Behind a gateway they arrive as types the code reaches for.
One place to manage connections
In the Executor app I scope connections to the workspace, not to myself, so a teammate joining inherits every authenticated connection and a rotated key changes in one place. Workspace scope is a console option, not in the docs.
Authenticate Vercel and Cloudflare once and they are there in every agent on every machine you log in from. Set up a new machine by logging in, with nothing to reconfigure per project or per harness.
In a company the org creates the connections; credentials sit in Executor and get attached to the upstream call, so an employee gets a working connection and never the production key. Offboarding is revoking a connection, not rotating every key that reached a laptop.
Per tool you can set allow, require approval, or block, and the org decides that, not each person's local config. Approval pauses the call for a human, and it happens outside the conversation, where nothing the model reads can influence it. Use it on every destructive tool, because tool results are untrusted text arriving in your context.
It does not have to be somebody else's server
Executor is MIT licensed, source at UsefulSoftwareCo/executor. Besides the hosted cloud you can run a local CLI as a background service, a desktop app on Mac, Windows or Linux, the whole server in one Docker container over a SQLite file, or a single Cloudflare Worker in your own account.
I use the cloud. For a company, self-hosting is usually the deciding fact: the box holding every credential your engineers' agents use can be one you own.
Setup path
- Create the integration: pick the service and paste its credential. For PostHog that is a personal API key from your account settings, under Personal API keys, not the project token.
- Add a connection, scoped to the workspace.
- Name the connection after the project,
peak-art-posthograther thanposthog. Two PostHog projects are otherwise indistinguishable to the model. - Copy the add command the app gives you:
claude mcp add --transport http executor <url-from-executor> --scope user- Put one line in your global rules file so the agent reaches for the gateway by default (see Rules Files and Scope):
Executor is the way to reach any external service (Jira/Atlassian, Notion,
Vercel, Google Workspace, PostHog, etc). It runs code against its OWN saved
connections, independent of the direct MCP connectors.Then "using PostHog, give me unique visitors to the production domain today" routes itself, with no tool name in the prompt.
What I connect, and what I refuse
Read-only for data stores. If the agent needs to change data, it writes a script in the repo where I read the diff and git keeps it.
For GitHub, use the gh CLI over a GitHub MCP. Already installed, already authenticated, zero tool definitions.
Executor is beta as of writing; I recommend it because I run everything through it daily. The free tier was around 10,000 executions a month for up to three members when I set it up, and those numbers will move, so check the pricing page.
What to do
- Run
claude mcp listand remove every server you have not used this month. - Multiply what is left by the sessions you run at once for your real connection count.
- Route new services through one gateway instead of adding a server each time.
- Point it at the OpenAPI spec when there is one.
- Scope connections to the workspace, named after the project.
- Add the gateway rule to your global rules file.
- Give data stores read-only access, require approval on destructive tools.
- Replace any GitHub MCP with the
ghCLI.