If you have spent any time around AI agents in the last year, you have run into the phrase "MCP server." A README tells you to add one. Your coding assistant lists a dozen of them. Someone on your team says the database is "now available over MCP." It sounds like infrastructure — and in a sense it is — but the concept is much smaller and more practical than the jargon suggests.
This article explains what an MCP server actually is, what it exposes, the difference between local and remote servers, and how to add one to the AI tools you already use. For the protocol's history, design rationale, and where it sits among other agent standards, see what is the Model Context Protocol. Here we stay close to the server itself.
What an MCP server actually is
The Model Context Protocol (MCP) is an open standard, created by Anthropic and announced in late November 2024, that standardizes how AI applications connect to external tools and data. The usual analogy is "USB-C for AI integrations," and it is a good one: instead of writing bespoke glue for every app-to-tool pairing, you implement the protocol once on each side and everything interoperates. In December 2025, Anthropic donated MCP to the Agentic AI Foundation, a directed fund under the Linux Foundation, so it is now vendor-neutral and governed in the open.
MCP defines three roles:
- Host — the AI application that initiates connections and manages everything: an IDE, a chat app, or an AI agent.
- Client — a connector that lives inside the host and maintains a one-to-one stateful connection to a single server.
- Server — the service that exposes capabilities to the client.
An MCP server, then, is the piece you install or point at. It is a program — often a tiny one — that advertises what it can do and answers requests. The host's client connects to it, the two negotiate capabilities at initialization, and from then on the model can use whatever the server offers.
The wire format underneath is JSON-RPC 2.0 over a chosen transport, with stateful connections and explicit capability negotiation. The current stable specification revision is 2025-11-25.
What a server exposes: tools, resources, and prompts
A server offers any combination of three server primitives:
| Primitive | What it is | Who controls it |
|---|---|---|
| Tools | Functions the model can invoke to take an action or compute a result | Model-controlled |
| Resources | Contextual data or content the host/model can read (files, records, docs) | Application- or user-controlled |
| Prompts | Reusable templated messages or workflows | Usually user-initiated |
Tools are the headline feature — a filesystem server's read_file, a GitHub server's create_issue, a database server's run_query. Under the hood, MCP tools map onto the model's native function calling (also called tool use): the host hands the model the server's tool schemas, the model emits a structured call, and the host routes it to the server. MCP does not replace function calling — it standardizes how those tools are discovered, described, and connected so you do not have to wire each one by hand.
There are also client primitives that flow the other way — sampling (the server can ask the host's LLM to generate a completion, with user approval), roots (the server asks which filesystem boundaries it may operate in), and elicitation (the server requests structured input mid-task). Most day-to-day servers you install lean almost entirely on tools and resources, but it is worth knowing the channel is bidirectional.
Local (stdio) vs remote (Streamable HTTP)
Every MCP server is reached over one of two transports, and which one a server uses determines how you configure it.
| Local — stdio | Remote — Streamable HTTP | |
|---|---|---|
| How it runs | Host launches the server as a subprocess | Server runs at a network endpoint |
| Channel | Newline-delimited JSON-RPC over stdin/stdout; stderr for logs | Single HTTP endpoint (POST + GET), optional SSE for streaming |
| Config field | command, args, env | url (plus optional headers) |
| Sessions | Per-process | Optional MCP-Session-Id header for stateful sessions |
| Auth | Local OS / env vars | Optional OAuth 2.1; MCP-Protocol-Version header required |
| Best for | Local filesystem, local DB, local credentials | Hosted/shared services, multi-user, SaaS |
A few notes that save confusion. Clients should support stdio whenever possible, so it is the safe default for anything that runs on your own machine. Streamable HTTP was introduced in the 2025-03-26 spec revision and replaced the original HTTP+SSE transport from the first (2024-11-05) revision; that old SSE transport is deprecated, though the spec still documents backward-compatibility handling for it. For new setups, the rule is simple: local tool, use stdio; hosted tool, use Streamable HTTP; avoid standalone SSE.
A working config block
Configuration almost always comes down to a JSON object keyed on mcpServers. Here is what both transports look like — a local filesystem-style server and a remote HTTP server, side by side:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/you/projects"],
"env": {
"LOG_LEVEL": "info"
}
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_PERSONAL_ACCESS_TOKEN}"
}
},
"company-api": {
"url": "https://mcp.example.com/mcp",
"headers": {
"Authorization": "Bearer ${COMPANY_MCP_TOKEN}"
}
}
}
}
The local entries (command / args / env) launch a subprocess over stdio. The remote entry (url) connects over Streamable HTTP. Note the ${VAR} references for secrets — keep tokens in environment variables, never hard-coded in a committed file.
This is the canonical shape, but the field names and file locations vary by tool. Some CLIs want httpUrl instead of url for remote servers; one stores config in TOML rather than JSON. That per-tool variance is exactly what trips people up.
Generate this for your client: build a paste-ready config block — local or remote — for Claude Code, Claude Desktop, VS Code, Cursor, or Codex CLI without hand-editing JSON.
MCP Server Config Generator
Generate paste-ready MCP server config for Claude Code, Claude Desktop, VS Code, Cursor, and Codex CLI — stdio (command/args/env) or remote Streamable HTTP — with one-click copy for each client.
Open the full MCP Server Config Generator tool →Categories of servers you will actually use
You rarely build a server before you have used a handful. The common categories:
| Category | What it gives the model | Typical transport |
|---|---|---|
| Filesystem | Read/write/search files within allowed directories | stdio (local) |
| Version control (e.g. GitHub) | Read repos, issues, and PRs; create issues/PRs | stdio or HTTP |
| Databases | Run queries and inspect schema | stdio (local) or HTTP |
| Web | Fetch pages, search, scrape content into context | HTTP or stdio |
There is also an official MCP Registry — an open catalog and API for discovering public servers — which launched in preview on September 8, 2025 at registry.modelcontextprotocol.io. It is still officially in preview, so treat it as a discovery aid rather than a guarantee of quality or durability. As always, what a server can do is bounded by the credentials and directories you hand it.
How to add one
This is the build-intent part, and the honest answer is that the protocol is universal but the configuration is not. Each AI tool stores its MCP config in a different place with slightly different field names — url vs httpUrl, JSON vs TOML, three different meanings of "scope."
Two resources do the heavy lifting:
-
The per-tool walkthrough. Our guide on how to add an MCP server to any AI coding CLI covers Claude Code, Codex CLI, Gemini CLI, Qwen Code, and Oh My Pi — config file locations, scopes, secrets handling, and the field-name gotchas (including the
urlvshttpUrltrap) for each. -
The config generators. Rather than hand-edit JSON, paste your server details into the generator for your tool and copy a correct block out:
If you are weighing MCP servers against the other extension points in a coding agent, our breakdown of MCP vs subagents, skills, and hooks explains when a server is the right tool and when it is not.
Building your own
If no existing server does what you need, write one. The MCP project ships official SDKs for Python, TypeScript, Java/Kotlin, C#, Go, and more. The shape of the work is the same regardless of language:
- Decide what you expose — which tools, resources, and prompts, and their JSON schemas.
- Implement the handlers — the code that actually runs when the model calls a tool or reads a resource.
- Pick a transport — stdio if it runs locally next to the host, Streamable HTTP if you are hosting it for others.
- Let the protocol handle the rest — discovery and capability negotiation are built in, so once your server speaks MCP, any compatible host can connect.
A local stdio server can be a few dozen lines wrapping an internal API or CLI. One discipline to remember up front: for stdio servers, never write to stdout for logging — anything on stdout corrupts the JSON-RPC channel. Logs go to stderr. If you plan to host it, you also inherit the responsibilities of an OAuth 2.1 resource server, which the spec's authorization section covers in detail.
Check your config before you ship it: paste an mcpServers block to validate the transport shape and catch hard-coded secrets that belong in environment variables.
MCP Config Validator
Paste your mcpServers JSON and lint it — validates the transport shape, catches common mistakes (url vs httpUrl, args not an array), and flags hard-coded secrets that belong in environment variables.
Open the full MCP Config Validator tool →A word on security
An MCP server runs with your privileges and can see whatever you give it access to. That makes it a real attack surface, and the research over 2025 bears this out. Documented risk classes include tool poisoning (hidden instructions buried in a tool's description that the model obeys silently), prompt injection via the content a tool returns, the confused-deputy problem (a server with one broad token tricked into using it across boundaries), rug pulls (a server that is benign at approval time and changes behavior later), and the supply-chain risk of thousands of unvetted community servers. Real CVEs exist across these classes — from the Cursor "MCPoison" rug-pull flaw to command-injection RCEs in popular community servers.
The defenses are straightforward but not optional: prefer first-party or signed servers, allowlist what you connect, use least-privilege scoped credentials, keep a human in the loop for sensitive or irreversible actions, and treat both tool descriptions and tool outputs as untrusted input. Before you connect anything you did not write — especially anything touching credentials, a shell, or production data — read our deeper analysis in MCP security risks.
The short version
An MCP server is a small program that exposes tools, resources, and prompts to an AI app over a standard JSON-RPC protocol. Local servers run as a subprocess over stdio; remote servers run behind an HTTP endpoint over Streamable HTTP. Adding one is a matter of a small config block — command/args/env for local, url for remote — and the field names vary just enough between tools that a config generator and the add-a-server guide are worth keeping bookmarked. Once you understand that one shape, every "now available over MCP" announcement stops being mysterious and starts being useful.