AI · LLM

MCP in Practice: The Standard Protocol for Wiring Tools into AI Agents

How MCP works: architecture, primitives, stdio vs Streamable HTTP, tradeoffs vs direct integration, security risks, and adoption criteria as of 2026.

Who should read this

Summary: MCP (Model Context Protocol) is the open standard for connecting AI agents to external tools and data. Released by Anthropic in November 2024 and adopted by OpenAI, Google, and the rest of the major vendors, it has become the default answer to “how do I attach tools to an agent?” This article covers the architecture (Host–Client–Server), the three primitives, transport selection, tradeoffs against direct API integration, and the security risks you must address before adopting it — all from a practitioner’s perspective.

This article is written for developers who need to connect internal systems and external services to agents, and technical leads deciding whether to adopt MCP. It is not an SDK tutorial; it focuses on structure and decision criteria.


Why MCP, why now: the N×M integration problem

Agent development in 2023–2024 was integration hell. With N tools and M agents (or LLM apps), you needed N×M integration codebases. You wrapped the Slack API once for the Claude app, again for the internal chatbot, again for the IDE assistant — the same API wrapped slightly differently by every team.

MCP restructures this into “N servers + 1 standard protocol.” A tool provider builds an MCP server once, and every MCP-capable client (Claude, IDEs, your in-house agent runtime) uses it as-is. It standardizes peripheral connections the way USB-C did — which is why the “USB-C of AI” analogy stuck.

Adoption speed is what makes this standard real. After the November 2024 release, OpenAI and Google DeepMind announced support in the first half of 2025, and major IDEs and agent runtimes shipped built-in clients. Public MCP servers now number in the thousands, and an official registry has standardized how servers are distributed and discovered. In 2026, “can my agent use this tool?” effectively means “is there an MCP server for it?”


The architecture: Host, Client, Server

The most common initial confusion is assuming “client = my app.” MCP splits roles across three layers.

Host application Claude app, IDE, in-house agent runtime — owns the LLM and conversation flow MCP Client One per server, holds a 1:1 connection — permissions, sessions, message routing MCP Server Exposes tools · resources · prompts — an adapter wrapping one domain Real systems Local files Databases External SaaS APIs Internal services
MCP's three-layer structure. One Host contains multiple Clients; each Client connects to exactly one Server.
  • Host: the application facing the user. It owns LLM calls, conversation management, and the policy decision of which servers to attach.
  • Client: the protocol layer living inside the Host, maintaining a 1:1 connection with a server. Three servers means three clients.
  • Server: the side exposing tools and data. A good server wraps one domain (GitHub, Postgres, your internal CRM) narrowly and deeply.

This split matters in practice because of trust boundaries. The Host trusts the user, the Server trusts the systems behind it — but the Host must not blindly trust the Server. We return to this boundary in the security section.

The three primitives — plus two reverse channels

What a server offers a client falls into three categories.

What it isWho controls itTypical examples
Tools Executable functions the model invokesLLM decides to call (human approval gate recommended)Create an issue, run a query, send a message
Resources Read-only context data provided to the modelHost/user selects and injectsFile contents, DB schemas, documents
Prompts Reusable prompt templates served by the serverUser explicitly selects (slash commands, etc.)Code review templates, structured report formats
Sampling (reverse) Server requests a generation from the client's LLMClient controls approval and billingWhen server-side logic needs LLM inference
Elicitation (reverse) Server requests additional input from the userClient mediates through its UIMid-task confirmations and choice prompts
As of July 2026. A practical sequencing: design Tools first, then add Resources and Prompts as you refine context quality.

One design trap worth naming: do not make everything a tool. A “read the docs” tool forces the model to decide on a call every time, while exposing the same data as a Resource lets the Host preload it into context. Seen through the lens of call-decision cost and context engineering, tool sprawl is an anti-pattern that inflates the agent’s decision burden.

And one more — tool outputs should come back as structured results, not free text; it makes downstream handling dramatically more reliable. We covered this in depth in the structured output guide.

Transports: stdio vs Streamable HTTP

