Skip to main content

delegus-mcp

Delegus for Python MCP servers. An ASGI middleware checks every MCP tools/call against the calling agent's delegated authority before your tool runs. It works with the official Python MCP SDK's MCPServer over streamable HTTP, with Starlette, and with FastAPI. It follows the same rules as the Node middleware, delegus.mcp() in @delegus/sdk.

pip install delegus-mcp
import os
from mcp.server.mcpserver import MCPServer
from delegus_mcp import DelegusMCPMiddleware

mcp = MCPServer("tickets")

@mcp.tool()
def create_ticket(title: str) -> str:
    return f"created ticket: {title}"

app = DelegusMCPMiddleware(
    mcp.streamable_http_app(),
    api_key=os.environ["DELEGUS_RP_KEY"],
    public_base_url="https://tools.example.com",
)

Run it with any ASGI server, for example uvicorn server:app. public_base_url is the address agents call and sign for; behind a proxy, it's the public one. For FastAPI or Starlette, wrap the app the same way, or use app.add_middleware(DelegusMCPMiddleware, api_key=…, public_base_url=…).

Options:

  • tools: a list or a predicate, to enforce only some tools (others pass unchecked);
  • relying_party: skips a lookup when credentials are missing;
  • on_decision: called with each decision, for logs;
  • max_body_bytes: default 1 MiB; a larger body is refused;
  • api_base_url;
  • timeout_seconds.

What happens to each request

  • tools/call: the agent's Delegus-Grant and Delegus-Proof headers are checked, including that the Proof was signed for this tool at this address.

    • On ALLOW, the tool runs. The receipt is in scope["state"]["delegus"] (in Starlette, request.state.delegus) and the response carries Delegus-Receipt-Id.
    • On DENY, the middleware answers HTTP 403 with JSON-RPC error -32040 and the Delegus reason, and the tool never runs.
  • Anything it can't read is refused:

    • a missing, unparseable or oversized body, or one with duplicate keys (REQUEST_UNREADABLE);
    • a JSON-RPC batch carrying a checked tool call (BATCH_NOT_SUPPORTED);
    • a tool call without a string tool name (TOOL_NAME_INVALID).

    These are the middleware's own refusals and carry no signed receipt.

  • Delegus can't be reached: 403 SERVICE_UNAVAILABLE. It fails closed.

  • Everything that can't run a tool passes through: initialize, tools/list, ping, notifications, JSON-RPC responses, GET (the SSE stream), HEAD, OPTIONS, and a DELETE that ends a session.

  • The app receives exactly the bytes that were checked.

Limits

  • No stdio. It checks HTTP requests, so it covers MCP servers served over HTTP, not stdio-only servers.
  • No argument inspection. Delegus v0.2 binds the tool, not its arguments: a permission can allow create_ticket, not "tickets under a priority". Validate arguments in the tool.
  • Server-to-client messages aren't checked. Requests your server sends to the client on an SSE stream (sampling, elicitation) pass as they are.
  • Only requests that reach this app are checked. If the same tools are exposed some other way, those routes aren't protected.

Tested against

The shared MCP request-shape suite in @delegus/conformance: the same rows the Node middleware and the Delegus MCP gateway run. It asserts that a refused request never reaches the tool, and that a forwarded one arrives byte for byte. End to end, with the official Python MCP SDK (mcp 2.x) and a local Delegus:

  • a delegated call runs with a receipt;
  • after a revoke, the same call is refused with AUTHORITY_REVOKED;
  • a batch is refused.

Python 3.9 or later. Apache-2.0.

Release files for delegus-mcp 0.1.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 delegus-mcp 0.1.0
File Size Uploaded
delegus_mcp-0.1.0.tar.gz 13.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for delegus-mcp 0.1.0
File Interpreter ABI Platform
delegus_mcp-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 26.3 kB

Release files / delegus_mcp-0.1.0.tar.gz

Download URL delegus_mcp-0.1.0.tar.gz
Size 13.9 kB
Tags Source
SHA-256 checksum
How to use checksums
e7bdd8ebfadf22b4902228a5fb914233cf71b3658f6aee2628918966e0264a9d
BLAKE2b-256 checksum
How to use checksums
5dd4409e83c6ad5b98d0ce43323be1d4fbf5a48eb4cf594eb4354af8f36fb2c0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.15

Release files / delegus_mcp-0.1.0-py3-none-any.whl

Download URL delegus_mcp-0.1.0-py3-none-any.whl
Size 12.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
aabbdc530af32afaa8b306266595f52ec948a9ab1629e1207f54cf52bb544db8
BLAKE2b-256 checksum
How to use checksums
e4fc278f69753148b38ab59b845132255b0fcd1777a46f44a7a173a47fa76e05
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.15

Release history Release notifications | RSS feed

This release

0.1.0 This release

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