/pattern/mcp/

04 · ProductionTool IntegrationMCP-based Tool IntegrationMCP ServerMCP-based Tool Discovery

MCP.
Tools speak a shared protocol.

External resources and tools are made available via the Model Context Protocol as a standardized integration layer.

In practiceA coding assistant connects to a local filesystem server and a remote GitHub server through a single MCP transport layer, without custom integration code for each.

When to reach for it

  • Tools and data sources need to be usable across different frameworks.
  • Local or external systems must be connected.
  • Context access should be standardized.

When it backfires

  • Direct SDK integration is simpler and sufficient.
  • The security model is unclear.
  • Protocol operation introduces more complexity than value.

The tradeoff

Broad interoperability is gained at the cost of additional operational and permission management overhead.

The mental model

A shape you can draw on a napkin.

Picture a universal power socket. Before MCP, every tool an agent wanted to use had its own plug — a different SDK, schema, and auth model. Wiring N agents to M tools meant N×M custom integrations.

MCP collapses that to N + M. A tool author writes one server; an agent runtime ships one client. Any tool that speaks the protocol plugs into any agent that speaks it — no custom wiring. It is, in Anthropic's phrase, "a USB-C port for AI applications."

MCPMCPMCPHOST · MCP CLIENTYour agentone client, many serversFilesystemMCP SERVERGitHubMCP SERVERPostgresMCP SERVERFILESREPODB
The effect

What it actually does.

A standard protocol bridges host and tool server.

hostMCPserver
How it works

Three roles, one stateful connection.

MCP follows a client–server architecture borrowed from the Language Server Protocol. A host runs one or more clients; each client holds a dedicated connection to one server. Messages are JSON-RPC 2.0, carried over stdio for local servers or streamable HTTP for remote ones.

HOST · THE AI APPClaude Desktop · IDE · runtimeMCP ClientONE PER SERVER · STATEFULJSON-RPC 2.0stdio · streamable httpMCP SERVERToolsMODEL-CONTROLLEDResourcesAPP-CONTROLLEDPromptsUSER-CONTROLLEDEXTERNALSYSTEM

initialize → capability negotiation → discovery → operation

Role 01

Host

The AI application the user actually touches — Claude Desktop, an IDE plugin, or your agent runtime. It owns the LLM, the conversation, and the decision to use a tool. It spins up clients as needed.

Role 02

Client

A connector living inside the host that maintains a 1:1 stateful session with exactly one server. It handles the handshake, relays requests, and keeps capabilities in sync.

Role 03

Server

A program — local or remote — that exposes capabilities over MCP. The tool author writes it once; any compliant client can then discover and invoke what it offers.

What a server exposes

Three server primitives.

Primitive · 01

Tools

Model-controlled

Executable functions the model can choose to call to take an action or fetch live data. Discovered via tools/list, invoked via tools/call.

search_flights(from, to, date) create_issue(repo, title, body)
Primitive · 02

Resources

Application-controlled

Read-only context data identified by URI — files, rows, documents — that the host can pull into the model's context window without an action.

file:///logs/2026-05.txt postgres://schema/tickets
Primitive · 03

Prompts

User-controlled

Reusable, parameterized templates the server offers — surfaced to the user as slash-commands or menu actions that pre-package a known workflow.

/summarize-pr pr=482 /triage-bug id=ENG-19

The connection runs both ways. A server can also call back into the host through sampling (ask the host's LLM to generate a completion), elicitation (ask the user for more input), and roots (learn which filesystem boundaries it's allowed to touch). That two-way capability is what separates MCP from a plain tool-calling API.

Walk it through

A real run, message by message.

TaskWhat were our top 3 support issues last week?
6 / 6
InitializeThe host's client opens a session and sends initialize. Client and server exchange protocol version and capabilities — the server announces it has tools and resources.
DiscoverClient calls tools/list. The Postgres server returns one tool — query_tickets(sql) — plus its JSON Schema, so the model now knows the tool exists and how to shape arguments.
ReasonThe model decides it needs aggregated counts and selects query_tickets, drafting SQL that groups tickets by category for the last 7 days.
tools/callquery_tickets(sql="SELECT category, COUNT(*) … WHERE created > now() - interval '7 days' GROUP BY 1 ORDER BY 2 DESC LIMIT 3")
ResultThe server runs the query against the database and returns structured content: Billing 142 · Login 98 · Sync 61.
AnswerTop 3 issues last week: Billing (142), Login problems (98), and Sync failures (61).
The point of the protocol: point the same agent at a GitHub MCP server instead and it answers questions about pull requests — with zero new integration code. Discovery, schemas, and invocation are identical because they ride one standard.
In code

The protocol in practice.

Server · Pythonpython
# server.py — expose a database as an MCP server
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("support-tickets")

@mcp.tool()
def query_tickets(sql: str) -> list[dict]:
    """Run a read-only SQL query against the tickets database."""
    return db.execute(sql).fetchall()

@mcp.resource("postgres://schema/tickets")
def schema() -> str:
    """The tickets table schema, so the model can read column names."""
    return open("schema.sql").read()

if __name__ == "__main__":
    # stdio for local; switch to transport="streamable-http" for remote
    mcp.run(transport="stdio")
Where it sits

MCP and A2A are complementary, not rivals.

Two open protocols cross the boundary out of any single framework. MCP standardizes how an agent talks to a tool; A2A standardizes how an agent talks to another agent. You will often run both.

Dimension
MCP
A2A
Scope
Agent ↔ tool / data
Agent ↔ agent
Standardizes
Tool discovery, invocation, structured I/O
Agent discovery, task lifecycle, artifact exchange
Core artifacts
Resources, Tools, Prompts
Agent Cards, Tasks, Artifacts
Initiator
Agent (client) calls MCP server
Either agent can initiate; tasks have a defined lifecycle
Governing body
Anthropic (open spec)
Linux Foundation (initiated by Google, April 2025)
Privacy model
Tool exposes capability surface; agent owns reasoning
Agents are opaque to each other; internal state stays private
Pitfalls

Three ways this pattern will hurt you.

Treating MCP as a network primitive

Teams expose internal databases via MCP without auth checks, treating the protocol layer as a security boundary.

Fix · Enforce auth at the MCP server layer, not just the transport. Audit every exposed resource for least-privilege access.

Brittle schemas on rapid iteration

The MCP server changes its schema weekly. Client agents break because they pin to an outdated tool definition.

Fix · Version MCP schemas and support a compatibility window. Reject clients that don't declare a version header.

Tool-surface overload

One client mounts a dozen servers; the model now sees 80 tools and picks the wrong one — or stalls choosing.

Fix · Mount only the servers a task needs. Scope tools per route and keep names and descriptions unambiguous.

Threat exposure

What this pattern exposes

Adopting this pattern opens these attack surfaces. Each links to its entry in the threat model.

Full threat model →
Framework support

Where MCP is native.

OpenAI Agents SDKFirst-class MCP server mountingNative
Microsoft Agent FrameworkMicrosoft backs MCP; A2A co-sponsorNative
Claude DesktopReference host — local stdio serversNative
LangGraphvia adaptersAdaptable
LlamaIndexcommunityAdaptable
CrewAIcommunityAdaptable

Search

Search patterns, frameworks, and pages.