What Does Building an MCP Server Involve?

Filed as AFR/MCP-14 · task class Code modification · all MCP topics

Four decisions and some plumbing

Building an MCP server is four decisions and some plumbing, and the plumbing is the smallest part of it. The decisions: what to expose; how to describe it; how the process will be reached; and what credentials it will hold. Libraries exist for most languages and handle the message layer, so the code that remains is largely the code that would have existed anyway to call the underlying system.

The first decision is granularity, and it is the one most often got wrong. An operation that mirrors an internal function is usually too fine: a caller has to chain five of them and can chain them in the wrong order. An operation taking fifteen optional arguments is too coarse: nothing can tell which combinations are meaningful. The useful unit is a task somebody would name out loud when asking for it.

The second decision is the description, and it is where the work actually is. The name, the summary and the argument schema are the whole interface as far as a caller is concerned — there is no other documentation in the loop. A description that omits a constraint does not produce an error; it produces a confidently wrong call. Writing them well reliably takes longer than implementing the handlers behind them.

The fourth decision is what a caller receives when an operation cannot be completed, and it is the one most often left to whatever the language does by default. A request that was malformed or asked for something unsupported is a failure of the request itself; an operation that ran and could not do the thing is an ordinary result saying so, because the caller is expected to read it and try something else. Only one of the two is worth reporting as the caller’s fault. A failure that says nothing beyond having failed produces the identical call a second time, with the identical outcome.

What is easy to add and hard to take away

Callers read the names, descriptions and schemas at run time instead of compiling against them, which makes adding an operation cheap: nothing that already worked notices. It makes withdrawal expensive in an unusual way. An operation that disappears breaks no build anywhere — it simply stops being listed, and whatever depended on it now behaves as though the capability had never existed.

So a first version’s surface tends to outlive the confidence with which it was drawn, and the operations worth publishing first are the ones somebody has actually asked for. One added because the underlying function happened to be sitting there is a long commitment made on the strength of a convenience.

What the plumbing actually consists of

The plumbing is what remains: complete the initialization exchange and declare what is supported, answer the listing requests, execute an invocation and return its result, and report failures in the form a caller expects. A library does most of it and the specification decides the rest.

How the Registry classifies building a server

Implementing a server and documenting the operations it makes available is code written against a running system, which the code modification class covers. On the order form's task class field, select Code modification, which covers writing, editing, refactoring, and testing code. That class has its own page at /tasks/code.

The Registry files this topic under one canonical task, fixed in advance and published here rather than generated per visit:

Build an MCP server that exposes an internal search service and document the operations it makes available.

That string, hashed once, is 7d1ec686cef0b843… — the first sixteen of sixty-four hex characters. An assessment ordered against a task of this kind is computed from the class, the wording submitted, and the permanent chart the Registry derives for the model configuration named on the order: its ascendant, its ruling planet, and the composite harmony that constrains the range of verdicts available to it. The whole derivation is published at /method.

The risk in building is exposing the operation that was easy rather than the one that was needed — a surface shaped by the convenience of the underlying code instead of by the task. 4 risk factors are tracked for code modification tasks generally; an assessment reports 3 of them, selected by the submitted task's own seed rather than chosen. Their names, severities and descriptions are certificate content and are not published on a free page.

Get Assessment

What this page does not claim

The Registry makes no representation that an assessment predicts the outcome of any task, and no assessment is validated against real-world results.

This page defines a term and states a classification. It publishes no verdict: the Registry does not test implementations, does not measure how often anything works, and has never run the canonical task above against any model. Which language, which library and which transport a build uses are choices the canonical brief leaves entirely open.

What is sold is a permanent, numbered assessment for one submitted task at one model configuration — a verdict on a seven-point scale, a recommended execution window, and, above the first tier, the risk factors the class tracks. EUR 1.90 Standard, EUR 4.90 Extended, and EUR 14.90 Full Chart, which adds the permanent chart for the configuration itself. Assessments from EUR 1.90; machine-readable at /pricing.json.

Related surfaces

← All MCP topics · The AFR-1 method · Code modification task class

Related topics: Tools · Inspecting a server · MCP in Python

Questions about a build

What is involved in building an MCP server?
Deciding what to expose and at what granularity, describing each operation so a caller can use it correctly, implementing the handlers against the underlying system, answering the protocol’s own messages, and deciding how the server is reached and what credentials it holds.
Do I have to implement the protocol messages myself?
Usually not. Libraries handle the message layer in several languages, which leaves the decisions — scope, granularity, descriptions, credentials — as the actual work.
What goes wrong most often?
Granularity and descriptions, rather than code. Operations that mirror internal functions force a caller to chain them correctly, and a description that omits a constraint produces a call that succeeds and is wrong.
How much of the protocol has to be implemented by hand?
Little of it in most cases. Libraries answer the initialization exchange, the listing requests and the message framing. What remains is the part nobody can supply for you: deciding what to expose, describing it accurately, holding the credentials, and deciding what a caller gets back when something fails.