An MCP server is a program that exposes tools, data, and prompts to AI applications through the Model Context Protocol (MCP), an open standard for connecting AI models to external systems. You build an MCP server by defining tools with an official SDK, and you use one by adding its URL or launch command to an MCP client such as Claude or Cursor.
This guide follows the 2026-07-28 MCP specification, which changed how MCP servers are built. Many older tutorials describe a flow that no longer applies.
Key takeaways
- An MCP server wraps an external system, such as an issue tracker or a database, so that any MCP-compatible AI application can discover and call its capabilities.
- Tools are the part of an MCP server that matters most. Resources and prompts exist in the specification but see little real-world use.
- Since the 2026-07-28 specification, MCP servers are stateless: there is no handshake and no session ID, and every request carries its own context.
- The quality of an MCP server depends mostly on its tool descriptions. One benchmark of 41,902 MCP servers gave an A grade to only 0.5% of them.
- An MCP server is the wrong choice for a coding agent that already has a terminal and a well-known CLI. It is the right choice when the agent has no shell or must never see credentials.
What is an MCP server?
An MCP server is a program that gives AI applications access to an external system through the Model Context Protocol. The MCP server wraps a service such as GitHub, a database, or an internal tool, and describes what it can do so that an AI model can discover and call those capabilities without custom integration code.
For example, an MCP server for an issue tracker lets a model list, create, and update issues. When a user asks "what is blocking the release?", the model calls the server's search tool and answers from live data.
MCP was introduced by Anthropic in November 2024 and is now an open standard hosted as a Linux Foundation project. The official SDKs see close to half a billion downloads a month, according to the MCP maintainers' July 2026 release post.
How does an MCP server work?
An MCP server works by answering two kinds of request from an AI application: "what tools do you have?" and "run this tool with these arguments." The application shows the tool list to the model, the model picks a tool, and the MCP server executes it and returns the result for the model to use.
| Part | What it is | Example |
|---|---|---|
| Host | The AI application the person uses | Claude, Cursor, a custom support agent |
| Client | The connector inside the host that speaks MCP | One client per connected server |
| MCP server | The program that wraps an external system | A server for GitHub, Postgres, or an internal billing system |
| Tool | A function the model can call | find_overdue_invoices(customer_name) |
| Resource | Read-only data the host can attach as context | A file or a database schema |
| Prompt | A reusable prompt template the user can invoke | A "summarize this incident" template |
Tools are the part of an MCP server worth learning first. Simon Willison, co-creator of Django and a prominent writer on LLM tooling, estimated in September 2026 that tools account for more than 95% of what people use MCP for, and that resources and prompts rarely see widespread use.
Since the 2026-07-28 specification, an MCP server holds no protocol session. Each request carries its own protocol version and client details, so any request can be handled by any server instance behind an ordinary load balancer.
What is the difference between an MCP server and an API?
An API is called by code a developer wrote in advance, while an MCP server is called by an AI model that decides at runtime which capability to use. An MCP server usually sits on top of an existing API and adds what a model needs: discoverable tool names, plain-language descriptions, and typed inputs.
| Criterion | MCP server | REST API |
|---|---|---|
| Who decides what to call | The AI model, at runtime | A developer, at build time |
| How capabilities are discovered | The server lists its tools with descriptions and schemas | A person reads the documentation |
| Shape of each operation | A task, such as "find overdue invoices" | A resource endpoint, such as GET /invoices |
| Where credentials live | In the client or server, outside the model's reach | In the calling code |
| Best for | Letting many AI applications use one system | Application-to-application integration |
An MCP server does not replace an API. The MCP server is the layer that makes an API usable by a model that has never seen its documentation.
Why are MCP servers useful?
MCP servers are useful because one server makes a system available to every MCP-compatible AI application, with no separate integration per model or vendor. An MCP server also keeps credentials away from the model, gives administrators one place to control access, and lets non-developers connect a service by pasting a URL.
- Build once, connect anywhere. One MCP server works with any host that speaks MCP, instead of a custom plugin for each AI product.
- Credentials stay out of the model's reach. The MCP server holds the API keys or handles sign-in, so a manipulated model cannot read or leak them.
- Access is controllable and auditable. An MCP server exposes only the operations its owner chose, and every tool call can be logged.
- Setup takes one step for the end user. Adding a remote MCP server means entering a URL and signing in, with nothing to install.
Simon Willison gave the same four reasons in a September 2026 comment: control over which services an agent can reach, authentication that hides API keys from the agent, a usable interface for connecting services, and audit logging.
When should you not build an MCP server?
You should not build an MCP server when the agent already has a terminal and a well-known command-line tool for the job, or when the task is a fixed workflow that a script could run. An MCP server earns its cost only when the agent has no shell, must never see credentials, or serves non-developers.
| Situation | Better choice | Why |
|---|---|---|
| A coding agent with a terminal, and a mature CLI exists (git, gh, aws) | The CLI | The model already knows the CLI and loads no tool definitions up front |
| The same steps run the same way every time | A script | A fixed workflow needs no model in the loop |
| A chat or support agent with no shell | MCP server | Tools are the only way the agent can act |
| The agent must not be able to read API keys | MCP server | Credentials stay inside the server |
| Non-developers connect their own accounts | Remote MCP server | A URL and a sign-in, with nothing to install |
| Many teams or products need the same system | MCP server | One integration serves every MCP host |
The token cost behind the first row is measured. Scalekit's benchmark of 75 runs found that GitHub's MCP server, which loads 43 tool definitions, used 4 to 32 times more tokens than the gh CLI on the same tasks.
That benchmark measures one implementation choice, not a limit of MCP. An MCP server with five well-described tools, or a host that loads tool definitions on demand, avoids most of that overhead.
How do you build an MCP server?
You build an MCP server in four moves: choose the few tasks it should perform, define each task as a typed function with an official SDK, test it in the MCP Inspector, and run it locally over stdio or remotely over Streamable HTTP. A working single-tool MCP server takes about 25 lines of Python.
- Choose three to five tasks. List what a user would ask for, such as "find overdue invoices", and make each one a tool. Do not mirror every API endpoint.
- Install an official SDK. TypeScript, Python, Go, and C# are the Tier 1 SDKs for the 2026-07-28 specification. For Python, run
uv add "mcp[cli]". - Define each tool as a typed function. The SDK turns the function name, type hints, and docstring into the tool definition the model reads.
- Test the server in the MCP Inspector. Run
uv run mcp dev server.py, call each tool by hand, and check the output. - Pick a transport. Use stdio when the MCP server runs on the user's machine. Use Streamable HTTP when it runs as a hosted service:
uv run mcp run server.py --transport streamable-http. - Add authorization to a remote server. Remote MCP servers use OAuth. The current specification favors Client ID Metadata Documents over Dynamic Client Registration.
- Keep state explicit. If a tool needs to continue earlier work, return a handle, such as a
report_id, and accept it as an argument on the next call.
This complete MCP server follows the pattern in the official Python SDK. It was run against SDK version 2.2.0 on October 1, 2026.
from mcp.server import MCPServer
mcp = MCPServer("Invoices")
INVOICES = [
{"id": "INV-1042", "customer": "Acme Corp", "amount_usd": 1800.0, "days_overdue": 45},
{"id": "INV-1077", "customer": "Acme Corp", "amount_usd": 320.0, "days_overdue": 12},
]
@mcp.tool()
def find_overdue_invoices(customer_name: str, min_days_overdue: int = 30) -> list[dict]:
"""Find unpaid invoices for one customer that are past their due date.
Use this when someone asks what a customer owes or which invoices are late.
Returns a list of invoices with id, amount_usd, and days_overdue, or an
empty list if nothing is overdue. customer_name is the company name as it
appears in billing, for example "Acme Corp".
"""
return [
i for i in INVOICES
if i["customer"].lower() == customer_name.lower()
and i["days_overdue"] >= min_days_overdue
]
Called with customer_name="acme corp", this MCP server returns invoice INV-1042 only, because the second invoice is 12 days overdue and the default threshold is 30. The full tool definition the model receives is 914 characters of JSON.
Many MCP tutorials written before July 2026 describe steps that are now retired or deprecated.
| Older tutorials say | Current practice (2026-07-28 specification) |
|---|---|
Open every connection with an initialize handshake and track Mcp-Session-Id | No handshake and no session ID; each request is self-contained |
| Keep state in the protocol session | Return an explicit handle from a tool and pass it back as an argument |
| Use the HTTP+SSE transport for remote servers | HTTP+SSE is deprecated; use Streamable HTTP |
| Register clients with Dynamic Client Registration | Deprecated in favor of Client ID Metadata Documents |
| Use Sampling, Roots, and Logging | Deprecated; still working for at least twelve months, not for new servers |
from mcp.server.fastmcp import FastMCP | Python SDK v2 uses from mcp.server import MCPServer; pip install mcp now installs 2.x |
How do you write a good MCP tool description?
A good MCP tool description tells the model four things: what the tool does, when to use it, what each parameter means, and what comes back. The model chooses tools by reading these descriptions and nothing else, so a vague description produces wrong tool choices however good the code behind it is.
Most published MCP servers fail this test.
- Arcade's ToolBench (2026) graded 41,902 MCP servers and 218,422 tools. Only 0.5% of servers earned an A, and 167,333 tools received an F. Missing descriptions were the most common problem.
- A 2026 study of 10,831 MCP servers found description flaws were pervasive and called the pattern "code-first, description-last."
- Research summarized in a 2025 empirical paper found that 97.1% of 856 tools had at least one description flaw and 56% did not state their purpose clearly.
The same tool, described two ways:
| Weak | Strong | |
|---|---|---|
| Name | get_data | find_overdue_invoices |
| Description | "Gets data." | "Find unpaid invoices for one customer that are past their due date. Use this when someone asks what a customer owes or which invoices are late." |
| Parameters | id: str | customer_name: str, the company name as it appears in billing, for example "Acme Corp" |
| Return value | Not stated | "A list of invoices with id, amount_usd, and days_overdue, or an empty list if nothing is overdue." |
A checklist for every tool on an MCP server:
- The name is a verb plus a specific object.
- The first sentence states the purpose.
- One sentence says when to use the tool.
- Every parameter has a meaning and an example value.
- The return value is described, including the empty case.
- Error messages tell the model what to do next, such as "customer not found; try search_customers first."
How do you connect and use an MCP server?
You connect an MCP server by adding it to an MCP client: paste the URL of a remote server into the client's connector settings and sign in, or add the launch command of a local server to the client's configuration. After that, you ask for what you want in plain language and the model calls the tools.
- Find the server's address. A remote MCP server has a URL that usually ends in
/mcp. A local MCP server has a launch command, such asuv run mcp run server.py. - Add the server to your client. Remote servers go in the client's connector or integration settings. Local servers go in the client's MCP configuration file.
- Sign in if asked. A remote MCP server normally sends you through an OAuth sign-in so it acts with your permissions.
- Check the tool list. The client shows which tools the MCP server provides. Switch off any you do not need.
- Ask in plain language. The model decides when to call a tool. Most clients ask for approval before a tool changes anything.
The exact menu names differ by client and change often, so follow your client's current documentation for step 2.
How do you vet an MCP server before installing it?
Vet an MCP server the way you would vet a browser extension with access to your accounts: confirm who publishes it, check that it is maintained, read its tool list, and grant the narrowest permissions that work. Anyone can publish an MCP server, and a connected server acts with your credentials.
The ecosystem data supports the caution.
- A measurement study of the MCP ecosystem found that 21.9% of MCP servers had seen no update in more than a year, and only 40.9% were updated in the previous 90 days.
- A study of 10,240 MCP servers found that about 13% had tool descriptions that only partly or rarely matched what the code did.
- An analysis of 177,436 published tools, cited in a 2026 empirical paper, found that tools which modify external systems rose from 27% to 65% of tool usage between November 2024 and February 2026.
- In September 2026 the maintainers of the official MCP Python SDK disclosed a flaw that let a malicious MCP server capture a client's OAuth credentials.
A checklist before connecting any third-party MCP server:
- The publisher is the vendor of the service, or a party you can identify.
- The repository or changelog shows activity in the last 90 days.
- The tool list matches what the server claims to do, with no unexplained extras.
- The sign-in requests only the scopes the tools need.
- Tools that write, send, or delete require approval in your client.
- Your client and SDK versions are current.
Should you run an MCP server locally or remotely?
Run an MCP server locally when it serves one person and needs files or programs on that person's machine. Run an MCP server remotely when it serves a team, customers, or any non-developer, because a remote server needs no installation and handles sign-in through OAuth.
| Criterion | Local MCP server | Remote MCP server |
|---|---|---|
| Transport | stdio | Streamable HTTP |
| Runs on | The user's machine | Hosted infrastructure |
| Setup for the user | Install and edit a configuration file | Paste a URL and sign in |
| Authentication | Keys in local environment or config | OAuth, per user |
| Access to local files and apps | Yes | No |
| Scaling | One user | Any instance can serve any request since the 2026-07-28 specification |
| Best for | Personal tools, development, local data | Products, teams, non-developers |
Most new MCP servers that wrap a hosted service should be remote. The stateless core in the 2026-07-28 specification removed the session handling that used to make remote MCP servers hard to run behind a load balancer.
Frequently asked questions
Is MCP only for Claude?
No. MCP is an open standard hosted as a Linux Foundation project, and an MCP server works with any client that implements the protocol. The July 2026 specification release carried statements of support from AWS, Google Cloud, Microsoft, and Cloudflare, among others.
What languages can you build an MCP server in?
TypeScript, Python, Go, and C# have Tier 1 official SDKs that support the 2026-07-28 specification, and the Rust SDK supports it in beta. Official SDKs also exist for other languages, including PHP. Any language that can serve HTTP or read standard input can implement an MCP server without an SDK.
Is MCP free to use?
Yes. The MCP specification is open and the official SDKs are open source. The costs of an MCP server are hosting for remote servers and the model tokens consumed by tool definitions and tool results.
Do MCP servers use a lot of tokens?
An MCP server uses tokens in proportion to how many tools it defines and how long their descriptions are. Scalekit measured GitHub's 43-tool MCP server at 4 to 32 times the token use of a CLI. A single well-described tool is under 1,000 characters, and many hosts now load tool definitions only when needed.
Is MCP dead?
No. Developers running coding agents with terminal access have moved some work from MCP servers to command-line tools, and that criticism is valid for that case. Across all uses, the MCP maintainers reported close to half a billion SDK downloads a month in July 2026.
What changed in the 2026-07-28 MCP specification?
The 2026-07-28 MCP specification made the protocol stateless. It removed the initialize handshake and the session ID, added routing headers and cacheable tool lists, and deprecated Roots, Sampling, Logging, the HTTP+SSE transport, and Dynamic Client Registration, each with at least a twelve-month window.
Sources and methodology
This guide is based on the MCP specification and SDK documentation, published benchmarks and academic studies, and practitioner discussion, all as of October 1, 2026. The code sample was run against the official Python SDK, version 2.2.0. The ecosystem statistics come from the third-party studies linked below, not from our own measurement.
- The 2026-07-28 Specification, Model Context Protocol blog, July 28, 2026
- MCP Python SDK, official repository
- Simon Willison's comment on "MCP was always a bad idea?", September 20, 2026
- "MCP was always a bad idea?" discussion, Hacker News, September 2026
- MCP vs CLI: Benchmarking AI Agent Cost and Reliability, Scalekit, 2026
- Introducing ToolBench: A Quality Benchmark for MCP Servers, Arcade, 2026
- From Docs to Descriptions: Smell-Aware Evaluation of MCP Server Descriptions, arXiv, 2026
- From REST to MCP: An Empirical Study of API Wrapping and Automated Server Generation for LLM Agents, arXiv
- A Measurement Study of Model Context Protocol Ecosystem, arXiv, 2025
- Understanding and Measuring MCP Behavior under Misleading Tool Descriptions, arXiv, 2026
- An Empirical Study of Model Context Protocol Applications, arXiv, 2026
- Official MCP Python SDK Flaw Can Let Malicious Servers Steal OAuth Credentials, The Hacker News, September 29, 2026

