FastAPI Integration¶
Use mesh dependency injection in FastAPI backends with @mesh.route
Note: This page covers Python/FastAPI integration. For Java/Spring Boot, see @MeshRoute. For TypeScript/Express, see mesh.route() middleware.
Overview¶
MCP Mesh provides the @mesh.route decorator for FastAPI applications that need to consume mesh capabilities without being MCP agents themselves. This enables traditional REST APIs to leverage the mesh service layer.
Important: This page is for adding mesh capabilities to an existing FastAPI app. If you're starting fresh, use meshctl scaffold to create a standard MCP agent instead.
TypeScript/Express: A similar
mesh.route()middleware exists for Express applications. Seemeshctl man expressfor details.
Installation¶
Two Architectures¶
| Pattern | Decorator | Use Case |
|---|---|---|
| MCP Agent | @mesh.tool + @mesh.agent | Service that provides capabilities |
| FastAPI Backend | @mesh.route | REST API that consumes capabilities |
@mesh.route Decorator¶
from fastapi import APIRouter, Request
import mesh
from mesh.types import McpMeshTool
router = APIRouter()
@router.post("/chat")
@mesh.route(dependencies=["avatar_chat"])
async def chat(
request: Request,
message: str,
avatar_agent: McpMeshTool = None, # Injected by mesh
):
result = await avatar_agent(
message=message,
user_email="user@example.com",
)
return {"response": result.get("message")}
Dependency Declaration¶
Simple (by capability name)¶
@mesh.route(dependencies=["user_service", "notification_service"])
async def handler(
user_svc: McpMeshTool = None,
notif_svc: McpMeshTool = None,
):
...
With Tag Filtering¶
@mesh.route(dependencies=[
{"capability": "llm", "tags": ["+claude"]},
{"capability": "storage", "tags": ["-deprecated"]},
])
async def handler(
llm_agent: McpMeshTool = None,
storage_agent: McpMeshTool = None,
):
...
Complete Example¶
from fastapi import FastAPI, APIRouter, Request, HTTPException
import mesh
from mesh.types import McpMeshTool
from pydantic import BaseModel
app = FastAPI(title="My Backend")
router = APIRouter(prefix="/api", tags=["api"])
class ChatRequest(BaseModel):
message: str
avatar_id: str = "default"
class ChatResponse(BaseModel):
response: str
avatar_id: str
@router.post("/chat", response_model=ChatResponse)
@mesh.route(dependencies=["avatar_chat"])
async def chat_endpoint(
request: Request,
chat_req: ChatRequest,
avatar_agent: McpMeshTool = None,
):
"""Chat endpoint that delegates to mesh avatar agent."""
if avatar_agent is None:
raise HTTPException(503, "Avatar service unavailable")
result = await avatar_agent(
message=chat_req.message,
avatar_id=chat_req.avatar_id,
user_email="user@example.com",
)
return ChatResponse(
response=result.get("message", ""),
avatar_id=chat_req.avatar_id,
)
@router.get("/history")
@mesh.route(dependencies=["conversation_history_get"])
async def get_history(
request: Request,
avatar_id: str = "default",
limit: int = 50,
history_agent: McpMeshTool = None,
):
"""Get conversation history from mesh agent."""
result = await history_agent(
avatar_id=avatar_id,
limit=limit,
)
return {"messages": result.get("messages", [])}
app.include_router(router)
Running Your FastAPI App¶
Run your existing FastAPI application as you normally would:
Note: Unlike MCP agents, FastAPI backends are NOT started with meshctl start.
The backend will:
- Connect to the mesh registry on startup
- Resolve dependencies declared in
@mesh.route - Inject
McpMeshToolproxies into route handlers - Re-resolve on topology changes (auto-rewiring)
Key Differences from @mesh.tool¶
| Aspect | @mesh.tool | @mesh.route |
|---|---|---|
| Registers with mesh | Yes | Yes (as Type API) |
| Provides capabilities | Yes | No |
| Consumes capabilities | Yes | Yes |
| Has heartbeat | Yes | Yes (for dependency resolution) |
| Protocol | MCP JSON-RPC | REST/HTTP |
| Use case | Microservice | API Gateway/Backend |
When to Use @mesh.route¶
- Building a REST API that fronts mesh services
- API gateway pattern
- Backend-for-Frontend (BFF) services
- Adding REST endpoints to existing FastAPI apps
- When you need traditional HTTP semantics (REST, OpenAPI docs)
When to Use @mesh.tool Instead¶
- Building reusable mesh capabilities
- Service-to-service communication
- LLM tool providers
- When other agents need to discover and call your service
See Also¶
meshctl man express- TypeScript/Express equivalentmeshctl man decorators- All mesh decoratorsmeshctl man dependency-injection- How DI worksmeshctl man proxies- Proxy configuration