Languages: EN RU

Model Context Protocol: Architecture and Fundamentals

In the previous section, we covered Claude Code's extension mechanisms — commands, skills, subagents, hooks. All of them operate inside the agent loop. MCP is a different layer: not an extension of agent behavior, but a standard communication channel between any AI application and the outside world. Understand the protocol's architecture once, and you'll know how to use any MCP server and write your own.

Where MCP Came From

Anthropic announced the Model Context Protocol on November 25, 2024 as an open standard with code on GitHub and ready-to-use SDKs. The idea grew out of a concrete problem: every AI integration required a separate implementation for every tool. Want to connect GitHub — write a GitHub adapter. Want Postgres — write another one. N tools × M AI applications = N×M custom integrations. That doesn't scale.

The N×M integration problem: every AI application requires a dedicated adapter for every tool, leading to an explosion in the number of connections.Source: descope.com

MCP solves the problem the same way USB-C solved the cable charger problem: one standard connector — and any device works with any charger. Write an MCP server once, and it works with Claude Code, VS Code Copilot, Cursor, ChatGPT, and any other MCP client.

An important implication: MCP does not belong to Claude Code. Anthropic created the specification and the initial SDKs, but the protocol is open. VS Code, Cursor, OpenAI ChatGPT — all of these are already MCP clients. If you write an MCP server for your database, it will work with any of them without modification.

Check yourself
MCP was created by Anthropic — so the protocol is tied to Claude and only works in Claude Code. Do you agree? Why or why not?

Three Roles in the Architecture

MCP divides participants into three roles:

MCP Host — the AI application as a whole (Claude Code, Claude Desktop, VS Code). It coordinates connections and manages the lifecycle.

MCP Client — a component inside the host that maintains a single connection to a single server. The host creates a separate client for each connected server. Claude Code with three connected servers is one host and three clients.

MCP Server — a program that exposes tools, data, and templates. It can run locally (a process on the same machine) or remotely (on an external server).

graph TB subgraph Host["MCP Host (e.g., Claude Code)"] C1["MCP Client 1"] C2["MCP Client 2"] C3["MCP Client 3"] end S1["MCP Server\nFile System\n(local, stdio)"] S2["MCP Server\nPostgres\n(local, stdio)"] S3["MCP Server\nGitHub API\n(remote, HTTP)"] C1 -->|"dedicated connection"| S1 C2 -->|"dedicated connection"| S2 C3 -->|"dedicated connection"| S3 style Host fill:#f0f4ff,stroke:#6b7cff
graph TB
    subgraph Host["MCP Host (e.g., Claude Code)"]
        C1["MCP Client 1"]
        C2["MCP Client 2"]
        C3["MCP Client 3"]
    end

    S1["MCP Server\nFile System\n(local, stdio)"]
    S2["MCP Server\nPostgres\n(local, stdio)"]
    S3["MCP Server\nGitHub API\n(remote, HTTP)"]

    C1 -->|"dedicated connection"| S1
    C2 -->|"dedicated connection"| S2
    C3 -->|"dedicated connection"| S3

    style Host fill:#f0f4ff,stroke:#6b7cff
The host creates a separate client for each connected server; servers can be local or remote

The client and server communicate over the JSON-RPC 2.0 protocol. First comes a handshake: the client sends initialize with the protocol version and a list of supported capabilities, and the server replies with its own. After that, the client knows what the server has to offer: tools, resources, prompts — or only a subset of them.

// Client → Server: initialization
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-06-18",
    "capabilities": { "elicitation": {} },
    "clientInfo": { "name": "claude-code", "version": "1.0.0" }
  }
}

// Server → Client: response
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2025-06-18",
    "capabilities": {
      "tools": { "listChanged": true },
      "resources": {}
    },
    "serverInfo": { "name": "my-postgres-server", "version": "0.3.0" }
  }
}

Here "tools": { "listChanged": true } means: "I have tools, and I will notify you if they change." The client saves these capabilities and uses only what the server has declared.

Three Primitives: Tools, Resources, Prompts

Primitives are the core concept in MCP. They define what a server can share with a client.

