An MCP server is a program that publishes tools to AI assistants over the Model Context Protocol. An assistant that supports MCP, such as ChatGPT, Claude or Claude Code, connects to the server, reads the list of tools with their descriptions and input schemas, and calls them when a user's request needs them. The server executes each call against your real system and returns a result the assistant can read.
That is the whole protocol from your side. What makes a server good or bad is not the protocol code, which the official SDKs handle, but four responsibilities that sit around it.
A tool is a contract, not an endpoint
A tool has a name, a description, an input schema and a result. The assistant decides when to call it from the description alone, so the description is the most important text you will write. "Search the catalogue" is not enough; "Search the shop catalogue by phrase and optional category. Returns one page and a nextCursor; when it is not null, more results exist and you must say so" tells the assistant what it gets, what it must do with the cursor, and what the tool does not do.
A tool is also not an endpoint. An API designed for developers exposes operations; an assistant acting for a customer needs outcomes. The examples in these docs wrap a five-operation API in four tools, and the fifth operation (getOrder) is used internally by one of them rather than exposed. See Tool design: reads, writes and guarded actions.
Four responsibilities
- Credentials stay on the server. The assistant never sees your API key or the user's token. The server holds the upstream credential and attaches it to every call. In the examples it is read from the environment.
- Permissions on every call. A read tool that returns another customer's record is a data leak. Each call must be scoped to the account the request is for.
- Safe writes. A write that the assistant retries after a timeout must not happen twice; a write with consequences must not happen without the user agreeing. The examples use idempotency keys and a
confirmflag. - Honest results and errors. Results are summarised, not raw records. Errors say whether the assistant should fix its input, report nothing found, wait, or stop.
Transports
A server speaks MCP over a transport. Two matter:
- stdio: the client launches the server as a local process. Useful for personal tools and development.
- Streamable HTTP: the server is an HTTPS endpoint, usually at
/mcp. This is what ChatGPT, Claude and any hosted client need, and what every example here uses.
A Streamable HTTP server can be stateless (each request creates a fresh server instance, nothing is held between calls) or session-based. Stateless is simpler to run and scales horizontally; the TypeScript, Python and C# examples use it. PHP's request model makes a small file-backed session store the natural choice, and that example shows it.
What this documentation covers
- The sample API every example wraps, and why its five operations become four tools.
- Building the same server in TypeScript, Python, C# and PHP, with the official SDKs.
- Testing that the four servers expose one identical interface.
- Connecting the server to Claude and ChatGPT.
- What the OpenAPI-to-MCP generators produce from the same API, measured.
- Taking it to production.
Every term used here is defined once in the MCP glossary.