MCP abstracts the transport layer, and the practical choice is binary.

stdioStreamable HTTP
Execution model Client launches the server as a local subprocessDeployed as a standalone HTTP service, accessed remotely
Authentication Inherits process permissions (no separate auth)OAuth 2.1 based — the spec defines the auth flow
Best fit Dev tools, CLIs, local files and personal environmentsTeam-shared services, SaaS integrations, multi-tenant
Ops burden No deployment — ship a binary or scriptSame as any web service (TLS, scaling, monitoring)
Watch out for Server runs with your full local permissionsSession management, reconnects, legacy HTTP+SSE compatibility
The 2025 spec revisions made Streamable HTTP the default for remote transport. Legacy HTTP+SSE servers still exist, so verify client compatibility.

The decision rule is simple. “Should this server run with my machine’s permissions?” — if yes, stdio; if multiple people or hosts must share it, Streamable HTTP. The real operational cost of going remote is that authentication, authorization, and audit logging become necessary at the same level as any public-facing API service.

Direct API integration vs MCP: which, when

MCP becoming the standard does not mean every integration should be MCP. Defining tools directly through your framework’s function calling remains valid.

More than one client to connect? (Claude app + IDE + internal bot…)
Yes → Build an MCP server — write once, reuse everywhere
No → Next question
Does an existing public MCP server (GitHub, DB, etc.) already solve it?
Yes → Use it as-is — zero integration code
No → Next question
Do you need to ship tools to external teams or customers?
Yes → MCP server + Streamable HTTP + OAuth
No → Next question
Just 2–3 internal functions inside a single app?
Yes → Direct function calling is simpler — skip the MCP overhead
No → Next question
When in doubt: keep tool logic as pure functions, add a thin MCP adapter later
The MCP adoption decision flow. The key variables are client diversity and reuse scope.

Empirically, the best middle ground is that last line. Keep the tool’s actual logic protocol-agnostic as pure functions, and when client count grows, adding an MCP adapter is a matter of days. Bury the logic inside one framework’s tool definitions instead, and the migration cost snowballs.

Security: the other side of convenience

Security research since 2025 keeps surfacing the same three MCP risks.

1. Tool poisoning — planting malicious instructions inside a server’s tool descriptions themselves. The model must read descriptions to use tools, so descriptions become a prompt-injection vector. Attaching a third-party server is equivalent to putting that server author’s text into your model’s context.

2. Prompt injection via data — the classic attack where instructions embedded in tool-returned data (issue bodies, emails, web pages) get followed by the model. MCP did not create this problem, but the easier tool connectivity gets, the wider the exposed surface honestly becomes.

3. Over-privileged tokens and the confused deputy — hand one server a broad token, and when the model gets tricked, the blast radius equals the token’s scope. When several systems’ permissions pool inside one server, “whose authority did this run under?” gets blurry.

Four common mistakes

1. “Every existing API endpoint becomes a tool” — port 30 REST endpoints into 30 tools and the model’s selection accuracy collapses. Redesigning around the agent’s units of work — 5 to 10 task-shaped tools — always wins.

2. Sloppy tool descriptions — a description is not documentation; it is the interface the model reads. When to use it, when not to, and the constraints on each argument: that is the entirety of description quality.

3. Errors without a next action — return a raw “500 Internal Server Error” and the model retries the same call. An error like “auth expired — ask the user to re-login” is what keeps the agent loop alive.

4. Running remote servers with local-stdio instincts — a remote MCP server is a real service that needs auth, sessions, version compatibility, and audit logs. The moment you ship it to a team, treat it as a first-class citizen of your engineering process.


Conclusion: the protocol is settled; the design is not

For “how do I connect tools to an agent?”, protocol uncertainty is effectively gone. MCP is sufficiently adopted, and the spec keeps maturing along the remote, auth, and interaction axes.

What remains is, as always, design. The instinct to group tools by task, the judgment to separate Resources from Tools, the placement of trust boundaries and approval gates — no protocol does these for you. MCP standardized the connection, not the judgment. And the quality of an agent system is, in the end, the sum of those judgments.


Further reading