Async MCP Tools in Python
If a tool waits on HTTP, databases, queues, or storage, make it async and use async-compatible libraries.
@mcp.tool()
async def search_docs(query: str) -> list[dict]:
"""Search the documentation service."""
response = await http_client.get("/search", params={"q": query})
response.raise_for_status()
return response.json()["results"]Reuse clients
Do not create a new connection pool or HTTP client for every call. Initialize shared dependencies during server/application lifespan.
Bound concurrency
If a tool fans out to many services, use semaphores or bounded task groups. Unbounded concurrency can overwhelm downstream systems.
Cancellation
Where libraries support it, propagate request cancellation into in-flight work so abandoned agent calls stop consuming resources.