If you want your AI agent to do more than talk — send emails, query databases, manage files, call APIs — it needs tools. The Model Context Protocol (MCP) is how modern AI agents connect to those tools, and building an MCP server is how you expose your own services to any agent that speaks the protocol. This guide walks you through building one from scratch.
MCP is a standard for connecting AI models to external tools and data sources. Think of it as a contract: the agent asks "what tools do you have?" and your server responds with a list of callable functions, each with a name, description, and parameter schema. The agent picks a tool, sends the parameters, your server executes the work, and returns the result. That's it. No magic — just a well-defined JSON-RPC interface over stdio or HTTP. For the broader concept, see MCP explained.
Using the fastmcp library, a working MCP server that exposes a single tool looks like this:
Install: pip install fastmcp
Create server.py with a function decorated @mcp.tool(). The function's docstring becomes the tool description. Type hints become the parameter schema. Return value becomes the tool result. Run with python server.py or register it in your agent's MCP config.
The key insight: the AI reads your tool's description and parameter schema to decide when and how to call it. Write the description like you're explaining the tool to a smart colleague — what it does, when to use it, what the parameters mean. The better the description, the more reliably the agent uses it correctly.
If your agent framework already has a function-calling mechanism and your tools are one-off scripts, you might not need MCP. MCP shines when you want portability — the same tool server works with Claude Desktop, QADIR OS, Cursor, or any MCP-compatible client without rewriting the integration. It also shines when you want to share tools across agents: build the server once, connect it to multiple agents. See MCP vs function calling for the technical tradeoffs.
Database query tool: Expose a query_database tool that takes a SQL string (read-only), runs it against your Postgres/SQLite/D1, and returns the results as JSON. Your agent can now answer questions about your data without you writing dashboards.
File operations: Expose read_file, write_file, list_directory. Your agent can now manage files on disk — organize downloads, clean up directories, process documents.
API wrapper: Expose your SaaS API's endpoints as MCP tools. Your agent calls create_invoice with the customer name and amount instead of you clicking through a UI. This is how QADIR OS connects to 100+ services — each connection is an MCP server that wraps the service's API.
Hardware bridge: Expose take_screenshot, click, type_text. Your agent can now operate your desktop. This is the pattern behind computer-use agents.
Most MCP servers fail not because the code is wrong, but because the tool descriptions are poor. The AI model is reading your description to decide: (a) is this the right tool for the user's request, and (b) what parameters to pass. If your description says "does stuff with files" the model will guess wrong half the time. If it says "Reads the contents of a file at the given absolute path. Returns the file text. Use when the user asks to see, check, or read a specific file" the model nails it every time.
Spend 80% of your effort on descriptions and parameter docs. The code itself is usually trivial — it's a wrapper around something that already works.
An MCP server runs with whatever permissions your process has. If it can delete files, and you expose a delete_file tool, the AI can delete files. This is powerful and dangerous. Best practices: run read-only tools by default, require explicit confirmation for destructive operations, sandbox file access to specific directories, and log every tool call. QADIR OS enforces this through a permission gate (Mercury) that checks every tool call against a budget and authorization policy before execution.
The official @modelcontextprotocol/sdk package gives you the same pattern in TypeScript. Define tools as objects with name, description, and an input schema (JSON Schema), plus a handler function. The SDK handles the JSON-RPC transport. TypeScript's type system helps catch schema mismatches at compile time, which matters when you're building tools that handle user data.
QADIR OS ships with 192+ MCP tools pre-wired — ComfyUI for media, Stripe for payments, Google Workspace for productivity, Cloudflare for infrastructure, and dozens more. You can add your own MCP servers to extend it. The architecture is designed so every new tool you build is immediately available to every agent persona in the system.
ABUZ8 builds QADIR OS — 192+ tools already connected. Add your own MCP servers, or use the ones we've built. Try 164+ free AI tools, or join early access — no card required.