Skip to content

Commit 79025fc

Browse files
authored
add mcp service example (#12)
* add mcp service example * fix ruff
1 parent c4b3431 commit 79025fc

3 files changed

Lines changed: 65 additions & 0 deletions

File tree

backend/main.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
metrics,
1919
rerank,
2020
tokenization,
21+
mcp,
2122
)
2223

2324
settings = get_settings()
@@ -69,6 +70,7 @@ async def backend_http_error_handler(request: Request, exc: BackendHTTPError):
6970
app.include_router(metrics.router)
7071
app.include_router(rerank.router)
7172
app.include_router(tokenization.router)
73+
app.include_router(mcp.router)
7274

7375
if __name__ == "__main__":
7476
import uvicorn

backend/routers/mcp.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import aiohttp
2+
from fastapi import APIRouter, Request, Depends
3+
from fastapi.responses import Response, JSONResponse
4+
from backend.middleware.auth import require_auth
5+
from backend.services.mcp_service import mcp_proxy, list_mcp_servers
6+
7+
router = APIRouter()
8+
9+
10+
@router.get("/v1/mcp")
11+
async def get_mcp_servers(token: str = Depends(require_auth)):
12+
return {"servers": list_mcp_servers()}
13+
14+
15+
@router.post("/v1/mcp/{owner}/{repo}")
16+
async def mcp_endpoint(
17+
owner: str,
18+
repo: str,
19+
request: Request,
20+
token: str = Depends(require_auth),
21+
):
22+
body = await request.body()
23+
try:
24+
data, status = await mcp_proxy(owner, repo, body)
25+
return Response(
26+
content=data,
27+
status_code=status,
28+
media_type="application/json",
29+
)
30+
except aiohttp.ClientError:
31+
return JSONResponse(
32+
status_code=404,
33+
content={"error": f"MCP server '{owner}/{repo}' not reachable"},
34+
)

backend/services/mcp_service.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import aiohttp
2+
3+
NAMESPACE = "rob-poc"
4+
MCP_PORT = 8080
5+
6+
# Hardcoded MCP server registry: owner/repo -> K8s service DNS
7+
MCP_SERVERS = {
8+
"alan5543/calculator-mcp": f"http://tool-gym-alan5543-calculator-mcp-dev.{NAMESPACE}.svc.cluster.local:{MCP_PORT}",
9+
}
10+
11+
12+
async def mcp_proxy(owner: str, repo: str, body: bytes) -> tuple[bytes, int]:
13+
"""Forward a JSON-RPC request to the MCP server. Returns (body, status)."""
14+
url = MCP_SERVERS.get(f"{owner}/{repo}")
15+
if not url:
16+
return b'{"error":"MCP server not found"}', 404
17+
async with aiohttp.ClientSession() as session:
18+
async with session.post(
19+
url,
20+
data=body,
21+
headers={"Content-Type": "application/json"},
22+
timeout=aiohttp.ClientTimeout(total=30),
23+
) as resp:
24+
data = await resp.read()
25+
return data, resp.status
26+
27+
28+
def list_mcp_servers() -> list[dict]:
29+
return [{"owner": k.split("/")[0], "repo": k.split("/")[1]} for k in MCP_SERVERS]

0 commit comments

Comments
 (0)