Metadata-Version: 2.4
Name: mcp-hangar
Version: 1.1.0
Summary: Production-grade infrastructure for Model Context Protocol
Project-URL: Homepage, https://mcp-hangar.io
Project-URL: Documentation, https://mcp-hangar.io/getting-started/quickstart/
Project-URL: Repository, https://github.com/mcp-hangar/mcp-hangar
Author-email: Marcin Pyrka <marcin@mcp-hangar.io>
License: MIT
License-File: LICENSE
Keywords: ai,infrastructure,llm,mcp,model-context-protocol
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: System :: Systems Administration
Requires-Python: >=3.11
Requires-Dist: aiosqlite>=0.19.0
Requires-Dist: cryptography>=41.0.0
Requires-Dist: docker>=7.1.0
Requires-Dist: httpx>=0.25.0
Requires-Dist: mcp>=1.0.0
Requires-Dist: prometheus-client>=0.19.0
Requires-Dist: protobuf>=6.33.5
Requires-Dist: pydantic>=2.0.0
Requires-Dist: pyjwt>=2.8.0
Requires-Dist: python-multipart>=0.0.22
Requires-Dist: pyyaml>=6.0
Requires-Dist: questionary>=2.0.0
Requires-Dist: rich>=13.0.0
Requires-Dist: structlog>=24.0.0
Requires-Dist: typer>=0.12.0
Provides-Extra: dev
Requires-Dist: hypothesis>=6.90.0; extra == 'dev'
Requires-Dist: mypy>=1.8.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest-benchmark>=5.1.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
Requires-Dist: pytest-timeout>=2.2.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.3.0; extra == 'dev'
Provides-Extra: enterprise
Requires-Dist: fpdf2>=2.8.0; extra == 'enterprise'
Provides-Extra: langfuse
Requires-Dist: langfuse>=2.0.0; extra == 'langfuse'
Provides-Extra: opentelemetry
Requires-Dist: opentelemetry-api>=1.22.0; extra == 'opentelemetry'
Requires-Dist: opentelemetry-exporter-otlp>=1.22.0; extra == 'opentelemetry'
Requires-Dist: opentelemetry-sdk>=1.22.0; extra == 'opentelemetry'
Provides-Extra: postgres
Requires-Dist: asyncpg>=0.29.0; extra == 'postgres'
Description-Content-Type: text/markdown

# MCP Hangar

