LEETLABS
§ 00 / FIELD NOTE
BY Said Betmurzaev · Founder, Leetlabs

How to build an MCP server: a practical guide

The Model Context Protocol is the standard way to expose your systems (your data, your tools, your actions) to an AI model so it can use them. Anthropic introduced MCP in November 2024 as an open protocol, and it caught on fast: OpenAI adopted it across its Agents SDK and ChatGPT desktop app in March 2025, and Google followed. If you want a model to do something in your system rather than just talk about it, an MCP server is how you hand it that capability in a way every major client already understands.

This guide walks the actual build. It’s a how-to, not a pitch.

The mental model

An MCP server is a small program that speaks a defined protocol over JSON-RPC 2.0 and offers the model three kinds of things:

  • Tools are actions the model can take: functions it can call with arguments, like “create an invoice” or “search the codebase.” This is the primitive you’ll use most.
  • Resources are data the model can read: files, records, documents. Think of them as content the client can pull in as context.
  • Prompts are reusable templates a user can invoke, a way to package a known-good instruction.

A host (Claude Desktop, an IDE, your own app) runs a client that connects to your server. Your server’s job is narrow and worth stating plainly: describe what it offers, and execute requests when they come in.

The build, step by step

1. Pick an SDK and a transport. Official SDKs exist for TypeScript, Python, and several other languages, so you rarely implement the wire protocol by hand. Then choose a transport. Stdio is the standard-input/output channel used when the server runs locally as a subprocess of the client, which is the simplest place to start. Streamable HTTP is what you use when the server runs as a remote service that clients connect to over the network.

2. Define your tools precisely. This is the step that determines whether the server is useful, and it’s where most of the real work lives. Each tool needs a clear name, a description written for the model to read, and a typed schema for its inputs. The model decides whether and how to call a tool almost entirely from these descriptions, so vague ones produce wrong calls. Be specific about what the tool does, what each argument means, and what it returns.

3. Implement the handlers. Behind each tool is ordinary code: hit your database, call your API, run your logic. Return results in a structured, predictable shape, and return real errors when things fail, because the model uses those errors to decide what to do next. A tool that fails silently is worse than one that doesn’t exist.

4. Register and test. Point a client at your server, confirm it can list your tools and call them, and watch what the model does with them. You’ll almost always learn that a description needs sharpening or an error message needs to say more.

Vibehub as a worked example

We build MCP servers in production, so this isn’t theory. Our platform, Vibehub, orchestrates AI agents, and much of what those agents can do is delivered through MCP servers that expose real systems as tools the agents call. Building them taught us the parts the protocol docs don’t stress.

The hard part is never the protocol. It’s the surface you design on top of it. A few patterns that have held up:

Scope tools to intentions, not to your API. Don’t mechanically wrap every REST endpoint as a tool. That floods the model with low-level operations it has to chain correctly. Design tools around what someone actually wants to accomplish, and let the tool handle the multi-step plumbing internally.

Guard every action. A tool that can change data or spend money needs validation and limits inside the tool, not trust in the model to behave. Treat tool inputs the way you’d treat any untrusted input, because effectively they are.

Return errors the model can act on. “Invalid request” is useless to a model. “Field ‘amount’ must be a positive number, received -5” lets it correct itself and try again. Good error text is the cheapest reliability upgrade you can make.

Keep descriptions honest and current. The model believes your tool descriptions. If a description overpromises, the model calls the tool in situations it can’t handle, and the failure looks like a model problem when it’s a documentation problem.

Where to go from here

If you’re building for yourself, start with one tool over stdio, get a client calling it cleanly, and grow from there. The protocol is the easy 20 percent. Designing a tool surface a model uses correctly is the other 80, and it’s mostly good API design with a new audience.

If this is business-critical (you want your systems exposed to agents reliably and safely, not as a weekend experiment) that’s what our MCP development work is for. Either way, the advice is the same: the server is simple, the tools are the product, and the tools are where you should spend your time.