DEV Community

hefty
hefty

Posted on

MCP's real production problem is the trust boundary

"It connected" is not production readiness.

That is the demo milestone. It is useful, sure. The first time an agent calls a real tool, pulls data from a real service, or edits something outside its own chat box, the whole thing suddenly feels less like autocomplete and more like infrastructure.

But production is where the easy excitement gets boring.

The hard question is not "can the agent call a tool?" The hard question is "can I understand exactly what authority crossed that boundary, what resource it touched, what the model was shown, what the user approved, and how I undo it when something feels wrong?"

That is the part MCP teams need to take seriously.

MCP makes tool attachment feel clean. That is the whole appeal. A host can talk to servers. Servers expose tools and resources. Agents get a common way to reach local workflows, SaaS APIs, docs, databases, browser state, repo context, and all the other messy places where work actually lives.

Great.

Now every one of those connections is a trust boundary.

The demo boundary is too small

Most MCP demos focus on the happy path:

  • connect the server
  • list the tools
  • ask the agent to do something
  • watch the tool call happen

That is a reasonable demo. It is also nowhere near enough for a production workflow.

The production boundary is bigger. It includes the host, the MCP client, the server, the authorization server, the resource being accessed, the model context, the tool metadata, the approval UI, the logs, and the human who has to review the result later.

If that sounds like too much surface area, that is the point. The moment an agent can call tools, your security model is no longer just "does the API endpoint require auth?" It becomes "what did the agent believe this tool was, who gave it authority, and what could it do with that authority?"

That is a much more annoying question. It is also the useful one.

I do not think this means MCP is broken. The opposite, really. MCP is getting real enough that the boring boundary questions matter now. Standards only become interesting when people start depending on them.

OAuth is more than a login screen

The MCP authorization spec is a good reminder that remote tool use changes the shape of auth.

When an MCP server runs over HTTP and touches user-linked services, it is not enough to wave at OAuth and call it done. The spec frames protected MCP servers as OAuth resource servers and MCP clients as OAuth clients. That means the boring details matter: protected resource metadata, authorization server metadata, resource indicators, bearer tokens, token audience, PKCE, and scope boundaries.

This is where a lot of "agent tool" thinking gets sloppy.

A token is not a magic permission blob that should be passed around until something works. A token is authority. If the wrong service can accept it, or the wrong layer can replay it, or the client cannot tell which resource it was meant for, you have not built a helpful shortcut. You have built confusion into the system.

The official guidance is direct about token passthrough. Treating a token issued for one service as a convenient credential for another service is a boundary failure. It may make a prototype easier. It also makes the trust model harder to explain, harder to audit, and harder to recover from.

This is the part developers should bring back into everyday review:

  • What resource is this token actually for?
  • Which client is allowed to use it?
  • What scopes were granted?
  • Can the server validate the token audience?
  • Can a user revoke this path without tearing down everything else?
  • Are local and remote MCP servers being treated differently where they should be?

None of this is glamorous. Good. Permission should be boring.

The worst version of an agent workflow is one where the auth path works, but nobody can explain it after the fact.

Tool descriptions are not harmless docs

The part that still feels under-discussed is tool metadata.

In normal software, a description field is usually just documentation. Maybe it shows up in a UI. Maybe someone reads it. Maybe nobody does.

In an MCP client, tool descriptions and schemas can end up inside model context. That changes their role. They are labels for humans, but they also influence how the model decides what to call, when to call it, and what parameters to send.

That is why the tool-poisoning research around MCP is worth paying attention to. "A malicious server runs bad code" is the obvious fear. The more subtle failure is a server providing metadata that steers the model toward the wrong behavior.

That should make every approval dialog feel a little more serious.

If the client says "approve this tool call," what is the user actually seeing? A friendly tool name? A sanitized summary? The real parameters? The server-provided description? The resource being touched? The authority being used?

If the answer is "mostly vibes," that is not enough.

A tool description is part of the attack surface once it influences the model. A schema is part of the attack surface once it shapes the call. An approval UI is part of the security surface once a human is expected to catch mistakes there.

This is where product design and security stop being separate conversations. The user cannot approve what the interface hides.

Local does not automatically mean safe

There is a tempting shortcut in developer tooling: local equals trusted.

That is sometimes true enough. It is not a rule.

