What is an MCP server?
An MCP server is a program that exposes tools, data and prompt templates to AI applications through the Model Context Protocol (MCP), an open standard. Any MCP-compatible client – Claude, ChatGPT, Cursor, VS Code and others – can connect to it and let a model call your actions and read your data, without a custom integration per AI product.
I build and run one for Craaft, a kanban board where people and AI agents work the same cards. This guide covers what MCP actually specifies, how the pieces fit together, where people get it wrong, and when it’s worth shipping one for your own product.
What is MCP, in one paragraph?
MCP is a protocol for connecting language-model applications to the outside world. Anthropic published it as an open specification in late 2024 and it has since been adopted across most major AI clients. It’s built on JSON-RPC 2.0: the client and server exchange small JSON messages – requests, responses and notifications – over a transport. The useful comparison is the Language Server Protocol. Before LSP, every editor needed its own plugin for every language. Before MCP, every AI app needed its own connector for every service. MCP turns an M × N integration problem into M + N.
That’s the whole idea. MCP doesn’t make a model smarter, and it isn’t an agent framework. It’s a contract for how an AI application discovers what a service can do and then asks it to do it.
Hosts, clients and servers
The spec defines three roles, and most confusion about MCP comes from mixing them up.
- Host – the AI application the user is actually in: a desktop chat app, an IDE, an agent runtime. The host owns the model, the conversation and the user’s consent decisions.
- Client – a connector inside the host. The host creates one client per server, and each client talks to exactly one server.
- Server – your program. It declares what it offers, executes calls, and returns results. It never sees the whole conversation, only the requests the host decides to send it.
There’s no connection handshake in the current spec (2026-07-28): every request carries its protocol version and the client’s capabilities, and the server advertises its own through a server/discover call. Revisions up to 2025-11-25 did this once, in an initialize handshake, so you’ll still meet that in older clients and servers. A server that only offers tools says so; a client that supports elicitation says so. Nothing is assumed, which is why a minimal server can be a couple of hundred lines and still work with every compliant client.
What are MCP servers made of? Tools, resources and prompts
A server can expose three kinds of primitive. The difference between them is who decides when they’re used.
- Tools are model-controlled. Each has a name, a description and a JSON Schema for its input (and optionally its output). The model reads the descriptions and decides to call them – create_card, move_card, refund_payment. Tools are where side effects live, so they’re where your security thinking should go first.
- Resources are application-controlled. They’re read-only data identified by URI – a file, a record, a board export – that the host can attach to context, often because the user picked it. Servers can also publish URI templates and notify clients when a resource changes.
- Prompts are user-controlled. They’re reusable templates, usually surfaced as slash commands, that package a known-good instruction plus arguments – “summarize this sprint”, “draft a release note for card X”.
Clients can offer primitives back to servers too: sampling (the server asks the host’s model to generate something), roots (which directories or URIs the server should work within), and elicitation (the server asks the user for a missing piece of input mid-task). Few servers need these, and the 2026-07-28 revision deprecates sampling and roots, so don’t build new servers on them. Tools alone cover most products.
Transports: stdio and streamable HTTP
The protocol messages are the same regardless of how they travel. MCP defines two standard transports.
- stdio. The host launches your server as a local subprocess and talks to it over standard input and output. Simple, fast, no network exposure. It’s the right choice for developer tools that touch the local filesystem or run CLIs. Credentials typically come from environment variables, and the server runs with the user’s own local permissions.
- Streamable HTTP. Your server is a remote service with a single HTTP endpoint. The client POSTs JSON-RPC messages to it; the server answers with a plain JSON response or opens a Server-Sent Events stream when it needs to send progress, notifications or several messages. There are no protocol-level sessions: the 2026-07-28 revision removed the Mcp-Session-Id header that older tutorials show, so a server that needs state across calls returns its own handle and takes it back as an ordinary tool argument. Streamable HTTP replaced the earlier two-endpoint HTTP+SSE transport, which you’ll still see in older tutorials.
If you’re a SaaS company, you want streamable HTTP. Your customers shouldn’t have to install a Node package and paste an API key into a config file to use your product from their AI client. A hosted endpoint at a stable URL, with proper sign-in, is the version people actually adopt.
How authentication works for remote MCP servers
For HTTP transports, the spec builds authorization on OAuth 2.1. Your MCP server acts as an OAuth resource server; a separate (or co-located) authorization server issues tokens. The flow looks like this:
- The client calls your server without a token and gets a 401 with a WWW-Authenticate header pointing to your protected resource metadata document.
- That document names the authorization server(s). The client fetches the authorization server’s metadata to find its endpoints.
- If the client isn’t already known, it identifies itself with a Client ID Metadata Document – an HTTPS URL used as the client ID that points to a JSON description of the client. Dynamic client registration, which older guides describe, is deprecated and kept only as a fallback.
- The user signs in and consents in a normal browser OAuth flow with PKCE. The client asks for a token scoped to your server specifically (the resource parameter), so the token can’t be replayed against another service.
- Every MCP request carries the bearer token. Your server validates it – issuer, audience, expiry, scopes – on every call.
Two rules matter more than the rest. First, validate that the token was issued for your server; don’t accept any token that happens to be valid at your identity provider. Second, never pass the client’s token through to downstream APIs. If your MCP server calls another service, it uses its own credentials for that call. Token passthrough is explicitly forbidden by the spec because it turns your server into a confused deputy. I cover the wider threat model in AI agent security.
A worked example: Craaft’s MCP server
Craaft is a kanban board. The interesting product decision was that AI agents shouldn’t get a separate “AI mode” – they should work the same board as the humans, with the same cards, the same permissions, and every move visible live to everyone.
MCP made that cheap to offer. The server exposes tools that mirror what a person does in the UI: get_board, search_cards, create_card, move_card, add_comment, add_checklist_item, and so on. An agent in Claude or an IDE can pick up a card, read its checklist, do the work, comment with what it changed, and move the card to review. A human sees the card slide across the board in real time and reviews it like any colleague’s work.
A few things I’d repeat on any MCP server:
- The MCP server is a thin layer over the same service code as the REST API. Permission checks live in one place, so an agent can never do something its user couldn’t.
- Tool descriptions are product copy. The model only knows what you tell it. Saying when to use a tool, what it returns, and what not to use it for changes agent behavior more than any other single fix.
- Tools are shaped around tasks, not tables. A get_focus tool that returns “what should I work on next” beats forcing the model to page through every card and work it out.
- Results are compact and structured. Agents pay for every token you return. Return IDs and the fields that matter, not the full object graph.
Why SaaS companies should ship an MCP server
Your customers are starting to do work from inside AI clients. If your product isn’t reachable from there, the agent routes around it – it uses a competitor that is, or it scrapes your UI badly. An MCP server is the cheapest way to be present: one integration that works across every compliant client, maintained by you rather than by a third party guessing at your API.
It’s also smaller than people expect. If you already have a clean internal service layer and OAuth, a useful first version is usually a few well-chosen tools, not a rewrite. If you don’t have those, the MCP project tends to expose that, which is useful in itself. I do this as a custom MCP server engagement, usually alongside broader AI integration work.
MCP server checklist
- Streamable HTTP endpoint at a stable URL; stdio only if the job is genuinely local.
- OAuth 2.1 with protected resource metadata, PKCE, audience-bound tokens, no token passthrough.
- Tools call the same authorization code path as your API and UI.
- Five to fifteen task-shaped tools to start, each with a description that says when to use it.
- Input schemas with enums and required fields; reject anything outside them.
- Read-only tools separated from destructive ones, with annotations set honestly (clients treat them as hints, not guarantees).
- Pagination and size limits on every list-style result.
- Per-user rate limits and an audit log of every tool call with the acting user and client.
- Errors returned as tool results the model can read and recover from, not stack traces.
- An eval set of real tasks you rerun when you change tool names or descriptions.
When you don’t need one
If nobody will use your product from an AI client, don’t build one for the press release. If you’re building an AI feature inside your own app, you control both ends and can call functions directly – MCP adds a process boundary you may not need. And if your public API is still unstable, fix that first; an MCP server inherits every inconsistency underneath it. For the broader question of what agents are good for, see AI agents for business.
Questions
What is an MCP server in AI?
It’s a service that speaks the Model Context Protocol so AI applications can use it. The server lists tools (actions), resources (data) and prompts (templates). An AI client connects, discovers them, and lets the model call the tools on the user’s behalf – with the user’s permissions and, for remote servers, after an OAuth sign-in.
Is an MCP server the same as an API?
No, but it usually sits on top of one. An API is designed for developers who read docs and write code. An MCP server is designed for a model that reads tool descriptions at runtime and decides what to call. It adds discovery, capability negotiation and a common auth flow, so one integration works across many AI clients.
What is the difference between MCP tools and resources?
Tools are actions the model decides to invoke, and they can have side effects – creating a record, sending a message. Resources are read-only data addressed by URI that the host application or user chooses to attach to context. If it changes state, make it a tool. If it’s reference material, a resource is often the better fit.
Are MCP servers secure?
They’re as secure as you build them. The protocol defines OAuth-based authorization for remote servers, but it can’t stop a model from being manipulated by prompt injection in the data it reads. Scope tools tightly, enforce permissions server-side, require human confirmation for destructive actions, and log every call.
Should I use stdio or HTTP for my MCP server?
Use stdio for local developer tools that need the user’s filesystem or shell. Use streamable HTTP for anything a SaaS customer connects to: it needs no local install, supports proper OAuth sign-in, and lets you deploy fixes without asking every user to update a package.
Want your product usable from Claude, ChatGPT and Cursor?
Tell me what your API does today. In a two-week sprint we can ship a working remote MCP server with OAuth and a first set of tools, then decide what comes next.
GMT+2 · Full EU overlap · US East mornings