Tools — executable functions. The client invokes them via tools/call, the server runs the code and returns a result. Examples: querying a database, calling an external API, searching the filesystem. This is the most commonly used primitive — it is what allows Claude Code to "act" in the real world.

// Tool invocation
{ "method": "tools/call",
  "params": {
    "name": "query_database",
    "arguments": { "sql": "SELECT * FROM users LIMIT 10" }
  }
}

Resources — read-only data sources. This is context: a database schema, file contents, a list of tasks from a tracker. Resources do not perform actions — they provide data that the AI uses to understand the situation. They are identified by URI, enumerated via resources/list, and read via resources/read.

Prompts — ready-made interaction templates: system prompts, few-shot examples, boilerplate for common tasks. The server can offer them to the client via prompts/list. They are used less frequently in Claude Code, but are useful for standardizing interactions with specific tools.

Check yourself
You have an MCP server for Postgres. Claude Code wants to discover which tools are available. What happens first — and which method is used?

Every primitive follows the same pattern: */list for discovery, */get or */read to retrieve content, tools/call to execute. The client always asks "what do you have?" first, then uses it.

Two Transports

The protocol does not dictate exactly how the client and server exchange bytes. That is the job of the transport layer, and MCP supports two options:

Stdio — standard input/output streams. The host launches the server as a child process and communicates via stdin/stdout. No network overhead, maximum speed, direct process isolation. Suitable for local servers: filesystem, local database, utilities.

Streamable HTTP — HTTP POST for requests from the client, optionally Server-Sent Events for streaming responses from the server. Supports standard HTTP authentication mechanisms (bearer tokens, API keys). For remote servers, MCP recommends OAuth. Suitable for cloud integrations: SaaS APIs, enterprise systems, public services.

Most servers in the official registry use stdio for local installation. Remote MCP servers (Sentry, GitHub Cloud API, and similar) use Streamable HTTP.

# Local server via stdio (in Claude Code config)
claude mcp add my-db -- node /path/to/db-server/index.js

# Remote server via HTTP (with OAuth)
claude mcp add sentry --url https://mcp.sentry.io/

Place in the Ecosystem

By mid-2026, MCP is supported by Visual Studio Code (Copilot), Cursor, ChatGPT, JetBrains, Zed, and dozens of other tools. The official server registry on GitHub contains ready-made integrations: GitHub, Postgres, SQLite, Slack, Google Drive, Puppeteer, Brave Search, and more.

This means: if your company already runs an MCP server for an internal knowledge base, every team member can use it — through Claude Code, through Cursor, or through any other compatible client — without rewriting the integration.

Check yourself
Your colleague has built an MCP server for your company's internal CRM. Who will be able to use it?

In the context of Claude Code, MCP is the "sixth mechanism" that didn't make it into the table in the previous article. Commands, skills, subagents, and hooks extend agent behavior from within. An MCP server is an external system that the agent calls as a tool. Neither a skill nor a command can give Claude Code a live connection to a database. MCP is the only way to do that.


Quick recall
Когда в MCP выбрать Tool вместо Resource?
Quick recall
Почему в MCP хост создаёт отдельный клиент для каждого подключённого сервера, вместо одного клиента на всех?
Quick recall
Как Model Context Protocol решает проблему N×M кастомных интеграций?

See also

  • Connecting MCP Servers in Claude Code — the claude mcp add command, local/project/user scopes, the .mcp.json file
  • Building Your Own MCP Server — FastMCP, Python and TypeScript SDKs, MCP Inspector
  • Practice: GitHub, Databases, and Web APIs via MCP — real integrations with pattern walkthroughs
  • What to Choose: Command, Skill, Subagent, MCP, or Hook — when MCP is the only right answer
  • Tool Use, MCP, and Streaming in the API — how MCP works at the Claude API level
  • Claude Agent SDK: Building Agents Programmatically — programmatic management of MCP connections

Sources

  1. What is the Model Context Protocol (MCP)?
  2. MCP Architecture Overview
  3. Introducing the Model Context Protocol — Anthropic