HOW-TO · RAG
How to Set Up MCP Server with Standard Tools
Target environment
Ubuntu 24.04 · Ollama 0.4.x
PREREQUISITES
Python 3.10+, MCP SDK installed
What this does
The Model Context Protocol (MCP) standardizes how LLMs interact with external tools and data sources. An MCP server exposes tools that any MCP-compatible client can discover and call.
Steps
- Install the MCP SDK.
pip install mcp
- Create an MCP server with basic tools. Use the
Serverclass and@server.tool()decorator.
from mcp.server import Server, stdio_server
from mcp.types import Tool, TextContent
server = Server("basic-tools")
@server.tool("greet")
async def greet(name: str) -> str:
"""Greet a person by name."""
return f"Hello, {name}!"
@server.tool("add")
async def add(a: float, b: float) -> float:
"""Add two numbers."""
return a + b
@server.tool("current_time")
async def current_time(timezone: str = "UTC") -> str:
"""Get the current time for a timezone."""
from datetime import datetime, timezone as tz
import pytz
tz_obj = pytz.timezone(timezone)
return datetime.now(tz_obj).isoformat()
- Run the server over stdio. This is the standard transport for local MCP clients.
async def main():
async with stdio_server() as (read, write):
await server.run(read, write)
if __name__ == "__main__":
import asyncio
asyncio.run(main())
- List available tools. Any client can call
list_toolsto discover capabilities.
# Client-side
from mcp.client import stdio_client
from mcp.client.stdio import stdio_client
async def list_tools():
async with stdio_client(server_params) as (read, write):
client = Client(read, write)
tools = await client.list_tools()
for t in tools:
print(f" {t.name}: {t.description}")
- Call a tool from the client.
async def call_greet():
async with stdio_client(server_params) as (read, write):
client = Client(read, write)
result = await client.call_tool("greet", {"name": "World"})
print(result.content[0].text)
Verification
python -c "
from mcp.server import Server
s = Server('test')
print(s.name)
# Expected: test
"
Common failures
- Tool function not registered. The
@server.tool()decorator must wrap anasyncfunction. Synchronous functions silently fail to register. - Transport mismatch. Client and server must use the same transport (stdio, SSE, etc.). Mixing them causes connection errors.
- Missing
pytzfor timezone tools. Thecurrent_timetool depends onpytz. Install withpip install pytzor usezoneinfo. - Version mismatch - The installed package or runtime differs from the command shown; check the version first and rerun the smallest verification command.
- Local environment drift - Another service, virtual environment, model, or path is being used; print the active binary path and configuration before changing the guide steps.
Related guides
- How to Create Custom MCP Tools for Your Application
- How to Connect MCP Client to Remote MCP Server