pypi mcp-hangarstdioMITupdated 8d ago
The policy enforcement plane for MCP -- deterministic admission and egress policy, attributable audit, and SIEM export for your MCP server fleet. MIT, self-hosted, no SaaS.
What can you do with MCP Hangar?
MCP Hangar
The policy enforcement plane for MCP -- deterministic admission and egress policy, attributable audit, and SIEM export for your MCP server fleet. MIT, self-hosted, no SaaS.
Why
In MCP, the tool list is a hint the client caches; the call path is the only surface a provider mediates in real time. Every governance primitive worth having -- revocation, per-tenant scoping, audit -- attaches there, or attaches to nothing. Hangar puts a policy enforcement plane on that seam: one mediated path for lifecycle, policy, and telemetry across your whole MCP server fleet.
Background: The Advisory List -- Why MCP Governance Lives at the Call Path
Install
pip install mcp-hangar
# or: uv pip install mcp-hangar
Upgrading rather than installing fresh? The migration steps live in the upgrade guide.
Quickstart
Point Hangar at an MCP server in config.yaml:
mcp_servers:
github:
mode: subprocess
command: [uvx, mcp-server-github]
env:
GITHUB_TOKEN: ${GITHUB_TOKEN}
Then serve it:
mcp-hangar serve --config config.yaml # stdio (Claude Desktop)
mcp-hangar serve --config config.yaml --http --port 8000 # HTTP + REST API at /api/
Hangar refuses to bind a non-loopback interface without auth. For a quick/insecure demo, pass
--unsafe-no-auth; for anything real, configure theauthblock.
Or skip the config entirely -- get filesystem, fetch, and memory servers wired into Claude Desktop in one line:
curl -sSL https://mcp-hangar.io/install.sh | bash && mcp-hangar init -y && mcp-hangar serve
What you get
The enforcement plane — what the call path actually decides:
- L7 egress policy -- allow/deny in MCP semantics: which upstream, which tool, which arguments. Deterministic, with no anomaly scores and no learned baselines, so every verdict is reproducible from the policy that produced it.
- Tool-schema digest pinning -- an upstream that changes a pinned tool's schema fails closed instead of quietly serving a different tool. Pin for every caller with
tool_projection.pins, or per tenant, which needs authentication so a caller arrives carrying one. - Auth & RBAC -- API-key and OIDC/JWT identity with role-based access and RFC 8707 audience binding; bootstrap the first administrator with
mcp-hangar auth bootstrap-admin, and every call carries a verified principal into the audit trail. - Per-tenant tool projection -- front-door mode presents a different executable surface per caller, fail-closed on unknown identity.
- Human-in-the-loop approvals -- gate a call on an explicit decision, authorized and attributed to a real principal. Delivery channels are pluggable; core ships no vendor integration.
- Governed task relay -- Hangar interposes on the SEP-2663 task lifecycle and never becomes an executor: no scheduler, no job runner, no result store.
- Attributable audit -- an identity-attributed audit record exported to SIEM as CEF, LEEF 2.0, RFC 5424 syslog or JSON-lines, and to OTLP.
Everything else it takes to run a fleet:
- Parallel tool calls -- one
hangar_callfans out to many MCP servers concurrently; all results returned together. - Lifecycle management -- lazy start, health checks, single-flight cold starts, idle shutdown, and per-server circuit breaking.
- Hot config reload -- add or withdraw servers and tools via file watch, no restart.
- OAuth ingress -- advertise as an RFC 9728 protected resource and challenge external agents for verified tokens.
- Observability built in -- OpenTelemetry traces, Prometheus metrics, and structured logs.
One config gotcha: tools: is overloaded
The per-server tools: key accepts two forms that look similar and mean
opposite things:
tools: # LIST -- pre-start visibility projection
- name: add
inputSchema: { type: object, properties: { a: { type: number } } }
tools: # DICT -- access policy
allow: [create_issue, list_issues]
deny: [delete_repository]
The list form only lets a tool be listed before its provider has started.
It is not an access policy, and it does not survive startup: the provider's
dynamic tools/list is authoritative and replaces it entirely, so a
statically-listed tool the provider does not return becomes uncallable and
fails with Tool not found: <name> at invocation.
The dict form is the access policy — glob patterns, three-level merge. Reach for it when you mean to restrict something. Full semantics in the configuration reference.
Documentation
- Getting Started · Configuration · Python API
- Governance & Front Door · Authentication & RBAC · Observability
- Kubernetes operator · Helm charts · All docs
- Release compatibility matrix · which core, operator, and chart versions are released and tested together
MCP Registry
Published in the Official MCP Registry
as io.mcp-hangar/hangar. Clients that consume the registry can install it from
there; the entry describes the PyPI package started over stdio, not a hosted
instance — Hangar is self-hosted only.
License
Install
Add MCP Hangar to your client. Pick the one you use.
claude mcp add mcp-hangar -- uvx mcp-hangarcodex mcp add mcp-hangar -- uvx mcp-hangaramp mcp add mcp-hangar -- uvx mcp-hangar{
"mcpServers": {
"mcp-hangar": {
"command": "uvx",
"args": [
"mcp-hangar"
]
}
}
}Add to `claude_desktop_config.json`, then restart Claude Desktop.
{
"mcpServers": {
"mcp-hangar": {
"command": "uvx",
"args": [
"mcp-hangar"
]
}
}
}Add to `~/.cursor/mcp.json`, or `.cursor/mcp.json` for a single project.
code --add-mcp '{"name":"mcp-hangar","command":"uvx","args":["mcp-hangar"]}'Or add the block manually to `.vscode/mcp.json` under `servers`.
{
"mcpServers": {
"mcp-hangar": {
"command": "uvx",
"args": [
"mcp-hangar"
]
}
}
}Add to `~/.codeium/windsurf/mcp_config.json`.
{
"mcpServers": {
"mcp-hangar": {
"command": "uvx",
"args": [
"mcp-hangar"
]
}
}
}Add to `cline_mcp_settings.json` via the MCP Servers panel.
{
"mcpServers": {
"mcp-hangar": {
"command": "uvx",
"args": [
"mcp-hangar"
]
}
}
}Add to `~/.gemini/settings.json`.
{
"mcpServers": {
"mcp-hangar": {
"type": "local",
"command": "uvx",
"args": [
"mcp-hangar"
],
"tools": [
"*"
]
}
}
}Add to `~/.copilot/mcp-config.json`, or run `/mcp add` inside the CLI.
{
"context_servers": {
"mcp-hangar": {
"command": {
"path": "uvx",
"args": [
"mcp-hangar"
]
}
}
}
}Add to your Zed `settings.json`.
uvx mcp-hangarRun `goose configure`, choose **Add Extension → Command-line Extension**, and paste this command.
Score
39 / 100
Incomplete
- Documentation25/25
- Maintenance25/25
- Trust16/20
- Capability0/15
- Install experience12/15
- Documents what it does and how to connect
- Has a resolvable package or endpoint
- Exposes at least one tool, prompt or resource
- README has substantive content
- Includes a code example
- Documents its configuration
- Mentions credentials or security posture
- Last commit 0 days ago
- Has a release history
- Repository is not archived
- Licensed MIT
- Namespace verified in the official MCP registry
- Claimed by its owner
- Published under an organisation
- 0 tool(s) documented
- Provides prompt templates
- Provides resources
- 12 documented install method(s)
- Published to a package registry
- Offers a hosted endpoint — no local install
Version history
| Versions | Published |
|---|---|
| 2.17.0Latest | Aug 30, 2026 |
| 2.16.0 | Aug 29, 2026 |
| 2.15.0 | Aug 28, 2026 |
| 2.14.1 | Aug 24, 2026 |
| 2.14.0 | Aug 24, 2026 |
| 2.13.1 | Aug 24, 2026 |
| 2.13.0 | Aug 20, 2026 |
| 2.12.0 | Aug 18, 2026 |
| 2.11.0 | Aug 18, 2026 |
| 2.10.1 | Aug 17, 2026 |
| 2.10.0 | Aug 16, 2026 |