Skip to Content
IntegrationsMCP Ingress

MCP Ingress

keel-mcp-ingress is a small MCP stdio server. It lists the managed MCP tools your project has enrolled and verified, and sends every tools/call through Keel’s managed MCP execution path. Listing a tool grants no authority; policy admission decides each call.

Before you start

  • A Keel project on a plan that can authorize the tools you need. Starter can only authorize payment tools; other MCP tools need Production.
  • Upstream MCP servers enrolled by the Keel operator and their tool contracts verified. With nothing enrolled, the ingress lists no tools.
  • An agent-bound Client key. An ordinary dashboard Runtime key is not bound to an agent and cannot use this path.

Create an agent-bound key

Use an Admin key from API Keys to register the agent and issue its key. Keep the Admin key out of the agent’s environment.

curl -sS https://api.keelapi.com/v1/principals \ -H "Authorization: Bearer $KEEL_ADMIN_KEY" \ -H "Content-Type: application/json" \ -d '{"principal_type": "agent", "display_name": "Support agent"}' curl -sS https://api.keelapi.com/v1/api-keys \ -H "Authorization: Bearer $KEEL_ADMIN_KEY" \ -H "Content-Type: application/json" \ -d '{"scope": "client", "agent_principal_id": "AGENT_PRINCIPAL_ID", "expires_at": "2026-12-31T00:00:00Z"}'

The second response returns the key once in raw_key. Store it in the MCP client’s secret configuration, not in source control.

Because the agent is the requester, the project owner can approve its REVIEW requests in the dashboard. A request sent with a key the owner holds cannot be approved by that same owner.

Revoking or suspending the agent (POST /v1/principals/{id}/revoke), or decommissioning it in Authority, stops every key issued for it.

Install

Requires Python 3.11 or newer.

python3 -m venv .venv .venv/bin/python -m pip install keel-mcp-ingress==0.1.1

Configure your MCP client

Any MCP stdio client works, including Claude-compatible clients:

{ "mcpServers": { "keel": { "command": "/absolute/path/to/.venv/bin/keel-mcp", "env": { "KEEL_BASE_URL": "https://api.keelapi.com", "KEEL_API_KEY": "YOUR_AGENT_BOUND_CLIENT_KEY", "KEEL_PROJECT_ID": "YOUR_PROJECT_ID" } } } }

If the key is missing, revoked, expired, or not bound to a live agent, keel-mcp exits with “Keel MCP ingress could not authenticate or reach the configured Keel API”.

Calls and outcomes

  • tools/call takes the upstream arguments and a caller-generated idempotency_key. Keep both unchanged for the whole intended request.
  • ALLOW dispatches once through Keel. DENY, an unapproved REVIEW and THROTTLE dispatch nothing.
  • For REVIEW, approve the returned Permit in the dashboard, then retry with the same arguments and key. Approval itself never dispatches.
  • Results include permit_id when Keel names one. Use it to export signed evidence and verify it with keel-verify.

What this does not establish

A successful MCP result is not signed proof of an external state change. Keep authorization, Keel dispatch, provider receipt, provider execution and independently observed external state separate when you read the evidence.

Last updated on Edit this page on GitHub