Skip to content
Agent Month

MCP server

Last verified: June 2026· definition

If the Model Context Protocol is the standard, an MCP server is the thing that implements it for a specific system. It advertises a set of tools (typically read, search, create, update operations), and any MCP client — Claude Code, Cursor, and others — can discover those tools and call them mid-task.

The protocol part is the easy part; there are community and official servers for many popular systems. What separates a demo from something a team can rely on is everything around it: credentials scoped to least privilege, read-only defaults, rate and cost guards, audit logs on every call, and a human approval gate on anything destructive.

The strategic value is reuse. Build the server once and every agent and engineer in the company reaches that system through the same governed path, instead of each team hand-rolling its own integration with its own credentials.

Tool design is the whole job

A server exposing one tool per API endpoint conforms to the protocol and performs badly, because selection accuracy falls as tools multiply and their descriptions overlap. The useful version exposes a small number of task-shaped tools matching what someone actually wants done, each with a description leading on when to use it rather than only what it does. Getting this right does more for agent reliability than any other decision in the build.

Identity comes from the session, never the arguments

The most serious mistake in MCP server design is accepting a tenant or user identifier as a tool argument the model supplies. Anything the model can set can be influenced by content it has read, so that pattern creates a cross-tenant access path by construction. Identity must be derived from the authenticated connection and applied server-side, with the model’s arguments treated as untrusted input subject to authorisation checks.

Transport determines the requirements

A stdio server launched as a local subprocess has a simple lifecycle and no network surface. A remote server over HTTP needs OAuth, connection management, rate limiting, and multi-tenant isolation, and becomes a service with uptime expectations. One consequence catches people repeatedly: on stdio, stdout carries the protocol, so any logging written there corrupts the stream and breaks the connection. Logs go to stderr.

Observability and approval gates

Because a server is where agent actions become real effects, it is the correct place to log what was called, by which identity, with what arguments and outcome. It is also where approval requirements on destructive operations belong — deletes, payments, outbound messages. Agents retry and occasionally misfire, and a gate at the server converts a routine mistake into a prompt rather than an incident.

Common misconceptions

  • MythAn MCP server is a thin wrapper over an API.

    RealityThat is the version that works poorly. Useful servers reshape capabilities into task-level tools and add authorisation, approval, and logging that the underlying API does not provide.

  • MythInternal servers need less security.

    RealityInternal agents typically hold broader permissions and read untrusted content such as tickets and emails. The blast radius is frequently larger internally, not smaller.

  • MythIf it connects, it is configured correctly.

    RealityA connected server can still fail to register tools, usually because it wrote to stdout on a stdio transport or errored during initialisation after the connection opened.

Frequently asked questions

How many tools should an MCP server expose?

Fewer than instinct suggests. Selection accuracy degrades as the number grows and descriptions start to overlap, so a handful of well-separated, task-shaped tools outperforms dozens mirroring individual endpoints. Where a large surface must genuinely be available, grouping related operations behind fewer entry points with a clear parameter generally works better than enumerating everything.

Why do my server’s tools not appear in the client?

Most often the server wrote something to stdout. On a stdio transport stdout is the protocol channel, so a log line, banner, or stray print corrupts the JSON-RPC stream and the handshake never completes — the connection looks established but no tools register. Move all logging to stderr. The other common cause is an error during initialisation after the connection opened, which the client’s MCP log will show.

How should an MCP server handle multi-tenancy?

Derive the tenant from the authenticated session and enforce scoping inside the server, treating every model-supplied argument as untrusted. Never accept a tenant identifier as a tool parameter, because injected content can influence what the model sends. Every data access should be constrained by the session identity server-side, and each call logged with that identity so cross-tenant attempts are visible.

Go deeper