Loading
0xE0Lesson 15 of 15

Capstone: build a stdio MCP server

Write a working MCP server from scratch that discovers, lists and calls a tool over stdio.

35 min 5-question quiz 1 code exercise
By the end of this lesson you can
  • Read newline-delimited JSON-RPC requests from stdin
  • Answer server/discover, tools/list and tools/call correctly
  • Return the right kind of error for every failure

Time to build the whole thing. Your server will speak MCP over stdio: one JSON-RPC request per line on stdin, one response per line on stdout. In practice you would use an official SDK, which handles this plumbing for you - but writing it once by hand shows exactly what the SDK does, and makes every bug you meet later easier to understand.

Your server must handle:

RequestResponse
any request missing a required _meta fielderror -32602 “Missing required _meta”
server/discoversupportedVersions: ["2026-07-28"], capabilities: {"tools": {}}
tools/listthe add tool definition
tools/call for add with integer a and bthe sum as text content, structuredContent: {"sum": …}, isError: false
tools/call for add with bad argumentsa tool execution error, isError: true
tools/call for an unknown toolerror -32602 “Unknown tool: NAME”
any other methoderror -32601 “Method not found”

Try it

Try the add tool

Before you code it, play the server: send arguments to add and look at the response each one deserves. Your server should produce the same kinds of answers.

The tool, as tools/list describes it

{
  "name": "add",
  "description": "Add two integers.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "a": {
        "type": "integer"
      },
      "b": {
        "type": "integer"
      }
    },
    "required": [
      "a",
      "b"
    ],
    "additionalProperties": false
  }
}

The server’s responseSuccess

{
  "jsonrpc": "2.0",
  "id": 7,
  "result": {
    "resultType": "complete",
    "content": [
      {
        "type": "text",
        "text": "Added 2 and 3."
      }
    ],
    "isError": false
  }
}

Key takeaways

  • A stdio server is a loop: read a line, handle the request, write one JSON line.

  • Check _meta first, dispatch on method, and validate arguments before doing anything.

  • Unknown methods → -32601; unknown tools or missing _meta → -32602; bad tool arguments → isError: true.

Lesson quiz

5 questions · pass with 4 correct · up to 50 XP

Passing this quiz completes the lesson and keeps your streak going. Questions you miss come back in review sessions later.

Practice: write Python

Write Python in the editor and run it against sample inputs. Python runs locally in your browser using a WebAssembly runtime.

Exercise 1

Build the server

+25 XP

Complete handle so the server answers every request as described in the table above, printing exactly one JSON line per request with the respond helper.

  • Error messages: Missing required _meta, Unknown tool: NAME, Method not found.
  • For bad add arguments, the text is Invalid arguments: a and b must be integers (arguments must be exactly a and b, both integers, not booleans).
  • For a successful add, return {"content": [{"type": "text", "text": "SUM"}], "structuredContent": {"sum": SUM}, "isError": false}.
  • Discover, list and add
  • Every kind of error
  • Tool list
main.py
Loading editor…

Python runs in a sandboxed browser worker with a 60 second time limit. Its runtime loads from the Pyodide CDN; your code stays in this browser.

Questions about this lesson

Stuck? Ask. Figured something out? Share it. Explaining is one of the best ways to learn.

Loading posts…

Did you like the lesson? 😆👍
Consider a donation to support our work: