Getting Started with Model Context Protocol in 2026
Learn how MCP works at the code level: the JSON-RPC handshake, tool registration, and transport options. Includes a working FastMCP example.
Lee Li
Independent Developer · MCP Enthusiast
Getting Started with Model Context Protocol in 2026
Before Model Context Protocol existed, connecting an AI assistant to your codebase was a bespoke engineering project. Every team wrote custom glue code. You had to figure out how to parse project structure, map file paths, serialize context into prompts—and then repeat when your colleague wanted a different AI. The problem was never the AI itself—it was the integration layer.
When Anthropic released MCP, the core insight was simple: what if instead of building N integrations for M tools, we defined one protocol that all of them spoke?
Note on sources: This explanation of FastMCP internals is based on my reading of the FastMCP source code (approximately 800 lines at anthropics/fastmcp on GitHub). I will note where my explanation differs from or extends the official documentation.
The Decorator Mechanics: What Actually Happens
When you write @mcp.tool(), the decorator does three things in sequence:
When a JSON-RPC tools/call message arrives, the handler looks up the tool name in this registry and invokes the node.
Note on official documentation vs. practical experience: The official FastMCP documentation describes the decorator as "minimal boilerplate." My experience is that it works as described for simple cases, but debugging registration issues requires understanding the three-step process above. If you see "Tool not found," check that the decorator ran and the name matches exactly.
The Protocol Handler: JSON-RPC Under the Hood
When the MCP host sends a JSON-RPC tools/call request, FastMCP's handler does four things:
If you have used FastAPI or Pydantic, this flow will feel familiar. The key difference from FastAPI is that MCP tools do not return HTTP responses—they return structured data that the MCP host interprets.
Performance note: In my tests on MacBook Pro M3, FastMCP tool calls have P50 latency of approximately 50-100ms for pure-computation tools with no I/O. This is consistent with the numbers I measured in my performance benchmarks article. The additional latency for I/O-bound tools depends entirely on your I/O operations.
Input/Output Schema Derivation: The Pydantic Connection
FastMCP uses Pydantic to derive JSON Schema from Python type hints. For a function with type annotations, FastMCP generates an input schema automatically.
The return annotation is stored separately and used to validate output. This means if your function returns the wrong type, you get a validation error at response time, not at call time. For production tools, this catching-at-the-boundary behavior matters.
Pydantic version note: I tested with Pydantic v2. Pydantic v1 has different validation behavior, particularly around type coercion. If you see unexpected validation errors, check your Pydantic version.
Stdio Transport Internals: Why Your Tool Might Hang
When FastMCP runs on stdio (the default, used by Claude Desktop), it spawns a child process. The parent (MCP host) and child communicate over stdin/stdout.
If your tool hangs, the entire connection hangs—there is no async cancellation built into the stdio transport by default. For I/O-bound tools, implement your own timeout or ensure your dependencies handle timeouts gracefully.
My observation: First-call latency over stdio adds 80-150ms for process spawn. This is a one-time cost per session, not per call. For long sessions with multiple tool calls, the overhead amortizes. This is consistent with the stdio performance numbers I documented in my MCP performance benchmarks article.
What FastMCP Does Not Do For You
Understanding the internals reveals real limitations:
Comparison with Official Documentation
The official FastMCP documentation focuses on the "minimal boilerplate" experience. This article provides the internal perspective that the documentation omits. If you encounter issues, understanding the ToolNode registration, Pydantic validation boundary, and stdio transport limitations will help you debug faster.
Where my explanation extends official docs:
Where official docs are more accurate:
When to Reach for FastMCP vs the Raw SDK
FastMCP is ideal for: simple servers with synchronous tools, rapid prototyping, when you want Pydantic validation without writing schemas yourself.
The raw @modelcontextprotocol/sdk is better when you need: HTTP/SSE transport, fine-grained protocol control, custom middleware.
The FastMCP source code at anthropics/fastmcp is approximately 800 lines. Reading it is the fastest way to understand what FastMCP does and does not do for you. Pay particular attention to how the ToolNode registry works and how the stdio transport loops.
Related Tools
Lee Li
Independent Developer · MCP Enthusiast
Building and breaking things with AI tools since 2023. MCP Find started as a personal project to track the rapidly evolving MCP ecosystem. Based in Hong Kong.