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 is tool definitions injected into 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 and asks it what it has (tools/list). Those definitions go into the model's context. The model emits a call, the harness routes it to the server (tools/call), the server does the work and hands back a result the model reads. That is the whole protocol: a tool call with a network hop.
The current spec revision lists two transports, stdio and Streamable HTTP. Claude Code still accepts legacy SSE. You 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, stored in ~/.claude.json), project (.mcp.json at the repo root, checked in, prompts teammates for approval), user (all your projects). Full reference: MCP in Claude Code.
Every connected server spends context before you type
Every server's definitions load before the conversation starts, and selection quality moves with that load: with tool definitions fetched on demand instead of preloaded, Opus 4 went from 49% to 74% on Anthropic's tool-use eval (advanced tool use). Tool search is on by default, so schemas arrive on demand (see Own Your Context Window). A server can opt out with "alwaysLoad": true, and that is the setting to watch: one opted-out server puts its whole catalog back in your startup context.
There is no documented tool cap. The docs say plainly that Claude Code imposes no fixed per-server limit and the practical limit is your context budget. My own working ceiling is still about 40 tools live at once. Past roughly that, picking the right tool gets sloppy.
One gateway instead of ten servers
I keep a single MCP connection: Executor, a proxy holding all the others. Jira and Atlassian, Notion, Vercel, Google Workspace, PostHog, Langfuse, Resend, Stripe, Figma, Cloudflare sit behind it. It takes MCP servers, OpenAPI specs and GraphQL endpoints alike, so when a service ships an OpenAPI spec you do not need its MCP server at all. A handful of tools sit in context; the rest of the catalog is reachable on demand.
The model writes code, not tool calls
The gateway hands the model a typed JavaScript sandbox built from the connected specs. The model writes code against those types and runs it. Executor's docs describe that sandbox as one where a method that does not exist fails with a type error before anything reaches the network — a wrong call fails loudly instead of quietly doing something else — and where secrets are injected host-side rather than passed through the model.
This is also why thousands of endpoints stay cheap: they cost nothing until the code references them. Anthropic measured the same pattern at 150,000 tokens down to 2,000, a 98.7% cut (code execution with MCP). One execution can chain several steps — query, filter, follow-up — without dragging each intermediate payload through context.
Connections belong to the workspace
In the Executor app I scope connections to the workspace rather than 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 something the docs describe.
Per tool you can set allow, require approval, or block. With approval required the call pauses for a human; in my setup the approval arrives as a link I open in the browser. Approval then lives outside the conversation, where nothing the model reads can influence it. Use it on every destructive tool. Tool results are untrusted text arriving in your context — a gateway does not change that, approval outside the chat does.
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. That is my rule and I hold it. If the agent needs to change data, it writes a script in the repo where I read the diff and git keeps it. A Supabase MCP with write tools buys nothing a reviewed script does not.
For GitHub, use the gh CLI over a GitHub MCP. Already installed, already authenticated, zero tool definitions.
Executor is young software — beta as of writing, fully open source, self-hostable with Docker or Cloudflare Workers, and runnable as a desktop app or a local CLI service if you want everything on your machine. The free tier was around 10,000 executions a month for up to three members when I set it up; a startup this fresh will move those numbers. The self-host path matters more than the tier.
What to do
- Run
claude mcp listand remove every server you have not used this month. - Route new services through one gateway rather than adding a server each time.
- Scope connections to the workspace and name each one after its project.
- Add the one-line gateway rule to your global rules file.
- Give data stores read-only access and require approval on destructive tools.
- Replace any GitHub MCP with the
ghCLI.