AI assistants are great at reasoning over what you give them, but out of the box they can't see your database, your files, or your internal APIs. For a long time, every tool integration was custom glue code written for one model and one app. The Model Context Protocol (MCP) fixes that with one open standard: build a tool once as an MCP server, and any MCP-compatible client can use it.
This guide explains what MCP is, why it matters, and how to build and connect your first server. As in my previous article, we'll go in small steps and verify each one before moving on.
What is MCP?
MCP is an open protocol, introduced by Anthropic, that defines how an AI application (the client) talks to an external program (the server) that exposes capabilities. A server can offer three kinds of things:
- Tools: functions the model can call, like "search orders" or "create ticket".
- Resources: read-only data the model can load, like files or database records.
- Prompts: reusable prompt templates.
Client and server exchange JSON-RPC messages, either over stdio (the client launches the server as a local process) or over HTTP for remote servers.
Here is what a single tool call looks like end to end:
Why it matters for AI tooling
- Build once, use everywhere. The same server works in any client that speaks MCP.
- Clear boundaries. The model only sees what your server exposes, and you control the code that touches real systems.
- Composable. A client can connect to several servers at once: one for GitHub, one for your database, one for internal docs.
- Less glue code. You write plain functions; the SDK handles the protocol.
Step 1: Decide what your server exposes
Before writing code, write down, in a short list:
- The 1 to 3 tools you need, with inputs and outputs.
- What data the tools may read or change, and what they must never do.
- 2 or 3 real requests a user might make, and the result you expect. These are your acceptance tests.
For this guide we'll build a tiny server with two tools: add (adds two numbers) and get_weather_note (returns a canned note for a city). Simple on purpose, so we can focus on the protocol.
Step 2: Set up the project
We'll use the official Python SDK.
mkdir my-first-mcp && cd my-first-mcp python -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate pip install "mcp[cli]" Verify the install before going further:
python -c "import mcp; print('ok')" Step 3: Write the server, one tool at a time
Create server.py with just one tool first:
from mcp.server.fastmcp import FastMCP mcp = FastMCP("my-first-mcp") @mcp.tool() def add(a: int, b: int) -> int: """Add two numbers and return the sum.""" return a + b if __name__ == "__main__": mcp.run() # uses stdio by default The function's type hints and docstring become the tool's schema and description, which is what the model reads to decide when to call it. Write the docstring for the model, clearly.
Step 4: Test it before connecting any AI
The SDK ships with a development inspector:
mcp dev server.py This opens the MCP Inspector, where you can list the tools and call add with test inputs. Only move on when add(2, 3) returns 5.
Now add the second tool:
@mcp.tool() def get_weather_note(city: str) -> str: """Return a short demo weather note for a city.""" return f"Demo note: it's a nice day in {city}." Run the inspector again and test it. One tool, one test, every time.
Step 5: Connect it to an AI client
Claude Desktop. Add your server to Claude Desktop's config file (claude_desktop_config.json):
{ "mcpServers": { "my-first-mcp": { "command": "/full/path/to/my-first-mcp/.venv/bin/python", "args": ["/full/path/to/my-first-mcp/server.py"] } } } Restart Claude Desktop, and the tools appear. Ask "What is 17 plus 25? Use the add tool." and check that it calls your server.
Grok and other clients. Any assistant or agent framework that supports MCP connects the same way: either it launches your server locally over stdio, or you deploy the server over HTTP and give the client its URL. Check your client's documentation for how it registers MCP servers; the server code doesn't change.
Step 6: Loop until your acceptance tests pass
Go back to the requests you wrote in Step 1. Run each one through the client. If the model picks the wrong tool or passes bad arguments, the fix is usually a clearer docstring or tighter parameter types. Adjust, retest, repeat.
Tips before going to production
- Least privilege. Give the server only the permissions it needs; prefer read-only tools until you trust the flow.
- Validate inputs. Treat everything the model sends as untrusted user input.
- Log every call. You'll want to see what the model asked for and what your server did.
- Keep secrets out of tool output. Anything a tool returns goes into the model's context.
The key principle
Same as with any AI-assisted build: don't try to build the whole thing at once. Define a small set of tools, add them one at a time, test each in the inspector, then connect a client and verify with real requests.
MCP turns "integrate this model with our system" into "write a few well-described functions." Start with one tool, get it working end to end, and grow from there.
About the author
I write about Applied AI, MCP, Azure AI Search, and RAG. Follow me on Dev.to and Hashnode for more.



