One decorator. FastAPI REST and MCP for AI agents — simultaneously. No drift. No duplication. One source of truth.
pip install unified-nexus
v0.1.0 · MIT
Traditional stacks force you to define a FastAPI route, then manually re-wrap it as an MCP tool. Over time they drift apart — different validation, different behavior. Unified Nexus ends that permanently.
# Two files. Two definitions. # They will drift. Always. routes/user.py ← HTTP logic mcp_tools/user.py ← MCP copy-paste models/user.py ← maybe shared? # Result: Code Drift. Silent bugs. # API validates X. Tool validates Y.
# One file. One decorator. # Always in sync. Guaranteed. main.py ← REST + MCP @nexus.universal_tool ← both at once ← that's it. # Result: One source of truth. # HTTP and AI share exact same logic.
Install, define a tool, run. Your function is immediately available via both REST and MCP.
# Install via pip pip install unified-nexus # Or clone from GitHub git clone https://github.com/rajboopathiking/UnifiedNexus cd UnifiedNexus pip install -e .
from unified_nexus import UnifiedNexus from pydantic import BaseModel, Field nexus = UnifiedNexus("MyNexusAPI") class UserRequest(BaseModel): user_id: int = Field(..., description="The unique ID of the user") @nexus.universal_tool(path="/user-info") def get_user(req: UserRequest): """ Fetches user status and clearance level. This docstring is used by Swagger AND AI agents! """ return {"id": req.user_id, "status": "Active", "tier": "Gold"} app = nexus.finalize() if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)
# Start the server python main.py # ✅ REST API Docs http://localhost:8000/docs # ✅ MCP Endpoint http://localhost:8000/mcp # ✅ Verify MCP with Inspector npx -y @modelcontextprotocol/inspector http://localhost:8000/mcp
# Async tools work natively @nexus.universal_tool(path="/fetch") async def fetch_data(resource_id: str): """Fetches data asynchronously from external source.""" async with httpx.AsyncClient() as client: res = await client.get(f"https://api.example.com/{resource_id}") return res.json() # Custom path + explicit method @nexus.universal_tool(path="/search", methods=["GET"]) def search(query: str, limit: int = 10): """Search the catalog. Returns ranked results.""" return {"results": [], "total": 0}
A single ASGI process serves both interfaces. FastMCP mounts cleanly inside FastAPI with correctly composed lifespans.
Your MCP endpoint works with every major AI host out of the box — no extra config, no plugins.
{
"mcpServers": {
"my-api": {
"url": "http://localhost:8000/mcp",
"transport": "streamable-http"
}
}
}
# Add to MCP settings: Server URL: http://localhost:8000/mcp Transport: streamable-http # Your tools appear in # the AI sidebar instantly.
# Test & debug all tools: npx -y @modelcontextprotocol/inspector \ http://localhost:8000/mcp # Opens at localhost:6274 # Full tool call UI included.