Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Chapter 1: The Problem MCP Solves

The N-Times-M Integration Nightmare

Picture this. You’re building an AI application. Your LLM needs to read files, query a database, search the web, and create GitHub issues. So you write custom integration code. Four integrations. Not terrible.

Now your company wants to support a second LLM provider. You rewrite all four integrations for the new API format. Eight integration paths. Getting worse.

Then marketing wants Slack integration. And sales needs Salesforce. And the data team wants BigQuery. And now you’re supporting three LLM providers.

Three providers times seven integrations. Twenty-one bespoke integration paths, each with its own authentication logic, error handling, and data formatting. Each one a unique snowflake of technical debt.

This is the N-times-M problem, and before MCP, it was the lived reality of every team building AI-powered applications. Every new tool required new integration code for every client. Every new client required adaptation code for every tool.

It was, to use a technical term, a mess.

What Life Looked Like Before MCP

Before the Model Context Protocol, developers had a few options for giving LLMs access to external tools and data. None of them were great.

Option 1: Bespoke Function Calling

LLM providers offer their own function calling (or “tool use”) APIs. You define functions as JSON schemas, stuff them into API requests, parse the model’s function call responses, execute the functions yourself, and feed results back to the model.

This works. For one application talking to one provider.

The moment you need the same tool available in Claude Desktop and your custom chatbot and your VS Code extension, you’re copy-pasting integration code across codebases. The tool definition format differs between providers. The execution model differs. The error handling differs.

Function calling is the mechanism by which models invoke tools. But it says nothing about how tools should be discovered, described, transported, or shared across applications.

Option 2: Framework-Specific Plugins

LangChain has tools. AutoGen has tools. CrewAI has tools. Each framework defines its own tool interface, its own registration mechanism, its own execution model.

Build a tool for LangChain? It only works in LangChain. Want it in CrewAI? Rewrite it. Want it in a framework that doesn’t exist yet? Wait and rewrite it later.

This creates walled gardens. A rich ecosystem of tools… that you can’t use anywhere else.

Option 3: Build Everything Into Your Application

The most common approach: just hardcode everything. Need database access? Import the database driver directly. Need web search? Call the API from your application code. Need file access? Use the filesystem APIs.

This works until your application becomes a monolith containing every integration anyone has ever needed. It works until you want the same integrations available from a different application. It works until you realize you’ve built a distributed system and called it “one app.”

Option 4: Custom APIs and Middleware

Some teams build their own middleware layer—a custom API gateway that their AI applications call to access tools and data. This is essentially building your own protocol from scratch.

You get points for ambition and deducted points for reinventing the wheel. You’ve solved the problem for your organization, at the cost of building and maintaining infrastructure that nobody else can use.

The USB Moment

Remember what it was like to connect a printer in 1995? Every printer had its own cable. Its own port. Its own driver. Its own special brand of frustration. You bought a scanner and it needed a different port, a different cable, a different driver, and at least one blood sacrifice to the driver gods.

Then USB happened. One standard port. One standard protocol. One standard cable. You plug in a printer, a scanner, a keyboard, a webcam, a coffee warmer—and they all just work. (The coffee warmer less reliably, but that’s a hardware problem.)

MCP is the USB-C of AI integrations.

Before MCP:

Claude Desktop ──custom code──> GitHub API
Claude Desktop ──custom code──> Filesystem
Claude Desktop ──custom code──> Database
VS Code Agent  ──custom code──> GitHub API (different implementation)
VS Code Agent  ──custom code──> Filesystem (different implementation)
VS Code Agent  ──custom code──> Database (different implementation)
Custom App     ──custom code──> GitHub API (yet another implementation)
Custom App     ──custom code──> Filesystem (yet another implementation)
Custom App     ──custom code──> Database (yet another implementation)

Nine integration paths. Three implementations of the same thing. Three times the bugs. Three times the maintenance.

After MCP:

Claude Desktop ──MCP──> GitHub MCP Server
VS Code Agent  ──MCP──> GitHub MCP Server
Custom App     ──MCP──> GitHub MCP Server

Claude Desktop ──MCP──> Filesystem MCP Server
VS Code Agent  ──MCP──> Filesystem MCP Server
Custom App     ──MCP──> Filesystem MCP Server

