Metadata-Version: 2.4
Name: keel-mcp-ingress
Version: 0.1.1
Summary: Thin MCP stdio protocol ingress into Keel managed MCP execution
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: mcp<2,>=1.30
Requires-Dist: httpx<1,>=0.27

# Keel MCP ingress

`keel-mcp-ingress` exposes operator-enrolled, schema-verified managed MCP tools
over standard MCP stdio. It delegates every call to the Keel managed-MCP API.
Listing a tool grants no authority.

## Prerequisites

Use a Keel project with the required plan, active policies, and upstream MCP
servers enrolled by the Keel operator. Server registration and discovery alone
do not confer trust. Custom/unmapped servers are not exposed by this initial
catalog. Initial catalog reads are bounded to 100 enabled servers and 1000
accepted tool contracts per project; larger catalogs return a clear refusal
rather than silently dropping tools. Use managed MCP directly for larger catalogs.
Starter cannot positively authorize arbitrary non-payment MCP calls. With no
enrolled, verified servers, `tools/list` returns an empty catalog.

Obtain a live agent-bound Client key: an owner creates an Admin key; the Admin
creates an AgentPrincipal (`POST /v1/principals`) and a Client key bound to its
`agent_principal_id` (`POST /v1/api-keys`). Keep the Admin/owner and upstream
credentials outside the agent. An ordinary project Runtime/service key has no
agent binding and cannot use this execution path. Upstream secrets stay in Keel.
Because the requester is the agent, the project owner can approve its REVIEW
requests; a request sent with a key the owner holds cannot be self-approved.

## Installation

Requires Python 3.11 or newer.

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

Configure any MCP stdio client (including Claude-compatible clients):

```json
{
  "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"
      }
    }
  }
}
```

HTTPS is required; HTTP is accepted only for an isolated loopback runtime.
Project identity is checked against the key. The ingress supplies required
per-request freshness headers without exemptions. If the key is missing,
revoked, expired, or not bound to a live agent, the ingress exits non-zero with
"Keel MCP ingress could not authenticate or reach the configured Keel API".

## Calls and outcomes

Use `tools/list`. Tool names are stable opaque aliases; descriptions identify the
upstream server/tool. Supply the original upstream `arguments` under the
`arguments` field and a caller-generated `idempotency_key`. Keep that key and the
exact arguments for the whole intended request. Nested argument content is
forwarded unchanged. Expired, drifted or disabled contracts disappear from the
catalog; existing API admission remains the final authority.

`tools/call` returns the existing API response under `response`, plus
`keel_http_status`, `idempotency_key`, and, when Keel names it, the
`permit_id` used to find the call's signed evidence. It marks refusals/failures as MCP
`isError`. ALLOW dispatches only through existing admission. DENY, unapproved
REVIEW and THROTTLE cause zero managed dispatch. For REVIEW, the owner approves
the returned Permit through the dashboard; retry the exact arguments and key.
Approval itself never dispatches. Changed arguments and authority cannot reuse
approval. A new key requests new authority; it does not reuse an approval.

For an unknown outcome or lost Keel response, reconcile using the original key
and downstream records. Do not generate a new key to retry a possibly completed
effect. The gateway does not retry automatically. Invalid input is refused.

Permit, dispatch, receipt and closure evidence use existing Keel export and
proof-pack APIs and the verifier. A successful MCP result is not itself signed
proof of an external state change. Distinguish authorization, Keel dispatch,
provider receipt, provider execution and independently observed external state.
Checkpoint publication remains PAUSED; this ingress does not resume it.

This initial ingress supports initialization, tool listing/calling and stdio
session cleanup. It does not add a policy engine, approval path, provider
credential delegation, remote OAuth service or unrelated MCP features. A model
Permit still does not authorize host-executed tools outside this managed boundary.