A local MCP server can still expose too much filesystem access. It can still bridge into credentials. It can still make network calls. It can still pass unreviewed context into the model. It can still become the thing an agent uses because the description sounded convenient.

Local reduces some risks and increases others. You may avoid a remote auth flow, but you also put the server close to sensitive repo state, shell commands, browser profiles, env files, local databases, and all the half-finished work developers keep on their machines.

That does not mean "do not run local MCP servers." It means do not skip the boundary review just because the process is on your laptop.

For a local server, I would still want to know:

  • which directories it can read
  • whether it can write or execute
  • what secrets it can see
  • what network access it has
  • how tools are named and described
  • whether calls are logged
  • how to disable it quickly

Again, boring. Again, exactly the point.

The approval screen is developer experience

Security advice often gets written like paperwork. That is unfortunate, because the best MCP safety features are also developer experience features.

Visible parameters are DX.

Readable tool descriptions are DX.

Small scopes are DX.

Revocation is DX.

Session handling is DX.

Audit logs are DX.

The developer trying to ship with an agent does not want a lecture about confused deputies or token audience validation. They want to know whether this tool call is about to touch the wrong account, write to the wrong repo, post to the wrong workspace, or send private context somewhere it does not belong.

The UI should make that obvious.

If the approval step is just a speed bump, people will click through it. If it shows the real resource, the real operation, the real parameters, and the real authority, it becomes part of the workflow.

That is what production readiness looks like to me. Not an impressive number of connected tools. A system where the next action is legible before it happens and reviewable after it happens.

A practical MCP checklist

If I were evaluating an MCP-backed agent workflow before letting it near real work, I would keep the checklist blunt.

Start with fewer tools than you think you need. Tool sprawl is review sprawl. Every new server adds metadata, permissions, sessions, and failure modes.

Prefer explicit scopes. If a tool only needs read access, do not give it write access because write access is convenient later. Convenience is how prototypes become weird production incidents.

Do not pass tokens through layers just to make integration easier. Bind tokens to the right resource and audience. If that sounds annoying, that is probably the boundary doing its job.

Show parameters before execution. A human should not have to infer what the agent is about to do from a cute tool name.

Treat tool descriptions as inputs, not decoration. Review them. Keep them short. Make them accurate. Do not let a server smuggle policy into prose that the model will treat as instruction.

Log calls in a way a developer can actually read. A giant blob of JSON nobody opens is not an audit trail. The useful record says what tool ran, against which resource, with which visible parameters, under which authority, and what happened next.

Separate local and remote assumptions. A local server may not need OAuth. It still needs a permission story. A remote server may have OAuth. It still needs audience validation, session discipline, and revocation.

Make rollback obvious. If a tool can mutate state, the workflow needs a way to stop, revoke, revert, or at least explain the damage without detective work.

Force the agent to say what it did not verify. That one sounds small, but it changes the tone of the whole system. "I called the tool and got a success response" is not the same as "I verified the target resource changed correctly and logged the call."

Trust is the product surface now

MCP's value is obvious: common plumbing for agents and tools. I want that world. I do not want every agent platform inventing its own one-off plugin format forever.

But the useful version of MCP is not the one with the longest tool list.

The useful version is the one where permission is visible, authority is scoped, metadata is treated as a real input, and a human can reconstruct what happened without reading a detective novel made of logs.

"The agent called the tool" is a nice demo.

"The right agent used the right authority against the right resource, showed the parameters, left an audit trail, and can be revoked cleanly" is the production bar.

That is less flashy. It is also the only version I would trust near real work.


Source notes

Top comments (2)

Collapse
 
eleftheriabatsou profile image
Eleftheria Batsou

The trust boundary is exactly where demo and production diverge, the moment the agent touches a real service, "it works" and "it's safe" stop being the same statement.

The piece I'd add: the trust boundary isn't only about auth, it's about reach. An authenticated MCP server that can touch more than its tools imply is still a production liability.

That's why we lean on network-level isolation at Zerops (where I work), the boundary holds structurally even if the auth layer is fooled. Great post, this is the conversation more teams need before they ship.

Collapse
 
hefty_69a4c2d631c9dd70724 profile image
hefty

Thanks, and I really like the way you frame it as reach. Auth is only one boundary; the more important question is what the server can actually touch once something goes wrong. Network-level isolation is a good example because it makes the limit structural instead of relying only on the model or the prompt to behave. That is where MCP starts to feel production-ready rather than demo-ready.