OpenAPI ⇢ Hyperia Server
Automatically wrap any REST/HTTP service described by an OpenAPI 3.0 / 3.1 spec and expose it as a fully‑featured Hyperia MCP server—no hand‑rolled glue code required.
Added in v2.0 (major revamp v2.2) – point Hyperia at your .json, hand it an
httpx.AsyncClient
, and receive tools/resources/prompts ready for LLMs.
1 Quick Start
import httpx, asyncio
from hyperia import Hyperia
spec = "https://api.example.com/openapi.json" # or dict loaded from file
spec = httpx.get(spec).json()
api = httpx.AsyncClient(base_url="https://api.example.com")
mcp = Hyperia.from_openapi(
openapi_spec = spec,
client = api,
name = "ExampleAPI", # optional, appears in roots
timeout = 8.0, # secs per request
)
if __name__ == "__main__":
mcp.run(transport="streamable-http", port=9000)
Hyperia parses the spec, builds Tools for mutating endpoints, Resources/Templates for GET routes, and wires a response mapper that converts JSON → TextContent
automatically.
2 Mapping Rules
GET
none
Resource
GET /stats
→ resource://stats
GET
present
ResourceTemplate
GET /users/{id}
→ users://{id}
any other (POST
, PUT
, PATCH
, DELETE
, …)
n/a
Tool
POST /login
→ login
This is implemented via a priority‑ordered RouteMap
list.
from hyperia.server.openapi import RouteMap, RouteType
custom = [
# Treat *any* /analytics/* GET as a Tool (force call instead of read)
RouteMap(methods=["GET"], pattern=r"^/analytics/.*", route_type=RouteType.TOOL)
]
mcp = Hyperia.from_openapi(spec, api, route_maps=custom)
all_routes_as_tools=True
is a convenience flag that sets one catch‑all map; use when building agent backends that only need actions.
3 Request Construction
Hyperia uses the path templating, parameter schema, and requestBody definitions from the spec to build the outbound HTTP request.
3.1 Query Params Filtering
None
or empty strings are omitted to avoid?max=&sort=
noise.Boolean false is still sent (
flag=false
).
await cli.call_tool("search", {"q": "gpu", "page": None})
# → GET /search?q=gpu
3.2 Path Params Validation
Required placeholders must be non‑null; else ValueError
.
3.3 Request Bodies
JSON – dict/list sent via
json=
multipart/form‑data – files or nested models (OpenAPI
encoding
) supportedapplication/x‑www‑form‑urlencoded – auto encoded
If the spec marks a request body as optional you may omit it.
4 Response Mapping
Response Content-Type
Mapped MCP Content
application/json
TextContent
with JSON string
text/*
TextContent
image/*
ImageContent
other / binary
BlobResourceContents
Hyperia strips unknown fields and honours schema.examples
when generating the description shown to LLMs.
5 Advanced Options
5.1 Global Timeout
mcp = Hyperia.from_openapi(spec, api, timeout=5)
Applies to every outbound HTTP call; per‑tool override coming in v2.5.
5.2 Auth Injection
Because you provide the httpx.AsyncClient
, you control headers, OAuth middleware, mTLS, or cookies there. Example Bearer token refresher:
class TokenAuth(httpx.Auth):
async def async_auth_flow(self, req):
req.headers["Authorization"] = f"Bearer {await get_token()}"
yield req
api = httpx.AsyncClient(base_url=url, auth=TokenAuth())
mcp = Hyperia.from_openapi(spec, api)
5.3 Server Prefix
Pass route_prefix="/v2"
if your OpenAPI paths are rooted differently than the runtime base URL.
6 Validation & Error Propagation
HTTP 4xx/5xx are translated into MCP errors so the client can handle gracefully. Response body (up to 2 KB) is forwarded in ToolError
unless redact_errors=True
.
7 Complete Walkthrough – PetStore
import httpx, asyncio
from hyperia import Hyperia
from pathlib import Path
spec = Path("petstore.yaml").read_text() # local file ok; yaml or json
spec = yaml.safe_load(spec)
client = httpx.AsyncClient(base_url="https://petstore.example.com/api")
mcp = Hyperia.from_openapi(spec, client, name="PetStore")
async def demo():
tools = await mcp.get_tools()
print("Tools:", list(tools))
# Call generated tool
async with httpx.AsyncClient() as aio_cli:
petstore_cli = Client(mcp)
async with petstore_cli:
res = await petstore_cli.call_tool("createPet", {"name": "Fido", "tag": "dog"})
print(res[0].text)
asyncio.run(demo())
8 Limitations & Roadmap
OAuth 2.1 / OpenID helpers planned → auto‑generate auth flows for client apps.
Async Streaming – OpenAPI
text/event‑stream
responses currently buffered, streaming proxy slated for v2.6.Enum to Literal – generation uses raw enums; future versions will convert to Python
Literal
for tighter schemas.
9 Troubleshooting
ValueError: Missing required path parameters
Called tool without all placeholders
Provide all path args
404 on every request
Wrong base_url
vs path prefix
Use route_prefix
Spec contains $ref
but Hyperia raises KeyError
Circular $ref
or unsupported JSON‑Pointer
Flatten spec or open GitHub issue
Last updated