MCP Server & Model Context Protocol Guide
What the Model Context Protocol is
The Model Context Protocol (MCP) is an open standard for connecting AI assistants to external tools and data. A client (Claude Code, Claude Desktop, an IDE, your own agent) connects to an MCP server, finds out what the server offers, and the model then calls those capabilities. One server serves every client that supports the protocol. For broader AI development concepts, see AI Development .
When to use it
- The model should work with your own system — a database, a CMS, a ticketing system, an internal API
- Several clients or agents should use the same integration
- You are debugging a connection between an MCP client and server
- You are deciding whether a new capability should be a tool, a resource or a prompt
Architecture
- Host — the application the model runs in (Claude Code, an IDE, a chat application).
- Client — the part of the host that holds the connection to one server. One client per server.
- Server — the program that offers capabilities. Messages are JSON-RPC 2.0.
A server offers three kinds of capabilities:
| Capability | Controlled by | What it is for | Example |
|---|---|---|---|
| Tools | the model | actions and queries with parameters | create_issue, search_docs |
| Resources | the application / user | content to read, addressed by URI | file:///README.md, db://orders/42 |
| Prompts | the user | prepared task templates | /review-pr |
In the other direction, a client can offer the server sampling (the server asks for text generated by the model), roots (directories it may work with) and elicitation (a question to the user).
Transports
- stdio — the client starts the server as a subprocess and talks over standard input and output. For local tools; no network and no authentication.
- Streamable HTTP — the server runs on its own at a URL and serves several clients. For remote and shared servers; authentication (OAuth or a token in a header) belongs with it.
The older HTTP+SSE transport is replaced by Streamable HTTP in the specification; do not use it for new servers.
Your own MCP server in Python
pip install "mcp[cli]"
# server.py
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("demo")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two integers."""
return a + b
@mcp.resource("note://{name}")
def note(name: str) -> str:
"""Return a note by name."""
return f"Content of note {name}"
@mcp.prompt()
def review(code: str) -> str:
"""A code review task."""
return f"Review this code and list the bugs:\n\n{code}"
if __name__ == "__main__":
mcp.run() # default transport: stdio
The type annotations and the docstring are not decoration: the SDK builds the tool’s JSON schema and description from them, and the model decides from those when and how to call the tool. For HTTP, mcp.run(transport="streamable-http") is enough.
Connecting a client
# Claude Code — a local server over stdio
claude mcp add demo -- python /abs/path/server.py
# Claude Code — a remote server over HTTP
claude mcp add --transport http notes https://example.com/mcp
claude mcp list # connected servers and their status
Configuration shared with the team belongs in a .mcp.json file in the project root:
{
"mcpServers": {
"demo": {
"command": "python",
"args": ["/abs/path/server.py"],
"env": { "API_TOKEN": "${API_TOKEN}" }
}
}
}
Debugging
npx @modelcontextprotocol/inspector python server.py
MCP Inspector opens a web interface where you can list the server’s tools, resources and prompts and call them by hand — without a model and without a client. It is the fastest way to find out whether a problem is in the server or in the client’s configuration.
Protocol method reference
| Area | Methods |
|---|---|
| Lifecycle | initialize, notifications/initialized, ping |
| Tools | tools/list, tools/call, notifications/tools/list_changed |
| Resources | resources/list, resources/templates/list, resources/read, resources/subscribe, resources/unsubscribe, notifications/resources/updated, notifications/resources/list_changed |
| Prompts | prompts/list, prompts/get, notifications/prompts/list_changed |
| Logging | logging/setLevel, notifications/message |
| Client capabilities | sampling/createMessage, roots/list, elicitation/create |
| Utilities | completion/complete, notifications/progress, notifications/cancelled |
A connection always starts with initialize: both sides exchange the protocol version and their capabilities — the list of what each supports. Do not call a method the other side did not announce.
Common mistakes
| Mistake | Symptom | Fix |
|---|---|---|
print() in a stdio server | The client reports a parse error or the connection drops — stdout belongs to JSON-RPC messages | Log to stderr or through notifications/message |
| Relative paths in the configuration | The server does not start, because the client has a different working directory | Absolute paths to the interpreter and the script |
| Missing environment variables | The server runs, but API calls fail | Pass them in the configuration’s env; the client does not load your shell profile |
| A vague tool description | The model does not call the tool, or calls it at the wrong moment | Describe what the tool does, when to use it and what it returns |
| Dozens of tools on one server | The descriptions fill the context and the model picks among them worse | Fewer tools with a clear purpose, split servers by domain |
| Huge tool output | One call fills the context | Paginate, filter and return only the fields needed |
| A remote server without authentication | Anyone with the URL can call the tools | OAuth or a token, least privilege |
| Trusting tool output | Text from the web or a ticket contains instructions the model carries out | Treat output as data, see LLM Attacks |
Frequently asked questions
What is MCP?
MCP (Model Context Protocol) is an open protocol an AI assistant uses to connect to external tools and data. Instead of a separate integration per application, one MCP server is enough, and every client that supports MCP can use it.
What is an MCP server?
An MCP server is a program that offers tools (functions the model can call), resources (data to read) and prompts (prepared templates) over the protocol. It runs either locally as a subprocess of the client, or remotely over HTTP.
What is the difference between MCP and a regular REST API?
A REST API is written for a programmer who knows its documentation. An MCP server describes its capabilities in machine-readable form — a name, a description and a JSON schema of the input — so the model discovers them through tools/list and calls them itself. An MCP server is often a thin layer over an existing API.
What is the difference between a tool and a resource in MCP?
A tool is an action the model calls, and it may change something: create a ticket, run a query. A resource is read-only content identified by a URI, usually picked into the context by the application or the user.
Is MCP secure?
The protocol does not handle security for you. A server runs with the permissions you give it, and a tool’s output can contain planted instructions. Connect only servers you trust, give them the least privilege they need, and protect remote servers with authentication.