Skip to main content

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

/mcp MUST be protected in production — pass dependencies=[...] to require auth, or allow_unauthenticated=True to 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 /mcp route, 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)

Source distribution for hawkapi-mcp 0.3.0
File Size Uploaded
hawkapi_mcp-0.3.0.tar.gz 28.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for hawkapi-mcp 0.3.0
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page