Claude Desktop ──MCP──> Database MCP Server
VS Code Agent  ──MCP──> Database MCP Server
Custom App     ──MCP──> Database MCP Server

One GitHub MCP server. Used by everything. One filesystem MCP server. Used by everything. The integration code is written once, in one place, and speaks one protocol.

N plus M, not N times M.

What MCP Actually Is

The Model Context Protocol is an open standard, created by Anthropic and released in November 2024, that defines how AI applications communicate with external tools and data sources. In December 2025, Anthropic donated MCP to the newly formed Agentic AI Foundation (AAIF) under the Linux Foundation, with platinum members including Amazon, Anthropic, Block, Bloomberg, Cloudflare, Google, Microsoft, and OpenAI. MCP is no longer one company’s project—it’s an industry standard.

At its core, MCP defines:

  1. A message format — JSON-RPC 2.0, the lingua franca of structured communication
  2. Three primitives — Tools (things the model can do), Resources (things the model can read), and Prompts (reusable interaction templates)
  3. A client-server architecture — Applications host MCP clients that connect to MCP servers
  4. Transport mechanisms — stdio for local processes, Streamable HTTP for remote servers
  5. A capability negotiation system — Clients and servers agree on what they each support
  6. A security model — Clear trust boundaries between hosts, clients, and servers

MCP is not:

  • A replacement for function calling (it uses function calling under the hood)
  • An LLM API (it’s provider-agnostic)
  • A framework (it’s a protocol; frameworks implement it)
  • A product (it’s an open specification)
  • Anthropic-specific (it works with any LLM)

The Cast of Characters

MCP defines three roles:

Hosts

The host is the AI application the user interacts with. Claude Desktop. VS Code with GitHub Copilot. Cursor. Your custom chatbot. The host contains the LLM, manages conversations, and decides how to act on model outputs.

The host is where the human is. It’s the trust anchor.

Clients

Each host contains one or more MCP clients. A client is a protocol-level connector that maintains a 1:1 relationship with a single MCP server. The client handles connection lifecycle, message routing, and capability tracking.

You can think of a client as a USB port. The host is the computer. Each port (client) connects to exactly one device (server).

Servers

MCP servers are lightweight programs that expose capabilities through the protocol. A server might wrap a database, an API, a filesystem, or any other data source or tool. Servers are focused—each one does a specific thing and does it well.

A filesystem server serves files. A GitHub server talks to GitHub. A PostgreSQL server queries databases. Each is a small, standalone program.

The Promise

MCP’s promise is straightforward: build once, use everywhere.

Build a tool server once, and every MCP-compatible application can use it. Build a client once, and it can talk to every MCP server. The ecosystem grows combinatorially without anyone needing to coordinate.

A developer in Tokyo builds a server that wraps the Japanese weather API. A developer in Berlin builds a chat application with MCP support. Without any coordination—without even knowing each other exists—the Berlin developer’s application can use the Tokyo developer’s weather data.

This is the power of a shared protocol. It turns an N-times-M integration problem into an N-plus-M ecosystem. And ecosystems, unlike integration codebases, compound.

What You’ll Learn in This Book

This book will take you from “what is MCP?” to “I’m running MCP servers in production and my colleagues think I’m a wizard.” Here’s the journey:

  • Chapters 2–3: The architecture and the wire protocol. How MCP works under the hood.
  • Chapters 4–6: The three primitives—tools, resources, and prompts. What MCP servers expose and how.
  • Chapter 7: Transports. How bits get from client to server and back.
  • Chapters 8–9: Building servers in TypeScript and Python. Hands on the keyboard.
  • Chapter 10: Building MCP clients. The other side of the connection.
  • Chapter 11: The SDK landscape. Every language that speaks MCP.
  • Chapter 12: Configuration. Setting up MCP in Claude Desktop, Claude Code, VS Code, Cursor, and more.
  • Chapter 13: Authentication and security. OAuth 2.1, trust boundaries, and keeping things safe.
  • Chapter 14: Advanced features. Sampling, elicitation, roots, progress tracking, and logging.
  • Chapter 15: Testing and debugging. The MCP Inspector and friends.
  • Chapter 16: Production patterns. Gateways, registries, and scaling.
  • Chapter 17: The ecosystem. A tour of popular MCP servers you can use today.
  • Chapter 18: The future. Where MCP is headed.

Let’s build.