Setu Recipes: reusable workflows across every app.Browse templates

MCP explained: how models call tools, and where it breaks

The Model Context Protocol, or MCP, was introduced by Anthropic in late 2024 as a common way for AI applications to connect to tools and data. It is now widely supported, and if you build agents you will meet it. This post explains how MCP works in practical terms: the pieces, the messages, the two transports, and the places it tends to hurt in production, namely authentication, secret URLs, context bloat and versioning.

Key takeaways

  • MCP is a JSON-RPC 2.0 based protocol that lets a host application discover and call tools, resources and prompts from servers.
  • Servers run locally over stdio or remotely over streamable HTTP; remote servers need real authentication.
  • A secret URL is a bearer credential, so treat it like a password and never log it.
  • Every tool you expose costs context on every call, so connect fewer tools and describe them tightly.
  • Pin and test against protocol and server versions, because tools can change under you.

What MCP is and the problem it solves#

Before MCP, every AI application that wanted to use GitHub, a database or a calendar wrote its own integration, in its own format. M applications and N tools meant M times N adapters. MCP replaces that with one protocol: a tool is wrapped once as an MCP server, and any MCP-capable application can use it.

The protocol is built on JSON-RPC 2.0, a simple request and response format using JSON messages with a method name, parameters and an id. MCP defines the methods: list the tools, call a tool, read a resource, fetch a prompt.

The practical gain is reuse. A team that builds one server for an internal system gets that system in every compatible client, and a client that speaks MCP gets every server without custom code.

Note what MCP is not. It does not make the model smarter, and it does not decide when a tool should be called. It standardizes how capabilities are described and invoked. The model still chooses, and the host application still has to enforce safety.

Hosts, clients and servers#

Three roles show up in the architecture.

  • Host: the application the user talks to, such as a chat app, an IDE or your own agent program.
  • Client: the connector inside the host that holds one connection to one server.
  • Server: a program that exposes capabilities, either wrapping a local resource or fronting a remote service.

A server can offer three kinds of things. Tools are actions the model can request, such as creating an issue. Resources are readable data the host can pull in, such as a file or a record. Prompts are reusable templates a user can invoke. Tools get the most attention because they power agents, but resources and prompts are part of the same protocol.

How MCP connects a model to an appA host application such as Claude contains an MCP client. The client talks JSON-RPC to an MCP server over stdio or HTTP. The server calls the app's own API over HTTPS with a token.Host app MCP clientinside Claude, Cursor... MCP serverlists tools,runs them The app's APIGitHub, Slack, Notion... JSON-RPCstdio or HTTP HTTPS+ token Decides whento call a toolDescribes tools,enforces rulesHolds thereal data
How a host app, MCP client, MCP server and the app's API fit together.

What a tool call looks like on the wire#

After connecting, the client asks the server what it has with a tools/list request. The server answers with names, descriptions and JSON Schemas for the inputs. The host passes those definitions to the model. When the model requests a tool, the host sends a tools/call:

{
  "jsonrpc": "2.0",
  "id": 7,
  "method": "tools/call",
  "params": {
    "name": "create_issue",
    "arguments": { "repo": "acme/web", "title": "Fix login redirect" }
  }
}

The server runs the action and replies with a result containing content the model can read, or an error. The model never talks to the server directly. The host mediates every call, which is exactly where you attach approvals, logging and limits.

Transports: stdio and streamable HTTP#

MCP messages travel over a transport. Two are standard.

stdio launches the server as a local subprocess and exchanges messages over its standard input and output. It is simple and has no network surface, which suits tools running on the same machine as the host. The trade-off is that the server runs with whatever access the local user has, and you have to install it.

Streamable HTTP lets a client talk to a remote server over HTTP, with the option of streaming responses. This is how hosted services are reached. It also means everything you know about web security now applies: TLS, authentication, rate limits, and who is allowed to call what.

Pick stdio for local developer tooling. Pick HTTP when the server must be shared, hosted or kept off the user's machine.

Where it breaks: authentication and secret URLs#

A remote MCP server holds, or can reach, someone's data. So how does it know who is calling? The protocol's authorization approach builds on OAuth, with the authorization code flow and PKCE for obtaining tokens. The exact details have changed between protocol revisions, so check the current specification before you build against it. In practice, many servers also use simpler schemes, and one is worth a warning.

Some setups give each user a unique URL and treat possession of that URL as proof of identity. That works, but the URL is now a bearer credential. Anyone who sees it can act as that user. Concretely:

  • Never log full URLs in request logs, analytics, error trackers or screenshots.
  • Do not paste them into tickets or chat.
  • Make them revocable and rotatable.
  • Limit what a URL can do, ideally with per-action rules and approvals.

Also remember the second credential. The MCP server usually holds tokens for the underlying apps. Those should be encrypted at rest and never returned to the model.

Where it breaks: too many tools#

Every tool the host advertises is sent to the model as a name, a description and a schema. That text sits in the context window on every call. Connect five servers with thirty tools each and you have spent a large share of the window before the user says a word. Worse, a model facing a hundred and fifty similar tools picks the wrong one more often.

Ways to keep it under control:

  • Connect only the servers the task needs, and prefer servers that expose a focused set of tools.
  • Write short, distinct descriptions. Avoid two tools that sound alike.
  • Let the host filter or load tools on demand rather than always-on.
  • Keep tool results small. A tool that returns a whole document on every call does the same damage as a long tool list.

Where it breaks: versions and change#

MCP is young and still evolving. Client and server negotiate a protocol version when they connect, and newer revisions have changed details such as how authorization and HTTP transport work. Do not assume that every client supports every revision.

There is a second kind of change: the server's own tools. A server author can rename a tool, add a required argument or change what it returns. Your agent's behaviour changes with it, with no release on your side.

Defensive habits help. Record which server versions you have tested. Keep a small set of end-to-end tasks that call your key tools and run them regularly. Treat tool descriptions from third-party servers as untrusted input, since they are text that goes straight into your model's context. A malicious or compromised server can use a description to try to steer the model, so review what you connect, and keep approvals on for any action with side effects.

How Setu approaches MCP#

Setu exposes the apps a person has connected through one private MCP URL per user, so an agent has a single endpoint instead of a server per app. Because that URL is a secret, treat it as such; Setu does not rely on it alone for risky actions. By default, new accounts ask before writes and deletes, and each app has rules of go ahead, ask or never for read, write and delete. A connection can also be made read-only.

Underneath, apps connect through managed OAuth and tokens are encrypted at rest with AES-256-GCM envelope encryption, and the model never receives them. Setup steps are in the MCP docs.

Frequently asked questions#

What is MCP in AI?

MCP, the Model Context Protocol, is an open protocol introduced by Anthropic in late 2024. It standardizes how AI applications discover and call tools, read resources and use prompts from servers, using JSON-RPC 2.0 messages.

What is the difference between MCP and function calling?

Function calling is how a model API returns a structured request to run a tool. MCP is a protocol for how an application finds and invokes tools from servers. An MCP host typically uses function calling to expose MCP tools to the model.

Is MCP safe to use with private data?

It can be, but safety comes from the host and server, not the protocol. Use authentication, least-privilege scopes, approvals for risky actions, encrypted token storage and logs that never record secrets or session URLs.

Should I use stdio or HTTP for an MCP server?

Use stdio for local tools that run on the user's machine and need no network access. Use streamable HTTP when the server is hosted, shared among users or must stay off the local machine, and secure it properly.

Skip building the MCP server for every app

Setu gives each user a private MCP endpoint for their connected apps, with approvals built in. Follow the MCP docs to point your client at it.