The governance problem MCP created without asking

Posted on Apr 6, 2026

My team adopted MCP fast. I encouraged it — the productivity gains were real and visible. Engineers connecting Sentry, Slack, Grafana, GitHub directly into their workflow, no friction. The kind of thing you want to happen organically.

Then one day I asked a simple question: who has a Sentry token? Who has Slack? Grafana?

The answer was: everyone. Each engineer had generated their own. No inventory. No rotation policy. No single revocation point. We had traded operational security for developer experience — and nobody had made that trade explicitly. It just happened, one mcp add at a time.

The problem isn't technological. It's design

MCP as a protocol is well thought out (this also applies to the CLI). The problem is it was designed for individual use. When you scale to a team, the attack surface grows proportionally — number of engineers times number of services. With 20 engineers and 10 MCP servers, you potentially have 200 active tokens scattered across personal machines. No central audit. No visibility into who called what, when, with which arguments.

This isn't the engineer's fault. It's the protocol having no opinion on governance — which makes sense for personal use, and breaks at team scale.

The question every CTO should ask before encouraging MCP adoption: when someone leaves the team, how many places will I need to revoke access?

In our case, the answer was: I don't know. And "I don't know" in security is not an acceptable position.

What we did

The solution we landed on was centralizing through a proxy. mcp serve exposes all configured servers as a single MCP endpoint. The team connects to the proxy — not directly to the services. The token lives in one place. Rotation becomes a single operation, not twenty. When someone leaves, you revoke one credential.

The proxy runs on our internal network. No engineer accesses external services directly — everything goes through the proxy, which is never exposed to the public internet. The Sentry token never leaves internal infrastructure. What travels out is only the result of the call. This structurally reduces the attack surface: instead of 200 tokens distributed across personal machines, you have a single access point that isn't even on the internet.

The proxy also solves a second problem we only noticed later: every MCP client — Claude Code, Cursor, any of them — spawns all configured servers at startup and keeps them alive forever. With 10 servers and 3 open sessions, you have 30 idle processes eating memory. The proxy fixes this with lazy initialization and adaptive idle shutdown: backends only start when called, and shut down automatically when idle.

Two distinct problems, same architectural solution.

What it still doesn't solve

A centralized proxy creates a single point of failure. If the proxy goes down, the team loses access to all services simultaneously — which is different from an individual token failing silently. It's a conscious tradeoff: I'd rather have a visible failure point than an invisible attack surface.

Granular per-user permissions exist, but they're based on glob patterns over tool names — not semantic roles. You can say "engineer A gets no access to Slack tools", but not "engineer A can read but not write". It's a start, not mature access control.

The audit log exists and is local by default. For real compliance, you'll want to integrate it with your observability stack. That's work, not magic.

What I learned

Technology that increases individual productivity tends to create proportional governance debt. MCP is no exception. The adoption speed of the protocol — and the speed at which your team will adopt it — doesn't give the ecosystem time to mature governance tooling before you need it.

As a CTO, my job isn't to block adoption. It's to make sure adoption doesn't create risks the team can't see because they're focused on the immediate gains — which are real. The work is keeping both in perspective at the same time.

If you're considering MCP for your team, start the question from the end: how will I revoke access when I need to? If you don't have a clear answer, you have a governance problem waiting to happen.