[![PyPI](https://img.shields.io/pypi/v/mcp-hangar)](https://pypi.org/project/mcp-hangar/)
[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

**Production-grade infrastructure for Model Context Protocol.**

MCP Hangar is a control plane for MCP servers. It manages MCP server lifecycle, parallel tool execution, security governance, and observability -- so you don't have to.

## Quick Start

**30 seconds to working MCP servers:**

```bash
curl -sSL https://mcp-hangar.io/install.sh | bash && mcp-hangar init -y && mcp-hangar serve
```

That's it. Filesystem, fetch, and memory MCP servers are now available to Claude.

<details>
<summary>What just happened?</summary>

1. **Install** - Downloaded and installed `mcp-hangar` via pip/uv
2. **Init** - Created `~/.config/mcp-hangar/config.yaml` with starter MCP servers
3. **Serve** - Started the MCP server (stdio mode for Claude Desktop)

The `init -y` flag uses sensible defaults:

- Detects available runtimes (uvx preferred, npx fallback)
- Configures starter bundle: filesystem, fetch, memory
- Runs a smoke test to verify MCP servers start correctly
- Updates Claude Desktop config automatically

</details>

### Manual Setup

```bash
# 1. Install
pip install mcp-hangar
# or: uv pip install mcp-hangar

# 2. Initialize with wizard
mcp-hangar init

# 3. Start server
mcp-hangar serve
```

### HTTP Mode

```bash
# Start with HTTP transport and REST API
mcp-hangar serve --http --port 8000

# REST API:  http://localhost:8000/api/
```

## What It Does

**Parallel execution.** Your AI agent calls 5 tools sequentially -- each takes 200ms, that's 1 second of waiting. `hangar_call` runs them in parallel. 200ms total.

```
hangar_call(calls=[
    {"mcp_server": "github", "tool": "search_repos", "arguments": {"query": "mcp"}},
    {"mcp_server": "slack", "tool": "post_message", "arguments": {"channel": "#dev"}},
    {"mcp_server": "internal-api", "tool": "get_status", "arguments": {}}
])
```

Single MCP tool call. Parallel execution. All results returned together.

**Lifecycle management.** Lazy loading, health checks, automatic restart, graceful shutdown. MCP servers start on first use, stay warm while active, shut down after idle TTL.

**Single-flight cold starts.** When 10 parallel calls hit a cold MCP server, it initializes once -- not 10 times.

**Circuit breaker.** One failing MCP server doesn't kill your batch. Automatic isolation and recovery.

## Configuration

```yaml
mcp_servers:
  github:
    mode: subprocess
    command: [uvx, mcp-server-github]
    env:
      GITHUB_TOKEN: ${GITHUB_TOKEN}

  slack:
    mode: subprocess
    command: [uvx, mcp-server-slack]

  internal-api:
    mode: remote
    endpoint: "http://localhost:8080"

  custom-server:
    mode: docker
    image: my-registry/mcp-server:latest
    container:
      command: ["python", "-m", "custom_entrypoint"]
```

### Claude Desktop Integration

`mcp-hangar init` auto-configures Claude Desktop. For manual setup, add to your Claude Desktop config:

**macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
**Linux:** `~/.config/Claude/claude_desktop_config.json`
**Windows:** `%APPDATA%\Claude\claude_desktop_config.json`

```json
{
  "mcpServers": {
    "hangar": {
      "command": "mcp-hangar",
      "args": ["serve", "--config", "~/.config/mcp-hangar/config.yaml"]
    }
  }
}
```

Restart Claude Desktop. Done.

## Python API

For programmatic use (scripts, pipelines, custom integrations):

```python
from mcp_hangar import Hangar, HangarConfig

# Async
async with Hangar.from_config("config.yaml") as hangar:
    result = await hangar.invoke("math", "add", {"a": 1, "b": 2})

# Sync wrapper
from mcp_hangar import SyncHangar

with SyncHangar.from_config("config.yaml") as hangar:
    result = hangar.invoke("math", "add", {"a": 1, "b": 2})

# Programmatic config
config = (
    HangarConfig()
    .add_mcp_server("math", command=["python", "-m", "math_server"])
    .add_mcp_server("fetch", mode="docker", image="mcp/fetch:latest")
    .build()
)
hangar = Hangar(config)
```

## Security & Governance (1.0)

- **Capability declaration.** Declare what each MCP server can access (network, filesystem, environment). Violations are detected and reported.
- **Behavioral profiling.** Baseline MCP server behavior, detect deviations (new destinations, protocol drift, frequency anomalies). Learning and enforcing modes.
- **Tool schema drift detection.** Track tool schema changes across MCP server updates.
- **Network connection monitoring.** `/proc/net/tcp` parsing, Docker and Kubernetes monitors with audit events.
- **RBAC.** Role-based access control with tool-level policies. API key and JWT/OIDC authentication.
- **Approval gate.** Human-in-the-loop approval for sensitive tool calls.

## Observability

- **OpenTelemetry.** Distributed tracing with W3C trace context propagation across MCP servers.
- **Prometheus metrics.** MCP server state, tool calls, health checks, circuit breaker, concurrency, batch execution.
- **Grafana dashboards.** Pre-built overview and per-MCP server deep dive dashboards.
- **Structured logging.** Correlation IDs across parallel calls. JSON log format for production.
- **Audit trail.** Event-sourced audit log with OTLP export for security-relevant events.

## Advanced Configuration

```yaml
mcp_servers:
  fast-mcp-server:
    mode: subprocess
    command: ["python", "fast.py"]
    idle_ttl_s: 300              # Shutdown after 5min idle
    health_check_interval_s: 60  # Check health every minute
    max_consecutive_failures: 3  # Circuit breaker threshold
    max_concurrency: 5           # Per-MCP server concurrency limit
    tools:
      deny_list: [delete_*]      # Tool access filtering

execution:
  max_concurrency: 50            # Global concurrency limit
  default_mcp_server_concurrency: 10

truncation:
  enabled: true
  max_batch_size_bytes: 950000   # Under Claude's 1MB limit

config_reload:
  enabled: true                  # Live config reload via file watch
```

## Scales With You

- **Home lab:** 2 MCP servers, zero config complexity
- **Team setup:** Shared MCP servers, Docker containers, hot-reload
- **Enterprise:** 50+ MCP servers, behavioral profiling, RBAC, approval gates, Kubernetes operator

Same API. Same reliability. Different scale.

## Documentation

- [Getting Started](https://www.mcp-hangar.io/docs/oss/getting-started/quickstart)
- [Configuration Reference](https://mcp-hangar.io/reference/configuration/)
- [REST API Guide](https://www.mcp-hangar.io/docs/oss/reference/configuration)
- [Observability Setup](https://www.mcp-hangar.io/docs/oss/guides/OBSERVABILITY)
- [Authentication & RBAC](https://www.mcp-hangar.io/docs/oss/guides/AUTHENTICATION)
- [Cookbook](https://www.mcp-hangar.io/docs/oss/cookbook/)

## License

Core (`src/`) is MIT licensed. Enterprise features (`enterprise/`) are BSL 1.1 licensed.

See [LICENSE](LICENSE) for MIT terms and [enterprise/LICENSE.BSL](enterprise/LICENSE.BSL) for BSL terms.

---

[Docs](https://mcp-hangar.io) | [PyPI](https://pypi.org/project/mcp-hangar/) | [GitHub](https://github.com/mcp-hangar/mcp-hangar)
