How to Build an MCP Server: General Patterns Beyond Search

The general shape of building any MCP server, using search tools as the running example.

The pieces every MCP server has

Regardless of what capability it exposes, an MCP server has the same handful of parts: a server instance that speaks the protocol, one or more declared tools (each with a name, description, and JSON Schema input definition), handler functions that run when a tool is called, and a transport — most commonly stdio for local servers or HTTP/SSE for remote ones. Search happens to be a clean example because the tool count is usually small (often just one or two tools) and the logic is a straightforward wrap-a-REST-API pattern, which is why it's a common first MCP server people build.

Tool descriptions matter more than you'd expect

The natural-language description attached to each tool (and to each parameter) is what the model reads to decide whether and how to call the tool — it's effectively part of the prompt, not just documentation for a human developer. A vague description like "searches the web" gives the model less to work with than "search the web and return ranked results with title, snippet, and URL; use for current events or facts outside your training data." Write tool descriptions the way you'd write a hint to a competent but context-free colleague.

Resources and prompts, briefly

MCP also defines "resources" (readable data the client can attach to context, like a document or a database record) and "prompts" (reusable prompt templates a server can expose), separate from tools. Most search MCP servers stick to tools alone, since a live search result is naturally a tool-call response rather than a static resource, but it's worth knowing the other primitives exist if you're designing a server that also exposes, say, cached or saved search results as browsable resources.

Testing before shipping

Before wiring a new server into a real agent, test it with a minimal MCP client or inspector tool that lets you call each declared tool directly and inspect the raw response — catching a malformed schema or an unhandled error path this way is much faster than debugging it through a full agent conversation. See building a search MCP server with SerpStack as the backend for a concrete, worked example of these patterns applied to a search tool specifically.