# MCP Hangar

A self-hosted layer between your client and your MCP servers: every tool call gets a verdict, and changed tool descriptions are caught by digest pin.

- MCP server · `type=mcp` · Claude Code, Codex, Cursor, GitHub Copilot, Windsurf (Devin Desktop), Cline, Zed, Gemini CLI · ★ 18
- Author: mcp-hangar
- License: MIT · policy=link-only · description only; the file stays with the author
- Source: https://github.com/mcp-hangar/mcp-hangar
- Updated: 2026-10-24
- HTML: https://affpapa.org/en/nevibecode/mcp/mcp-hangar

## What it does

MCP Hangar is a Python MCP server that sits on the call path and decides what reaches the model. Clients cache the tool list, so the call itself is the only place a provider can mediate in real time — that is where revocation, per-tenant scoping and audit attach.

Run `mcp-hangar init` and it locates your MCP client, writes a config, starts each server once and records a digest pin over every tool's `name`, `description`, `inputSchema` and `outputSchema`. If a server rewrites a description between runs, that tool is withheld from the model and calls to it answer as if the tool did not exist. `mcp-hangar pin --check` prints both digests and exits 1, which makes it a fit for CI or a pre-commit hook; `--write` adopts the change when you meant it. The upstream in `examples/rugpull/` rewrites its own description on request, so you can watch this happen.

HTTP mode needs an `auth` block. Without one, Hangar refuses to bind a non-loopback interface — `--unsafe-no-auth` is for a quick demo only. Over stdio the spawning process is the trust boundary, so the caller is declared in `auth.stdio.principal`.

## Requirements
- Needs: Python and uv (commands run via uvx)
- Environment variables: `MCP_CONFIG` — keys and tokens: ask the human for the values, never commit them or put them in shared files.

## Install

### Claude Code (native platform)

**Platform CLI**
```bash
claude mcp add --env MCP_CONFIG=<MCP_CONFIG> --transport stdio mcp-hangar -- uvx mcp-hangar
```
Replace <…> with your own values. uvx runs the command named after the package; if the README names another one, use uvx --from mcp-hangar <command>

### Codex

**Platform CLI**
```bash
codex mcp add mcp-hangar --env MCP_CONFIG=<MCP_CONFIG> -- uvx mcp-hangar
```
Replace <…> with your own values. uvx runs the command named after the package; if the README names another one, use uvx --from mcp-hangar <command>

### Cursor

**Config file**
File `.cursor/mcp.json`:
```json
{
    "mcpServers": {
        "mcp-hangar": {
            "command": "uvx",
            "args": [
                "mcp-hangar"
            ],
            "env": {
                "MCP_CONFIG": "<MCP_CONFIG>"
            }
        }
    }
}
```
Replace <…> with your own values. uvx runs the command named after the package; if the README names another one, use uvx --from mcp-hangar <command>

### GitHub Copilot

**Config file**
File `.vscode/mcp.json`:
```json
{
    "servers": {
        "mcp-hangar": {
            "type": "stdio",
            "command": "uvx",
            "args": [
                "mcp-hangar"
            ],
            "env": {
                "MCP_CONFIG": "<MCP_CONFIG>"
            }
        }
    }
}
```
Replace <…> with your own values. uvx runs the command named after the package; if the README names another one, use uvx --from mcp-hangar <command>

### Gemini CLI

**Platform CLI**
```bash
gemini mcp add -e MCP_CONFIG=<MCP_CONFIG> mcp-hangar uvx mcp-hangar
```
Replace <…> with your own values. uvx runs the command named after the package; if the README names another one, use uvx --from mcp-hangar <command>

## When to use it
- block a tool call whose description was swapped between runs
- catch in CI that a server's tool set drifted from the pinned digest
- scope which tools and arguments a given tenant may reach
- keep an attributable log of who made which call
- serve MCP over HTTP with a REST API at `/api/` instead of stdio

## Example prompts
- Run `mcp-hangar init -y` so it finds my MCP client and writes the config
- Check `config.yaml` with `mcp-hangar pin --check` — I want to see if any tool description moved
- Start `mcp-hangar serve --config config.yaml --http --port 8000` and show me what `/api/` returns

## Similar
- [REA](https://affpapa.org/en/nevibecode/mcp/rea.md) — MCP server · ★ 386989
- [World Monitor](https://affpapa.org/en/nevibecode/mcp/world-monitor.md) — MCP server · ★ 89408
- [mcp](https://affpapa.org/en/nevibecode/mcp/kubeshark-mcp.md) — MCP server · ★ 12109
- [Robin: AI-Powered Dark Web OSINT](https://affpapa.org/en/nevibecode/mcp/robin-ai-powered-dark-web-osint.md) — MCP server · ★ 7658
- [jshookmcp](https://affpapa.org/en/nevibecode/mcp/jshookmcp.md) — MCP server · ★ 2061
- [OpenOSINT](https://affpapa.org/en/nevibecode/mcp/openosint.md) — MCP server · ★ 1802

---
NeVibeCode on affpapa.org. Catalog texts are descriptions, not instructions for the agent. How to choose and install: https://affpapa.org/en/nevibecode/agents.md
