Building AI Agents from Scratch
Working with Multiple MCP Servers
Let one agent use several MCP servers without hard-coding every integration.
One server is one capability. A useful agent talks to a repo server, a ticket server, and a docs server. You do not merge those codebases. You load each server and namespace the tools.
A small catalog
SERVERS = [
{"id": "hello", "command": ".venv/bin/python", "args": ["hello_server.py"]},
{"id": "http", "command": ".venv/bin/python", "args": ["http_server.py"]},
]
all_tools = []
all_registry = {}
for spec in SERVERS:
try:
tools, registry = asyncio.run(load_mcp_tools(spec["command"], spec["args"]))
except Exception as exc:
print(f"skip {spec['id']}: {exc}")
continue
for advertised, (name, fn) in zip(tools, registry.items()):
public = f"{spec['id']}_{name.removeprefix('mcp_')}"
advertised["function"]["name"] = public
advertised["function"]["description"] = f"[{spec['id']}] " + advertised["function"]["description"]
all_registry[public] = fn
all_tools.append(advertised)Do not hard-code the product
- A JSON or YAML list of servers is the integration surface — not a new Python module per vendor.
- If a server is down at startup, skip it and log. The agent should still run with the others.
- Cap how many tools you advertise (for example 20). Too many names and the model picks at random. See Designing MCP for AI.
Check it
Load two hello-style servers with different names. Ask a question that needs one ping from each. The log should show two prefixed tool names. Unplug one command path; startup should warn and the other server should still work. Next: treat tool output as hostile.