What Is MCP (Model Context Protocol)? A Practical Guide for Developers
Before a shared protocol existed, connecting an AI application to an external tool or data source meant writing a custom integration for that specific pairing. Connect the same application to a second tool, and you write another one. Connect a second AI application to the same two tools, and you're now maintaining four separate integrations for what is conceptually the same problem, solved four times. The Model Context Protocol (MCP) exists to collapse that N×M problem into N+M: build one MCP server for your tool, and it becomes usable by any MCP-compatible client, not just the one you originally built it for.
What MCP Actually Standardizes
MCP defines a client-server architecture. An MCP client lives inside the AI application (an IDE, an agent framework, Claude itself) and connects to one or more MCP servers, each exposing a defined set of capabilities over a standard interface. The client doesn't need hardcoded knowledge of what a server offers — it discovers the server's capabilities at connection time.
Three primitives make up what a server can expose:
- Tools — functions the model can invoke: search a database, send a message, run a query, create a ticket.
- Resources — read-only data the application can pull into context: files, records, live data feeds.
- Prompts — reusable prompt templates a server can offer to any client that connects to it.
The MCP server is the reusable unit — the same server can be connected to by multiple different MCP clients without any changes on the server side.
Transport is typically Streamable HTTP for remote servers (or stdio for a local process). Either way, the client lists what's available on connect rather than the application needing that knowledge baked in ahead of time.
Why It Matters
The practical payoff is reuse. A company that builds one MCP server wrapping its internal ticketing system can connect that same server to Claude, an internal chat assistant, and a CLI tool — without touching the server again. That's the same principle behind USB-C replacing proprietary chargers, or ODBC standardizing how applications talk to databases: pick one interface, and every side of the integration only needs to implement it once.
How Claude Actually Connects to MCP Servers
There are two distinct paths in Anthropic's API, and they solve different problems.
1. The MCP connector — direct from the Messages API
For a single request that needs to reach a remote MCP server, the MCP connector lets Claude call it directly — no self-hosted MCP client required on your side. Two things go in the request together: an entry in mcp_servers naming the server, and a matching mcp_toolset entry in tools that references it by name.
const response = await client.beta.messages.create({
model: "claude-opus-4-8",
max_tokens: 1024,
betas: ["mcp-client-2025-11-20"],
mcp_servers: [
{ type: "url", url: "https://example.com/mcp", name: "example-mcp" }
],
tools: [
{ type: "mcp_toolset", mcp_server_name: "example-mcp" }
],
messages: [{ role: "user", content: "Look up the latest ticket status." }]
})
Both fields are required together — declaring the server without the matching toolset entry is a validation error.
2. Managed Agents — MCP servers with vault-based credentials
For persistent, stateful agents rather than one-off calls, MCP servers are declared on the agent itself (just type, name, and url — no credentials), and the actual authentication lives separately in a vault. Sessions attach the vault via vault_ids, and Anthropic auto-refreshes OAuth tokens using the stored refresh token. This keeps credentials out of the reusable agent definition entirely.
One distinction worth knowing before you hit it as a bug: MCP OAuth tokens are not the same as a service's REST API key. A Notion integration token that works fine against Notion's own REST API will not authenticate against the Notion MCP server — hosted MCP servers require an OAuth bearer token issued for that specific MCP endpoint, which is a different credential from the one you'd use to call the product's regular API directly.
Building Your Own MCP Server
Because a server only needs to expose tools, resources, and prompts over the standard interface, wrapping an internal API, database, or SaaS product as an MCP server is a one-time investment. Once it exists, it's usable by any MCP-aware client — not locked to a single vendor's plugin format the way earlier "connect your AI to X" integrations tended to be.
When MCP Is (and Isn't) the Right Layer
Good fit: a capability you want available across multiple AI tools, agents, or clients — a company-wide "search our internal docs" server that Claude, an internal assistant, and a CLI tool all connect to independently.
Overkill: a single custom tool used by exactly one agent in exactly one codebase. A plain function-calling tool defined directly in your API request is simpler, and there's no server to run, deploy, or keep available.
Conclusion
MCP isn't a replacement for tool use — it's a standardization layer underneath it. If you're building a tool for one agent, define it inline. If you're building a capability meant to be reused across multiple AI applications, MCP is what turns "write it once" into something that's actually true.



