Building With MCP: Real-World Agent Integration

From Spec to Ecosystem

Anthropic announced MCP in November 2024 as an open standard for connecting language models to external data sources and tools. The spec adoption timeline was remarkable: OpenAI endorsed it in March 2025, Google DeepMind in April, and Microsoft announced native MCP support at Build in May. By June, the Linux Foundation had accepted MCP as a hosted project, giving it the governance structure needed for long-term enterprise confidence.

The practical consequence was an explosion of published MCP servers. By September 2025, the community registry listed over 2,000 MCP servers covering everything from GitHub and Jira to Salesforce, databases, file systems, web browsers, and dozens of SaaS applications. The "write once, work everywhere" promise of the protocol — that an MCP server built for Claude Desktop would work in any MCP-compatible host — had largely held up in practice.

The standard defines three primitives: tools (functions the model can call), resources (data the model can read), and prompts (pre-defined interaction templates). The transport layer uses JSON-RPC over stdio or HTTP with server-sent events. This simplicity is deliberate — MCP's design philosophy prioritizes implementer accessibility over feature richness, which is why it found adoption faster than more complex predecessors like OpenAI's Plugins specification.

Building an MCP Server: What the Documentation Skips

The official MCP quickstart gets you to a working server in under an hour. Getting to a production-quality server takes considerably longer, and several lessons recur across implementations. Tool schema design is the first: the model's ability to use your tool correctly depends heavily on how clearly you describe what it does, what its parameters mean, and what errors it can return. Vague descriptions produce unreliable tool selection. Precise, specific schemas with concrete examples in the description produce dramatically better results.

Error handling deserves explicit attention. When a tool call fails — a network timeout, an API rate limit, an invalid parameter value — MCP defines how to return error responses, but how you format those error messages matters as much as returning them. An error message that says "request failed" gives the model nothing to work with. An error that says "rate limit exceeded, retry after 60 seconds" gives the model actionable information it can reason about and potentially handle.

Stateful resources are another common stumbling block. MCP resources are designed to represent data that the model can read — documents, database records, file contents. Representing mutable state that changes between tool calls requires careful design. The pattern that works is treating resources as snapshots (the current state of X at the time of reading) and making state changes explicit through tool calls, not implicit through resource mutation.

Security Considerations That Matter

MCP's tool execution model means that a language model can take real actions in the world on behalf of the user: querying databases, sending emails, modifying files, calling external APIs. The security surface this creates is different from traditional application security because the threat model includes prompt injection — malicious content in the model's context causing it to misuse authorized tools.

The patterns that emerged through 2025 included strict scope limitation (tools should do exactly one thing and refuse to do anything outside that scope), explicit confirmation for irreversible actions (deleting a record, sending a message), audit logging of all tool invocations, and careful validation of tool inputs against the defined schema rather than passing them directly to underlying APIs.

Authentication between MCP hosts and servers was also an area requiring careful implementation. The spec allows HTTP-based servers to use standard authentication mechanisms, but the responsibility for implementing those correctly falls on the server author. Several early published servers passed credentials through environment variables in ways that were insecure in containerized deployments. Reading the security section of the MCP spec carefully before publishing a server that handles sensitive data is not optional.

The Production Patterns That Work

After building and deploying MCP integrations through 2025, the patterns that consistently produced reliable agents were: narrow tool scopes (each tool does one thing, not five); comprehensive tool descriptions with examples of correct and incorrect usage; graceful degradation when external services are unavailable; and structured output formats that give the model a consistent schema to parse and reason about.

The most successful production MCP integrations we've seen treated the protocol as an API contract between the model and the underlying service — the same discipline you'd apply to designing any well-structured API, just with the additional consideration that the consumer is a language model rather than application code. Models respond to good API design the same way developers do: clearly scoped, well-documented interfaces produce better outcomes than sprawling, ambiguous ones.