Learning unit · Learning by building

Build an MCP server that does something

No echo tool, no hello world: a server with a domain, nine tools, two transports and two auth models - connected to a real client and deliberately made to fail.

7 steps · around 205 minutes of build time

The component MCP servers explains why the protocol exists and what a server offers. This course builds one.

Not the one with the echo tool. There are enough of those. It answers not a single one of the questions that show up with your second server, and with the second server they all show up at once: Who clears the sessions away? What happens when two clients are there at the same time? How should a failed call look to the model? And how do you describe a tool so that a model can do something with it?

What runs at the end

The Simhaven helpdesk. Eight tickets, a product manual, nine tools. And an agent that classifies, answers, escalates and closes them without a single line of user interface anywhere. Members enter the same scenery from the other side in the parcours; here you build the service their agent works against.

The server runs over both transports, knows two kinds of authorisation, copes with several simultaneous clients and ends up as its own container next to the application. Around 560 lines of TypeScript in six files. No framework. No database. No abstraction layer on top of the SDK.

What you need

Node 22 and nothing else. The course writes TypeScript and lets Node strip the types itself (--experimental-strip-types). No bundler, no build step, no tsc in the way. That is not convenience: the MCP service of this project runs the same way, and mcp/server.ts in the repo is started exactly like that.

Two packages come along, @modelcontextprotocol/sdk and zod. Both ran in the examples at versions 1.30 and 3.25.

Where the examples come from

Everything printed as output in this course is real output. The error messages in chapter 6 were triggered and not staged, the character counts are measured, the container in chapter 7 was built and health-checked. Where a number stands, it stands because that is how it came out.

The second source is this repo itself. Under mcp/ runs a server with sixteen editorial tools and two simulation worlds, with a session cap, a reaper and two auth models side by side. Wherever this course makes a decision, you can read next to it how it was decided there. And where it was once decided wrongly.

The roadmap

7 steps, one insight and one working state each. Every step stands on the one before it.

  1. 01
    The empty server25 min

    The server is done in twenty lines. The decision is the transport, not the code.

    Milestone One tool answers over stdio and over Streamable HTTP, both times against the same client.

  2. 02
    Tools you can actually describe25 min

    The description is not a comment. It is the part of the tool that ends up in the prompt.

    Milestone The schema rejects a wrong category with a message that says which ones would have been right.

  3. 03
    A domain, not a collection40 min

    Nine tools that finish one task are worth more than thirty that half-cover everything.

    Milestone The Simhaven helpdesk runs: eight tickets, read, classify, answer, escalate, close, count.

  4. 04
    State and sessions30 min

    A shared transport rejects the second `initialize` - and a session has to remember what it was opened for.

    Milestone Two clients work in separate inventories at the same time, and the reaper clears both away again.

  5. 05
    Who may do what30 min

    A token per case is the more interesting design: it belongs to a run, not to a user.

    Milestone The same container serves two endpoints with two auth models, and no session wanders between them.

  6. 06
    Connect it and let it fail30 min

    The three typical failures triggered rather than claimed - and one of them looks like a success.

    Milestone Unknown tool, missing required field and a result of 130,152 characters stand there as real output.

  7. 07
    Operations25 min

    A service nobody sweeps and nobody asks falls over exactly when nobody is watching.

    Milestone The server runs as its own container with a health check, a session cap and one log line per call.

Build your own MCP server · building-agents.com