hawkapi-mcp
MCP (Model Context Protocol) server for HawkAPI. Auto-exports every route as an agent tool — any MCP-compatible client can call your API.
Install
pip install hawkapi-mcp
Quickstart
from hawkapi import HawkAPI
from hawkapi.responses import JSONResponse
from hawkapi_mcp import mount_mcp
app = HawkAPI()
@app.get("/users/{user_id:int}")
async def get_user(user_id: int) -> JSONResponse:
return JSONResponse({"id": user_id, "name": "Alice"})
@app.post("/items")
async def create_item(body: dict) -> JSONResponse:
return JSONResponse({"created": body})
mount_mcp(app, allow_unauthenticated=True) # serves POST /mcp — dev only; see Auth
/mcpMUST be protected in production — passdependencies=[...]to require auth, orallow_unauthenticated=Trueto opt out explicitly. See Auth.
Point any MCP-compatible client at http://your-host/mcp. Every HawkAPI route becomes a tool — its operationId is the tool name, the OpenAPI schema becomes the input schema.
Tool naming
| Route definition | Generated tool name |
|---|---|
@app.get("/users/{id}", operation_id="get_user") |
get_user |
@app.get("/users/{id}") (no operation_id) |
get_users_id |
Tool input schema
The decorator combines path / query / header parameters and the JSON request body into a single object schema. Parameter names are namespaced so they cannot collide:
| Source | Schema key |
|---|---|
| Path parameter | path.<name> |
| Query parameter | query.<name> |
| Header parameter | header.<name> |
| JSON body | body |
Cookie parameters are deliberately not exposed as tool inputs — exposing session cookies as data trains agents to handle credentials as ordinary fields. Forward credentials via the request to /mcp instead (see Auth).
tools/call example:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_user",
"arguments": {"path.user_id": "42"}
}
}
The tool result has the response body in content[0].text and the raw HTTP status / headers in structuredContent. isError is true for any 4xx/5xx response.
Credential-bearing response headers are stripped from structuredContent before the agent sees them: set-cookie, authorization, and anything matching x-*-token / x-*-secret. Add more via strip_response_headers={...}.
Filtering tools
mount_mcp(app, include_only={"get_user", "create_item"})
mount_mcp(app, exclude={"internal_admin_route"})
Supported JSON-RPC methods
initialize— handshake. Returns the MCP protocol version, server info, and tool capability.ping— keepalive.tools/list— return the tool catalog.tools/call— invoke a tool. Returns response body + HTTP status.notifications/initialized— accepted, no response.
The endpoint accepts both single JSON-RPC objects and batches.
Auth
The /mcp endpoint exposes every route and MUST be protected. A single MCP
tool call can invoke any route, and the bridge synthesises an inner ASGI request
— so middleware that only guards inner routes can be bypassed. To make this
hard to get wrong, mount_mcp() raises RuntimeError at mount time unless you
either:
- pass
dependencies=[...]to attach auth (e.g.Depends) to the/mcproute, or - explicitly opt out with
allow_unauthenticated=True(local dev, or auth enforced upstream).
from hawkapi import Depends
from hawkapi_mcp import mount_mcp
mount_mcp(app, dependencies=[Depends(verify_token)]) # protected
mount_mcp(app, allow_unauthenticated=True) # explicit opt-out
hawkapi-mcp does not define its own auth layer — wire your HawkAPI dependencies
(HTTPBearer, OAuth2, API key) on the MCP route just like any other path. The
caller's Authorization and Cookie headers on the outer /mcp request are
forwarded into the synthetic inner request, so inner-route Depends(auth) sees
the real credentials (and the real client address is propagated where available).
Header arguments forwarded by the client land in the request before middleware runs.
Tool catalog freshness
The tool catalog is derived from app.openapi() and cached. By default it is
cached for the process lifetime, so routes added/removed/disabled at runtime are
not reflected — call server.invalidate_tools() to force a refresh, or pass
cache_ttl_seconds=... to mount_mcp() (or MCPServer) to auto-refresh after
the given interval:
mount_mcp(app, dependencies=[...], cache_ttl_seconds=60)
Development
git clone https://github.com/Hawk-API/hawkapi-mcp.git
cd hawkapi-mcp
uv sync --extra dev
uv run pytest -q
uv run ruff check . && uv run ruff format --check .
uv run pyright src/
Specification
Implements a subset of the Model Context Protocol sufficient to advertise and invoke tools. Streamable HTTP transport only — stdio is out of scope (deploy your app behind any ASGI server and the agent connects to the /mcp URL).
License
MIT.
Metadata
Release files for hawkapi-mcp 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| hawkapi_mcp-0.3.0.tar.gz | 28.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hawkapi_mcp-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 44.5 kB
Release files / hawkapi_mcp-0.3.0.tar.gz
| Download URL | hawkapi_mcp-0.3.0.tar.gz |
|---|---|
| Size | 28.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fc5906fa90693ced31433d8d2ca778341155b502b2ed4d288a2da020bd19a70a
|
|
BLAKE2b-256 checksum How to use checksums |
cebbc994b402d92a672a9f5d1c488dd92a7f66c2292c3320d0568eb16f6bda29
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 10, 2026.
Transparency logRelease files / hawkapi_mcp-0.3.0-py3-none-any.whl
| Download URL | hawkapi_mcp-0.3.0-py3-none-any.whl |
|---|---|
| Size | 15.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1f7e5139d7a83dba42e60501eeeaae1cf5f7e7d9a98dc28fcf11105157d30397
|
|
BLAKE2b-256 checksum How to use checksums |
91b138e5cf6e096f32e85700fc4f204f662433845c71f0429600dad8035613ba
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 10, 2026.
Transparency log