ASGI Integration

Embed Hyperia seamlessly inside Starlette, FastAPI, or any ASGI‑compatible stack.

While mcp.run() is perfect for standalone servers, many production apps already use an ASGI framework for routing, auth, and middleware. Hyperia ships first‑class helpers—and an optional FastAPI extension—to slot MCP endpoints into those apps with zero glue code.

New in Hyperia v2.2http_app() returns an ASGI app for Streamable HTTP by default. Legacy sse_app() remains for backward compatibility.


1 · Getting an ASGI App

from hyperia import Hyperia

mcp = Hyperia("MySrv")

@mcp.tool()
def greet(name: str):
    return f"Hello, {name}!"

# Streamable HTTP (recommended)
app = mcp.http_app(path="/mcp")

# Legacy SSE transport (deprecated)
# app = mcp.http_app(transport="sse", path="/sse")

The returned Starlette instance:

  • exposes MCP at /mcp (or custom path).

  • stores the server on app.state.hyperia_server (useful in middleware).

  • includes default CORS, compression, and exception handlers.

Custom Middleware

from starlette.middleware import Middleware
from starlette.middleware.cors import CORSMiddleware

app = mcp.http_app(
    middleware=[Middleware(CORSMiddleware, allow_origins=["*"])],
)

2 · Running with Uvicorn / Hypercorn

uvicorn mymodule:app --host 0.0.0.0 --port 8000

Or in‑code:

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

3 · Mounting in Starlette

from starlette.applications import Starlette
from starlette.routing import Mount

host_app = Starlette(
    routes=[
        Mount("/api", app=app),  # mounts /api/mcp
    ],
    lifespan=app.lifespan,        # important for Streamable HTTP session manager
)

lifespan=app.lifespan passes Hyperia’s startup/shutdown hooks upward so the session manager initialises correctly.

Nested Mounts

Starlette’s router can nest indefinitely:

inner = Starlette(routes=[Mount("/inner", app=app)])
outer = Starlette(routes=[Mount("/outer", app=inner)], lifespan=app.lifespan)

Endpoint → /outer/inner/mcp.


4 · FastAPI Deep Integration

Although you can mount the Starlette app directly, Hyperia provides an opinionated extension hyperia.fastapi for richer features: dependency injection, OpenAPI merger, and automatic security scheme propagation.

Installing

pip install hyperia[fastapi]

Quick Start

from hyperia import Hyperia
from hyperia.fastapi import attach_hyperia
from fastapi import FastAPI, Depends

mcp = Hyperia("Demo")

@mcp.tool()
def add(a: int, b: int): return a + b

app = FastAPI()
# one‑liner attachment; mounts at /mcp and merges OpenAPI
attach_hyperia(app, server=mcp, path="/mcp")

# normal FastAPI route still works
@app.get("/status")
async def status():
    return {"ok": True}

Why use the extension?

  • Adds OpenAPI tags for tools/resources so they show in Swagger UI.

  • Propagates FastAPI auth dependencies to the MCP endpoint automatically (OAuth2, API keys, etc.).

  • Shares the same lifespan context—one startup/shutdown.

  • Provides helper Depends wrappers that let FastAPI routes call MCP tools internally.

The extension is optional; vanilla mounting works fine if you just need routing.


5 · Custom Routes inside Hyperia

For lightweight servers, you can skip an external framework and add routes directly:

from starlette.responses import PlainTextResponse

@mcp.custom_route("/health", methods=["GET"])
async def health(_):
    return PlainTextResponse("OK")

These routes live alongside /mcp and are included when you embed the app elsewhere.


6 · Proxy & Mount Together

You can mount a proxy server into FastAPI too:

backend_proxy = Hyperia.as_proxy("https://crm.example.com/mcp")
api = FastAPI()
attach_hyperia(api, backend_proxy, path="/crm")

Now /crm/mcp forwards to the remote CRM MCP.


7 · Security & Middleware Patterns

  • Auth first – add FastAPI dependencies (JWT, OAuth) to protect the entire Hyperia mount. Example:

    from fastapi.security import HTTPBearer
    token = HTTPBearer()
    api = FastAPI(dependencies=[Depends(token)])
    attach_hyperia(api, mcp)
  • Rate limiting – plug Starlette‑Limiter or custom middleware before Hyperia.

  • CORS – supply CORS middleware list when calling http_app().


8 · Performance Tips

  • Use Uvicorn --workers N or Gunicorn uvicorn.workers.UvicornWorker for multi‑core HTTP throughput.

  • Streamable HTTP is stateless by default—easy to scale behind a load balancer. If you enable stateful mode, ensure sticky sessions.

  • For heavy workloads inside tools/resources, run them async or offload to a task queue (Celery, RQ).


9 · Recap

  1. Grab an ASGI app with mcp.http_app().

  2. Mount it wherever you need—Starlette, FastAPI, or another Hyperia via mount().

  3. Optionally use hyperia.fastapi.attach_hyperia() for automatic OpenAPI and auth integration.

Last updated