mcp-hangar 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mcp_hangar/__init__.py +139 -0
- mcp_hangar/application/__init__.py +1 -0
- mcp_hangar/application/commands/__init__.py +67 -0
- mcp_hangar/application/commands/auth_commands.py +118 -0
- mcp_hangar/application/commands/auth_handlers.py +296 -0
- mcp_hangar/application/commands/commands.py +59 -0
- mcp_hangar/application/commands/handlers.py +189 -0
- mcp_hangar/application/discovery/__init__.py +21 -0
- mcp_hangar/application/discovery/discovery_metrics.py +283 -0
- mcp_hangar/application/discovery/discovery_orchestrator.py +497 -0
- mcp_hangar/application/discovery/lifecycle_manager.py +315 -0
- mcp_hangar/application/discovery/security_validator.py +414 -0
- mcp_hangar/application/event_handlers/__init__.py +50 -0
- mcp_hangar/application/event_handlers/alert_handler.py +191 -0
- mcp_hangar/application/event_handlers/audit_handler.py +203 -0
- mcp_hangar/application/event_handlers/knowledge_base_handler.py +120 -0
- mcp_hangar/application/event_handlers/logging_handler.py +69 -0
- mcp_hangar/application/event_handlers/metrics_handler.py +152 -0
- mcp_hangar/application/event_handlers/persistent_audit_store.py +217 -0
- mcp_hangar/application/event_handlers/security_handler.py +604 -0
- mcp_hangar/application/mcp/tooling.py +158 -0
- mcp_hangar/application/ports/__init__.py +9 -0
- mcp_hangar/application/ports/observability.py +237 -0
- mcp_hangar/application/queries/__init__.py +52 -0
- mcp_hangar/application/queries/auth_handlers.py +237 -0
- mcp_hangar/application/queries/auth_queries.py +118 -0
- mcp_hangar/application/queries/handlers.py +227 -0
- mcp_hangar/application/read_models/__init__.py +11 -0
- mcp_hangar/application/read_models/provider_views.py +139 -0
- mcp_hangar/application/sagas/__init__.py +11 -0
- mcp_hangar/application/sagas/group_rebalance_saga.py +137 -0
- mcp_hangar/application/sagas/provider_failover_saga.py +266 -0
- mcp_hangar/application/sagas/provider_recovery_saga.py +172 -0
- mcp_hangar/application/services/__init__.py +9 -0
- mcp_hangar/application/services/provider_service.py +208 -0
- mcp_hangar/application/services/traced_provider_service.py +211 -0
- mcp_hangar/bootstrap/runtime.py +328 -0
- mcp_hangar/context.py +178 -0
- mcp_hangar/domain/__init__.py +117 -0
- mcp_hangar/domain/contracts/__init__.py +57 -0
- mcp_hangar/domain/contracts/authentication.py +225 -0
- mcp_hangar/domain/contracts/authorization.py +229 -0
- mcp_hangar/domain/contracts/event_store.py +178 -0
- mcp_hangar/domain/contracts/metrics_publisher.py +59 -0
- mcp_hangar/domain/contracts/persistence.py +383 -0
- mcp_hangar/domain/contracts/provider_runtime.py +146 -0
- mcp_hangar/domain/discovery/__init__.py +20 -0
- mcp_hangar/domain/discovery/conflict_resolver.py +267 -0
- mcp_hangar/domain/discovery/discovered_provider.py +185 -0
- mcp_hangar/domain/discovery/discovery_service.py +412 -0
- mcp_hangar/domain/discovery/discovery_source.py +192 -0
- mcp_hangar/domain/events.py +433 -0
- mcp_hangar/domain/exceptions.py +525 -0
- mcp_hangar/domain/model/__init__.py +70 -0
- mcp_hangar/domain/model/aggregate.py +58 -0
- mcp_hangar/domain/model/circuit_breaker.py +152 -0
- mcp_hangar/domain/model/event_sourced_api_key.py +413 -0
- mcp_hangar/domain/model/event_sourced_provider.py +423 -0
- mcp_hangar/domain/model/event_sourced_role_assignment.py +268 -0
- mcp_hangar/domain/model/health_tracker.py +183 -0
- mcp_hangar/domain/model/load_balancer.py +185 -0
- mcp_hangar/domain/model/provider.py +810 -0
- mcp_hangar/domain/model/provider_group.py +656 -0
- mcp_hangar/domain/model/tool_catalog.py +105 -0
- mcp_hangar/domain/policies/__init__.py +19 -0
- mcp_hangar/domain/policies/provider_health.py +187 -0
- mcp_hangar/domain/repository.py +249 -0
- mcp_hangar/domain/security/__init__.py +85 -0
- mcp_hangar/domain/security/input_validator.py +710 -0
- mcp_hangar/domain/security/rate_limiter.py +387 -0
- mcp_hangar/domain/security/roles.py +237 -0
- mcp_hangar/domain/security/sanitizer.py +387 -0
- mcp_hangar/domain/security/secrets.py +501 -0
- mcp_hangar/domain/services/__init__.py +20 -0
- mcp_hangar/domain/services/audit_service.py +376 -0
- mcp_hangar/domain/services/image_builder.py +328 -0
- mcp_hangar/domain/services/provider_launcher.py +1046 -0
- mcp_hangar/domain/value_objects.py +1138 -0
- mcp_hangar/errors.py +818 -0
- mcp_hangar/fastmcp_server.py +1105 -0
- mcp_hangar/gc.py +134 -0
- mcp_hangar/infrastructure/__init__.py +79 -0
- mcp_hangar/infrastructure/async_executor.py +133 -0
- mcp_hangar/infrastructure/auth/__init__.py +37 -0
- mcp_hangar/infrastructure/auth/api_key_authenticator.py +388 -0
- mcp_hangar/infrastructure/auth/event_sourced_store.py +567 -0
- mcp_hangar/infrastructure/auth/jwt_authenticator.py +360 -0
- mcp_hangar/infrastructure/auth/middleware.py +340 -0
- mcp_hangar/infrastructure/auth/opa_authorizer.py +243 -0
- mcp_hangar/infrastructure/auth/postgres_store.py +659 -0
- mcp_hangar/infrastructure/auth/projections.py +366 -0
- mcp_hangar/infrastructure/auth/rate_limiter.py +311 -0
- mcp_hangar/infrastructure/auth/rbac_authorizer.py +323 -0
- mcp_hangar/infrastructure/auth/sqlite_store.py +624 -0
- mcp_hangar/infrastructure/command_bus.py +112 -0
- mcp_hangar/infrastructure/discovery/__init__.py +110 -0
- mcp_hangar/infrastructure/discovery/docker_source.py +289 -0
- mcp_hangar/infrastructure/discovery/entrypoint_source.py +249 -0
- mcp_hangar/infrastructure/discovery/filesystem_source.py +383 -0
- mcp_hangar/infrastructure/discovery/kubernetes_source.py +247 -0
- mcp_hangar/infrastructure/event_bus.py +260 -0
- mcp_hangar/infrastructure/event_sourced_repository.py +443 -0
- mcp_hangar/infrastructure/event_store.py +396 -0
- mcp_hangar/infrastructure/knowledge_base/__init__.py +259 -0
- mcp_hangar/infrastructure/knowledge_base/contracts.py +202 -0
- mcp_hangar/infrastructure/knowledge_base/memory.py +177 -0
- mcp_hangar/infrastructure/knowledge_base/postgres.py +545 -0
- mcp_hangar/infrastructure/knowledge_base/sqlite.py +513 -0
- mcp_hangar/infrastructure/metrics_publisher.py +36 -0
- mcp_hangar/infrastructure/observability/__init__.py +10 -0
- mcp_hangar/infrastructure/observability/langfuse_adapter.py +534 -0
- mcp_hangar/infrastructure/persistence/__init__.py +33 -0
- mcp_hangar/infrastructure/persistence/audit_repository.py +371 -0
- mcp_hangar/infrastructure/persistence/config_repository.py +398 -0
- mcp_hangar/infrastructure/persistence/database.py +333 -0
- mcp_hangar/infrastructure/persistence/database_common.py +330 -0
- mcp_hangar/infrastructure/persistence/event_serializer.py +280 -0
- mcp_hangar/infrastructure/persistence/event_upcaster.py +166 -0
- mcp_hangar/infrastructure/persistence/in_memory_event_store.py +150 -0
- mcp_hangar/infrastructure/persistence/recovery_service.py +312 -0
- mcp_hangar/infrastructure/persistence/sqlite_event_store.py +386 -0
- mcp_hangar/infrastructure/persistence/unit_of_work.py +409 -0
- mcp_hangar/infrastructure/persistence/upcasters/README.md +13 -0
- mcp_hangar/infrastructure/persistence/upcasters/__init__.py +7 -0
- mcp_hangar/infrastructure/query_bus.py +153 -0
- mcp_hangar/infrastructure/saga_manager.py +401 -0
- mcp_hangar/logging_config.py +209 -0
- mcp_hangar/metrics.py +1007 -0
- mcp_hangar/models.py +31 -0
- mcp_hangar/observability/__init__.py +54 -0
- mcp_hangar/observability/health.py +487 -0
- mcp_hangar/observability/metrics.py +319 -0
- mcp_hangar/observability/tracing.py +433 -0
- mcp_hangar/progress.py +542 -0
- mcp_hangar/retry.py +613 -0
- mcp_hangar/server/__init__.py +120 -0
- mcp_hangar/server/__main__.py +6 -0
- mcp_hangar/server/auth_bootstrap.py +340 -0
- mcp_hangar/server/auth_cli.py +335 -0
- mcp_hangar/server/auth_config.py +305 -0
- mcp_hangar/server/bootstrap.py +735 -0
- mcp_hangar/server/cli.py +161 -0
- mcp_hangar/server/config.py +224 -0
- mcp_hangar/server/context.py +215 -0
- mcp_hangar/server/http_auth_middleware.py +165 -0
- mcp_hangar/server/lifecycle.py +467 -0
- mcp_hangar/server/state.py +117 -0
- mcp_hangar/server/tools/__init__.py +16 -0
- mcp_hangar/server/tools/discovery.py +186 -0
- mcp_hangar/server/tools/groups.py +75 -0
- mcp_hangar/server/tools/health.py +301 -0
- mcp_hangar/server/tools/provider.py +939 -0
- mcp_hangar/server/tools/registry.py +320 -0
- mcp_hangar/server/validation.py +113 -0
- mcp_hangar/stdio_client.py +229 -0
- mcp_hangar-0.2.0.dist-info/METADATA +347 -0
- mcp_hangar-0.2.0.dist-info/RECORD +160 -0
- mcp_hangar-0.2.0.dist-info/WHEEL +4 -0
- mcp_hangar-0.2.0.dist-info/entry_points.txt +2 -0
- mcp_hangar-0.2.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mcp-hangar
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Production-grade hot-load registry for MCP providers
|
|
5
|
+
Project-URL: Homepage, https://github.com/mapyr/mcp-hangar
|
|
6
|
+
Project-URL: Documentation, https://mapyr.github.io/mcp-hangar/
|
|
7
|
+
Project-URL: Repository, https://github.com/mapyr/mcp-hangar
|
|
8
|
+
Project-URL: Changelog, https://github.com/mapyr/mcp-hangar/blob/main/CHANGELOG.md
|
|
9
|
+
Author: MCP Registry Contributors
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Python: >=3.11
|
|
12
|
+
Requires-Dist: aiosqlite>=0.19.0
|
|
13
|
+
Requires-Dist: cryptography>=41.0.0
|
|
14
|
+
Requires-Dist: docker>=7.1.0
|
|
15
|
+
Requires-Dist: fastapi>=0.104.0
|
|
16
|
+
Requires-Dist: httpx>=0.25.0
|
|
17
|
+
Requires-Dist: mcp>=0.9.0
|
|
18
|
+
Requires-Dist: pyjwt[crypto]>=2.8.0
|
|
19
|
+
Requires-Dist: pyyaml>=6.0
|
|
20
|
+
Requires-Dist: starlette>=0.27.0
|
|
21
|
+
Requires-Dist: structlog>=24.0.0
|
|
22
|
+
Requires-Dist: uvicorn[standard]>=0.24.0
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: black>=23.0.0; extra == 'dev'
|
|
25
|
+
Requires-Dist: build>=1.0.0; extra == 'dev'
|
|
26
|
+
Requires-Dist: hypothesis>=6.90.0; extra == 'dev'
|
|
27
|
+
Requires-Dist: isort>=5.12.0; extra == 'dev'
|
|
28
|
+
Requires-Dist: pip-audit>=2.6.0; extra == 'dev'
|
|
29
|
+
Requires-Dist: pre-commit>=3.5.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
|
|
32
|
+
Requires-Dist: pytest-timeout>=2.2.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: ruff>=0.1.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: twine>=5.0.0; extra == 'dev'
|
|
36
|
+
Provides-Extra: docs
|
|
37
|
+
Requires-Dist: mkdocs-git-revision-date-localized-plugin>=1.2.0; extra == 'docs'
|
|
38
|
+
Requires-Dist: mkdocs-material>=9.5.0; extra == 'docs'
|
|
39
|
+
Requires-Dist: mkdocs>=1.5.0; extra == 'docs'
|
|
40
|
+
Requires-Dist: mkdocstrings[python]>=0.24.0; extra == 'docs'
|
|
41
|
+
Provides-Extra: observability
|
|
42
|
+
Requires-Dist: langfuse>=2.0.0; extra == 'observability'
|
|
43
|
+
Provides-Extra: postgres
|
|
44
|
+
Requires-Dist: asyncpg>=0.29.0; extra == 'postgres'
|
|
45
|
+
Provides-Extra: testcontainers
|
|
46
|
+
Requires-Dist: httpx>=0.25.0; extra == 'testcontainers'
|
|
47
|
+
Requires-Dist: pytest-docker>=3.0.0; extra == 'testcontainers'
|
|
48
|
+
Requires-Dist: testcontainers[postgres,redis]>=4.0.0; extra == 'testcontainers'
|
|
49
|
+
Description-Content-Type: text/markdown
|
|
50
|
+
|
|
51
|
+
# MCP Hangar
|
|
52
|
+
|
|
53
|
+
[](https://github.com/mapyr/mcp-hangar/actions/workflows/test.yml)
|
|
54
|
+
[](https://pypi.org/project/mcp-hangar/)
|
|
55
|
+
[](https://www.python.org/downloads/)
|
|
56
|
+
[](https://opensource.org/licenses/MIT)
|
|
57
|
+
[](https://mapyr.github.io/mcp-hangar/)
|
|
58
|
+
|
|
59
|
+
**Production-grade MCP infrastructure with auto-discovery, observability, and resilience patterns.**
|
|
60
|
+
|
|
61
|
+
## Overview
|
|
62
|
+
|
|
63
|
+
MCP Hangar is a lifecycle management platform for Model Context Protocol providers, built for platform teams running MCP at scale. It replaces ad-hoc provider management with a unified control plane featuring auto-discovery from Kubernetes, Docker, and filesystem sources; circuit breakers and saga-based recovery for resilience; and first-class observability through Langfuse, OpenTelemetry, and Prometheus. The architecture follows Domain-Driven Design with CQRS and Event Sourcing, providing full audit trails for compliance-heavy environments.
|
|
64
|
+
|
|
65
|
+
## Why MCP Hangar?
|
|
66
|
+
|
|
67
|
+
| Challenge | Without MCP Hangar | With MCP Hangar |
|
|
68
|
+
|-----------|-------------------|-----------------|
|
|
69
|
+
| **Provider lifecycle** | Manual start/stop, no health monitoring | State machine with circuit breaker, health checks, automatic GC |
|
|
70
|
+
| **Observability** | None or DIY | Built-in Langfuse, OpenTelemetry, Prometheus metrics |
|
|
71
|
+
| **Dynamic environments** | Restart required for new providers | Auto-discovery from K8s, Docker, filesystem, entrypoints |
|
|
72
|
+
| **Failure handling** | Cascading failures | Circuit breaker, saga-based recovery and failover |
|
|
73
|
+
| **Audit & compliance** | None | Event sourcing with full audit trail |
|
|
74
|
+
| **Cold start latency** | Wait for provider startup | Predefined tools visible immediately, lazy loading |
|
|
75
|
+
| **Multi-provider routing** | Manual coordination | Load balancing with weighted round-robin, priority, least connections |
|
|
76
|
+
|
|
77
|
+
## Key Features
|
|
78
|
+
|
|
79
|
+
<details>
|
|
80
|
+
<summary><strong>🔄 Lifecycle Management</strong></summary>
|
|
81
|
+
|
|
82
|
+
Provider lifecycle follows a strict state machine:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
COLD → INITIALIZING → READY ⇄ DEGRADED → DEAD
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
- **Lazy loading** — Providers start on first invocation, not at boot
|
|
89
|
+
- **Predefined tools** — Tool schemas visible before provider starts (no cold start for discovery)
|
|
90
|
+
- **Automatic GC** — Idle providers shutdown after configurable TTL
|
|
91
|
+
- **Graceful shutdown** — Clean termination with timeout enforcement
|
|
92
|
+
|
|
93
|
+
</details>
|
|
94
|
+
|
|
95
|
+
<details>
|
|
96
|
+
<summary><strong>🔍 Auto-Discovery</strong></summary>
|
|
97
|
+
|
|
98
|
+
Automatically detect and register providers from multiple sources:
|
|
99
|
+
|
|
100
|
+
| Source | Configuration |
|
|
101
|
+
|--------|---------------|
|
|
102
|
+
| **Kubernetes** | Pod annotations (`mcp.hangar.io/*`) with namespace filtering |
|
|
103
|
+
| **Docker/Podman** | Container labels (`mcp.hangar.*`) |
|
|
104
|
+
| **Filesystem** | YAML configs with file watching |
|
|
105
|
+
| **Python entrypoints** | `mcp.providers` entry point group |
|
|
106
|
+
|
|
107
|
+
Discovery modes:
|
|
108
|
+
- `additive` — Only adds providers, never removes (safe for static environments)
|
|
109
|
+
- `authoritative` — Adds and removes (for dynamic environments like K8s)
|
|
110
|
+
|
|
111
|
+
Conflict resolution: Static config > Kubernetes > Docker > Filesystem > Entrypoints
|
|
112
|
+
|
|
113
|
+
</details>
|
|
114
|
+
|
|
115
|
+
<details>
|
|
116
|
+
<summary><strong>📊 Observability</strong></summary>
|
|
117
|
+
|
|
118
|
+
Full observability stack for production operations:
|
|
119
|
+
|
|
120
|
+
**Langfuse Integration**
|
|
121
|
+
- End-to-end LLM tracing from prompt to provider response
|
|
122
|
+
- Cost attribution per provider, tool, user, or session
|
|
123
|
+
- Quality scoring and automated evals
|
|
124
|
+
|
|
125
|
+
**OpenTelemetry**
|
|
126
|
+
- Distributed tracing with context propagation
|
|
127
|
+
- OTLP export to Jaeger, Zipkin, or any collector
|
|
128
|
+
|
|
129
|
+
**Prometheus Metrics**
|
|
130
|
+
- Tool invocation latency and error rates
|
|
131
|
+
- Provider state transitions and cold starts
|
|
132
|
+
- Circuit breaker state and trip counts
|
|
133
|
+
- Health check results
|
|
134
|
+
|
|
135
|
+
**Health Endpoints**
|
|
136
|
+
- `/health/live` — Liveness check
|
|
137
|
+
- `/health/ready` — Readiness check (K8s compatible)
|
|
138
|
+
- `/health/startup` — Startup check
|
|
139
|
+
- `/metrics` — Prometheus scrape endpoint
|
|
140
|
+
|
|
141
|
+
</details>
|
|
142
|
+
|
|
143
|
+
<details>
|
|
144
|
+
<summary><strong>🛡️ Resilience</strong></summary>
|
|
145
|
+
|
|
146
|
+
Production-grade failure handling:
|
|
147
|
+
|
|
148
|
+
**Circuit Breaker**
|
|
149
|
+
- Opens after configurable failure threshold
|
|
150
|
+
- Auto-reset after timeout period
|
|
151
|
+
- Prevents cascading failures to healthy providers
|
|
152
|
+
|
|
153
|
+
**Saga-Based Recovery**
|
|
154
|
+
- `ProviderRecoverySaga` — Automatic restart with exponential backoff
|
|
155
|
+
- `ProviderFailoverSaga` — Failover to backup providers with auto-failback
|
|
156
|
+
- `GroupRebalanceSaga` — Rebalance traffic when members change
|
|
157
|
+
|
|
158
|
+
**Health Monitoring**
|
|
159
|
+
- Configurable check intervals
|
|
160
|
+
- Consecutive failure thresholds
|
|
161
|
+
- Automatic state transitions (READY → DEGRADED)
|
|
162
|
+
|
|
163
|
+
</details>
|
|
164
|
+
|
|
165
|
+
<details>
|
|
166
|
+
<summary><strong>🔒 Security</strong></summary>
|
|
167
|
+
|
|
168
|
+
Enterprise security controls:
|
|
169
|
+
|
|
170
|
+
- **Rate limiting** — Per-provider request limits
|
|
171
|
+
- **Input validation** — Schema validation before provider invocation
|
|
172
|
+
- **Secrets management** — Environment variable injection, never in config files
|
|
173
|
+
- **Container isolation** — Read-only filesystems, resource limits, network policies
|
|
174
|
+
- **Discovery security** — Namespace filtering, max providers per source, quarantine on failure
|
|
175
|
+
|
|
176
|
+
</details>
|
|
177
|
+
|
|
178
|
+
<details>
|
|
179
|
+
<summary><strong>🏗️ Architecture</strong></summary>
|
|
180
|
+
|
|
181
|
+
Domain-Driven Design with clean layer separation:
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
domain/ Core business logic, state machines, events, value objects
|
|
185
|
+
application/ Use cases, commands, queries, sagas
|
|
186
|
+
infrastructure/ Adapters for containers, subprocess, persistence, event bus
|
|
187
|
+
server/ MCP protocol handlers and validation
|
|
188
|
+
bootstrap/ Runtime initialization and dependency injection
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
- **CQRS** — Separate command and query paths
|
|
192
|
+
- **Event Sourcing** — All state changes emit domain events
|
|
193
|
+
- **Port/Adapter** — Extensible infrastructure layer
|
|
194
|
+
- **Thread-safe** — Lock hierarchy for concurrent access
|
|
195
|
+
|
|
196
|
+
</details>
|
|
197
|
+
|
|
198
|
+
## Quick Start
|
|
199
|
+
|
|
200
|
+
**Install:**
|
|
201
|
+
```bash
|
|
202
|
+
pip install mcp-hangar
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**Configure (`config.yaml`):**
|
|
206
|
+
```yaml
|
|
207
|
+
providers:
|
|
208
|
+
math:
|
|
209
|
+
mode: subprocess
|
|
210
|
+
command: [python, -m, my_math_server]
|
|
211
|
+
idle_ttl_s: 300
|
|
212
|
+
|
|
213
|
+
sqlite:
|
|
214
|
+
mode: container
|
|
215
|
+
image: ghcr.io/modelcontextprotocol/server-sqlite:latest
|
|
216
|
+
volumes:
|
|
217
|
+
- "/data/sqlite:/data:rw"
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**Run:**
|
|
221
|
+
```bash
|
|
222
|
+
# Stdio mode (Claude Desktop, Cursor, etc.)
|
|
223
|
+
mcp-hangar --config config.yaml
|
|
224
|
+
|
|
225
|
+
# HTTP mode (LM Studio, web clients)
|
|
226
|
+
mcp-hangar --config config.yaml --http
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Architecture Overview
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
233
|
+
│ MCP Hangar │
|
|
234
|
+
│ ┌──────────────────────────────────────────────────────────┐ │
|
|
235
|
+
│ │ FastMCP Server │ │
|
|
236
|
+
│ │ (Stdio or HTTP transport) │ │
|
|
237
|
+
│ └──────────────────────────┬───────────────────────────────┘ │
|
|
238
|
+
│ │ │
|
|
239
|
+
│ ┌──────────────────────────▼───────────────────────────────┐ │
|
|
240
|
+
│ │ Provider Manager │ │
|
|
241
|
+
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
|
|
242
|
+
│ │ │ State │ │ Health │ │ Circuit │ │ │
|
|
243
|
+
│ │ │ Machine │ │ Tracker │ │ Breaker │ │ │
|
|
244
|
+
│ │ └─────────┘ └─────────┘ └─────────┘ │ │
|
|
245
|
+
│ └──────────────────────────┬───────────────────────────────┘ │
|
|
246
|
+
│ │ │
|
|
247
|
+
│ ┌──────────────────────────▼───────────────────────────────┐ │
|
|
248
|
+
│ │ Providers │ │
|
|
249
|
+
│ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ │ │
|
|
250
|
+
│ │ │ Subprocess│ │ Docker │ │ Remote │ │ │
|
|
251
|
+
│ │ └───────────┘ └───────────┘ └───────────┘ │ │
|
|
252
|
+
│ └──────────────────────────────────────────────────────────┘ │
|
|
253
|
+
│ │
|
|
254
|
+
│ Background: [GC Worker] [Health Worker] [Discovery Worker] │
|
|
255
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Registry Tools
|
|
259
|
+
|
|
260
|
+
| Tool | Description |
|
|
261
|
+
|------|-------------|
|
|
262
|
+
| `registry_list` | List all providers with state, health status, and available tools |
|
|
263
|
+
| `registry_start` | Explicitly start a provider |
|
|
264
|
+
| `registry_stop` | Stop a running provider |
|
|
265
|
+
| `registry_invoke` | Invoke a tool on a provider (auto-starts if needed) |
|
|
266
|
+
| `registry_invoke_ex` | Invoke with retry, correlation ID, and metadata |
|
|
267
|
+
| `registry_invoke_stream` | Invoke with real-time progress notifications |
|
|
268
|
+
| `registry_tools` | Get tool schemas for a provider |
|
|
269
|
+
| `registry_health` | Get health status and metrics |
|
|
270
|
+
| `registry_status` | Dashboard view of all providers |
|
|
271
|
+
| `registry_discover` | Trigger discovery cycle |
|
|
272
|
+
| `registry_sources` | List discovery sources with status |
|
|
273
|
+
| `registry_warm` | Pre-start providers to avoid cold start latency |
|
|
274
|
+
|
|
275
|
+
## Configuration Reference
|
|
276
|
+
|
|
277
|
+
| Option | Description | Default |
|
|
278
|
+
|--------|-------------|---------|
|
|
279
|
+
| `mode` | Provider mode: `subprocess`, `container`, `docker`, `remote`, `group` | required |
|
|
280
|
+
| `command` | Command for subprocess providers | — |
|
|
281
|
+
| `image` | Container image for container providers | — |
|
|
282
|
+
| `idle_ttl_s` | Seconds before idle provider shutdown | `300` |
|
|
283
|
+
| `health_check_interval_s` | Health check frequency in seconds | `60` |
|
|
284
|
+
| `max_consecutive_failures` | Failures before transition to DEGRADED | `3` |
|
|
285
|
+
| `tools` | Predefined tool schemas (visible before start) | — |
|
|
286
|
+
| `volumes` | Container volume mounts | — |
|
|
287
|
+
| `network` | Container network mode | `none` |
|
|
288
|
+
| `read_only` | Container read-only filesystem | `true` |
|
|
289
|
+
|
|
290
|
+
## Observability Setup
|
|
291
|
+
|
|
292
|
+
```yaml
|
|
293
|
+
observability:
|
|
294
|
+
langfuse:
|
|
295
|
+
enabled: true
|
|
296
|
+
public_key: ${LANGFUSE_PUBLIC_KEY}
|
|
297
|
+
secret_key: ${LANGFUSE_SECRET_KEY}
|
|
298
|
+
host: https://cloud.langfuse.com
|
|
299
|
+
|
|
300
|
+
tracing:
|
|
301
|
+
enabled: true
|
|
302
|
+
otlp_endpoint: http://localhost:4317
|
|
303
|
+
|
|
304
|
+
metrics:
|
|
305
|
+
enabled: true
|
|
306
|
+
endpoint: /metrics
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
**Environment Variables:**
|
|
310
|
+
| Variable | Description |
|
|
311
|
+
|----------|-------------|
|
|
312
|
+
| `LANGFUSE_PUBLIC_KEY` | Langfuse public key |
|
|
313
|
+
| `LANGFUSE_SECRET_KEY` | Langfuse secret key |
|
|
314
|
+
| `OTEL_EXPORTER_OTLP_ENDPOINT` | OpenTelemetry collector endpoint |
|
|
315
|
+
| `MCP_TRACING_ENABLED` | Enable/disable tracing (`true`/`false`) |
|
|
316
|
+
|
|
317
|
+
**Endpoints:**
|
|
318
|
+
- `/metrics` — Prometheus metrics
|
|
319
|
+
- `/health/live` — Liveness probe
|
|
320
|
+
- `/health/ready` — Readiness probe
|
|
321
|
+
- `/health/startup` — Startup probe
|
|
322
|
+
|
|
323
|
+
## Documentation
|
|
324
|
+
|
|
325
|
+
📖 **[Full Documentation](https://mapyr.github.io/mcp-hangar/)**
|
|
326
|
+
|
|
327
|
+
- [Installation](https://mapyr.github.io/mcp-hangar/getting-started/installation/)
|
|
328
|
+
- [Quick Start](https://mapyr.github.io/mcp-hangar/getting-started/quickstart/)
|
|
329
|
+
- [Container Guide](https://mapyr.github.io/mcp-hangar/guides/CONTAINERS/)
|
|
330
|
+
- [Auto-Discovery](https://mapyr.github.io/mcp-hangar/guides/DISCOVERY/)
|
|
331
|
+
- [Observability](https://mapyr.github.io/mcp-hangar/guides/OBSERVABILITY/)
|
|
332
|
+
- [Architecture](https://mapyr.github.io/mcp-hangar/architecture/OVERVIEW/)
|
|
333
|
+
|
|
334
|
+
## Contributing
|
|
335
|
+
|
|
336
|
+
See [Contributing Guide](https://mapyr.github.io/mcp-hangar/development/CONTRIBUTING/) for development setup, testing requirements, and code style.
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
git clone https://github.com/mapyr/mcp-hangar.git
|
|
340
|
+
cd mcp-hangar
|
|
341
|
+
uv sync --extra dev
|
|
342
|
+
uv run pytest tests/ -v
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
## License
|
|
346
|
+
|
|
347
|
+
MIT License — see [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
mcp_hangar/__init__.py,sha256=6-zLNi9bhwX6ANwsnPtN3Dr67WpLoogKvjbLdSC_KVA,3622
|
|
2
|
+
mcp_hangar/context.py,sha256=OzMxjHRBjDakgAbwv1bJnIx4RVYxQ7h3tkP8uOXrVj0,5617
|
|
3
|
+
mcp_hangar/errors.py,sha256=6Qjy5O93HbE4mgb15C6SqERFAX9WtGg6pkzojko3IrU,28338
|
|
4
|
+
mcp_hangar/fastmcp_server.py,sha256=GtgMwFBS5vLL2nVqB4RoduUhiYk4vHOPhMSk49gHZDQ,35835
|
|
5
|
+
mcp_hangar/gc.py,sha256=07En3UYsJqXuGkvDf9hgGb09-NzRWoTVaXaOIuwuT3s,5159
|
|
6
|
+
mcp_hangar/logging_config.py,sha256=gaM0PFpbp-16EaECpDa5Be3sHxpPYvBapQ4aIGgoYkM,7013
|
|
7
|
+
mcp_hangar/metrics.py,sha256=0ILrSiaCxJfxqoTiHOzfd2OO43vd0uKOkr3vkHkmusA,34177
|
|
8
|
+
mcp_hangar/models.py,sha256=QiJJkLh7Y6QL9prxrqCOt-kR2_wIn1WvgTIiedrmSoY,1024
|
|
9
|
+
mcp_hangar/progress.py,sha256=jjod35OyvLMIV7QGtQzvMKaaTrznKNvdeEfCMLH-nO8,16879
|
|
10
|
+
mcp_hangar/retry.py,sha256=MMCG4KM9IUKw5ea4NX6vzVaQ6saOjg-RVvxN567wkGM,19085
|
|
11
|
+
mcp_hangar/stdio_client.py,sha256=kNzYHTYyI4wWgWWNCATKEPlURMPxfOWdOYMY8i8ZAk4,7793
|
|
12
|
+
mcp_hangar/application/__init__.py,sha256=6icvv45gOJyi57kK1Hz51mjgYGYWbKEoziQDazoRM7A,56
|
|
13
|
+
mcp_hangar/application/commands/__init__.py,sha256=JqruZ38IG2gOE13BYMRTrcOuZkizdjMTUM0CnjhK4RY,1559
|
|
14
|
+
mcp_hangar/application/commands/auth_commands.py,sha256=D2ZT7J10-uFf_cckArDG4OxK75oQica8YmU2FUV1gYM,3199
|
|
15
|
+
mcp_hangar/application/commands/auth_handlers.py,sha256=xe-RrQvUEawPhR3PcEyfgs7eT5IITdjBk94rvQL227g,9245
|
|
16
|
+
mcp_hangar/application/commands/commands.py,sha256=q9sJeSmup2VuwbLDo3FK0aZVt80N3ywO6ybNe2MmviQ,1343
|
|
17
|
+
mcp_hangar/application/commands/handlers.py,sha256=2LbnemNBlyXm5qMJI5rUAr6BeJumnqjZfUYJAsBf3Mo,6133
|
|
18
|
+
mcp_hangar/application/discovery/__init__.py,sha256=LQF9VE4z-bphfDQf9ViA99aqDT6oqbJ9CXnoYgaEAH8,676
|
|
19
|
+
mcp_hangar/application/discovery/discovery_metrics.py,sha256=efoi1UgK8oEPNe4t6iO0v5tQpK78_gO6L8kpVrxcuCo,8876
|
|
20
|
+
mcp_hangar/application/discovery/discovery_orchestrator.py,sha256=YzITUOhjxvk_r0wUF_l82ENELHhgEpY6vRe76q-VgU0,17320
|
|
21
|
+
mcp_hangar/application/discovery/lifecycle_manager.py,sha256=_vNEIczTTYc107KQqAfGQWV6hp9FCWlAq9X7W1f5qOM,9692
|
|
22
|
+
mcp_hangar/application/discovery/security_validator.py,sha256=fhCrUnBVCVndaecqjL04bYZ4lo8hxhrBE3rq64nHBPE,14815
|
|
23
|
+
mcp_hangar/application/event_handlers/__init__.py,sha256=DiZt8ILKL-Ufcmy6K4X-L616W0k593rVrtMqu5eUryI,1288
|
|
24
|
+
mcp_hangar/application/event_handlers/alert_handler.py,sha256=ZBhGKt7A-JrvGIZ3-n1K8rVuUd4UkTCFMmZSTwbXNVA,6584
|
|
25
|
+
mcp_hangar/application/event_handlers/audit_handler.py,sha256=Hv0lKBQDhLYFHNiX45HkGJpSz732H-MdklnrnzXS2Pc,6163
|
|
26
|
+
mcp_hangar/application/event_handlers/knowledge_base_handler.py,sha256=w0EpI5-a23GPzFwE9tIOU8sVEqlIAvfISyatFYypLNY,4214
|
|
27
|
+
mcp_hangar/application/event_handlers/logging_handler.py,sha256=uELo7AHIAX0sZdFVOOL0XHYYQ4NjXZsIMpvqd3ZbvqI,2162
|
|
28
|
+
mcp_hangar/application/event_handlers/metrics_handler.py,sha256=GT54wM4pKcf3P4uWQhI1_FYaIOAEeY4qYITAYe1o67g,5272
|
|
29
|
+
mcp_hangar/application/event_handlers/persistent_audit_store.py,sha256=PCK_1duRwxGf9AAZb8JUPNO0pkdYrOyNrcwt8kP3Yww,7196
|
|
30
|
+
mcp_hangar/application/event_handlers/security_handler.py,sha256=04Dqa2cUfeucpPcx-fV5ZHA_S4TnETWLuMRg7sWgMiA,20047
|
|
31
|
+
mcp_hangar/application/mcp/tooling.py,sha256=Amchmtomv5KTs17qR9ii4qDIsd_j7RcitijfgRxuf9c,5463
|
|
32
|
+
mcp_hangar/application/ports/__init__.py,sha256=GXwsH0Y9iXBN_x3ngN8x_ifFsX_lYeq_FmnM-kHBUXE,238
|
|
33
|
+
mcp_hangar/application/ports/observability.py,sha256=iZH4jI28m6hQ1-v18MbHj2pd5Nd4qXB4mdP8LNJnEPU,6436
|
|
34
|
+
mcp_hangar/application/queries/__init__.py,sha256=qRg9_P3YaUWEUw24i6ggPQpR9YaOghzbzjBYAh2tVfY,1305
|
|
35
|
+
mcp_hangar/application/queries/auth_handlers.py,sha256=ObcmJbjYHw6g6Uv_vgv4_yTFpYwjyML7SXbTYu3LXNg,7550
|
|
36
|
+
mcp_hangar/application/queries/auth_queries.py,sha256=OmvVza1yYWJUnJHF57ZhHQeyumQuWtwvCw23d-UEBHI,2850
|
|
37
|
+
mcp_hangar/application/queries/handlers.py,sha256=ujAqA5nR_Fpq9JSFjV9ySP_VGtB8aHynQrqEKtt57f8,7336
|
|
38
|
+
mcp_hangar/application/read_models/__init__.py,sha256=AkV6TMAGJ-QqoOHjPdmmECwJ1ilOoQ4gAJN5wmJJKMg,256
|
|
39
|
+
mcp_hangar/application/read_models/provider_views.py,sha256=RG53G5D45_JHBS7qX4uL7y90XZ_0lpyj9VfwOpbZzNM,4056
|
|
40
|
+
mcp_hangar/application/sagas/__init__.py,sha256=L9rLRVDmB_bL8PuU_ByHgJfTqfdKpAR20vhqmHiIE9c,323
|
|
41
|
+
mcp_hangar/application/sagas/group_rebalance_saga.py,sha256=VvTcIu0V32MfDlAxWdyfX8_ZJJYoL5ipdt_0TGVs0TE,4620
|
|
42
|
+
mcp_hangar/application/sagas/provider_failover_saga.py,sha256=60nTAiCRwE2JfQh57ALoQ_HK0-aKYycNHQB9r_NMJuc,9540
|
|
43
|
+
mcp_hangar/application/sagas/provider_recovery_saga.py,sha256=X_dZmYNHyi-HQ3wQSe4jKEknfqH0J7LsDp3dpLRxZ50,6345
|
|
44
|
+
mcp_hangar/application/services/__init__.py,sha256=jhKdEdqmyPcXZFhbET7ZkXKXEVkG7XgG0vYm25RKp1A,226
|
|
45
|
+
mcp_hangar/application/services/provider_service.py,sha256=dJ1dz5nT0NfIfvXvxKphWzrjHElivn3yylL-22iw0TE,5966
|
|
46
|
+
mcp_hangar/application/services/traced_provider_service.py,sha256=gJ85NVEqCVJI2l1Q3BBajCwmM3KTt4uXKcQHKCPIMTI,6424
|
|
47
|
+
mcp_hangar/bootstrap/runtime.py,sha256=baspB4PJMuJJcBZEe84eHxAqAnt_gTEpcnDd1xqCVhI,11157
|
|
48
|
+
mcp_hangar/domain/__init__.py,sha256=G9IgEXAZyIVqOpfK162q4k4DH4Z_KLEYhJ4pGIh-kUQ,2825
|
|
49
|
+
mcp_hangar/domain/events.py,sha256=xI9Eq1zgeh6b2O--_q8sOL1lRF9P0e3cA0jJQ7Oy0XQ,9856
|
|
50
|
+
mcp_hangar/domain/exceptions.py,sha256=g3QDq8ezGn_HXsXQ6YL-3b28-tjiaLPIi7IYh8RIJnM,15161
|
|
51
|
+
mcp_hangar/domain/repository.py,sha256=YDj6ukQtRRSoVJk31owCFv2PCOUx9Fdq_dvRkjX7cqw,6678
|
|
52
|
+
mcp_hangar/domain/value_objects.py,sha256=2FGp5rWhsxi5OPmPnON0qePbtgen-3Tc1UqL5D4DHuc,34858
|
|
53
|
+
mcp_hangar/domain/contracts/__init__.py,sha256=lvUknpnP4u82JNj_Qo8SMgzQIOcoqRnr3teowrNFl1Q,1623
|
|
54
|
+
mcp_hangar/domain/contracts/authentication.py,sha256=9URfwc2KkZeJAN7QW3OPyVVC38b7ML5QPqRNMVpFbzE,6482
|
|
55
|
+
mcp_hangar/domain/contracts/authorization.py,sha256=4nJmerxuwEELQTim5U5syPH9OHuTwU5NjgoM8o1A8BM,6657
|
|
56
|
+
mcp_hangar/domain/contracts/event_store.py,sha256=dq3qVVSFF3AvPuqIFArV7qNMVPPRseJDlwG0xJhEke4,5262
|
|
57
|
+
mcp_hangar/domain/contracts/metrics_publisher.py,sha256=SCQV68tyc9qTDzHp9ISBc4ke0TZO0QMskPHuQSPbS5M,1573
|
|
58
|
+
mcp_hangar/domain/contracts/persistence.py,sha256=2YPloQQO_yWoEouKKFZK-ywGnf7C5xvzkNpVzBR1FZ4,11675
|
|
59
|
+
mcp_hangar/domain/contracts/provider_runtime.py,sha256=ORbqi96YldMmSeQ9OaoI8KlBLkP11BeljbgeF9LGcQI,4105
|
|
60
|
+
mcp_hangar/domain/discovery/__init__.py,sha256=hHuZCAfN6_jd_s-x5FsvsZLyqJfsvGeKGwfLBps9aw4,575
|
|
61
|
+
mcp_hangar/domain/discovery/conflict_resolver.py,sha256=sy63Z4k3uvjL3Xr42mLyTedExtjUfIDASrz5Ufy78rI,9127
|
|
62
|
+
mcp_hangar/domain/discovery/discovered_provider.py,sha256=6V69Z1vmpv4aXWN8oPHXT1UqzUqXnEArSlW8g82dpjc,6295
|
|
63
|
+
mcp_hangar/domain/discovery/discovery_service.py,sha256=TgmRlsucGd-TAJ64499A6NsOe3kI2VuKDQ3QnHa6PGw,14892
|
|
64
|
+
mcp_hangar/domain/discovery/discovery_source.py,sha256=FhlidypMmUwWhrp0T8l-8HGqCqpAF2c5rw8O5ROjAcI,5774
|
|
65
|
+
mcp_hangar/domain/model/__init__.py,sha256=Aq8qoFDOT7WLCVL7kPntw0IbtsggAuQttPyoplinbKg,1803
|
|
66
|
+
mcp_hangar/domain/model/aggregate.py,sha256=BnuIH52vQvjhRXBtyxBREVBR_5V7OmkrPtq9DRg4jy4,1796
|
|
67
|
+
mcp_hangar/domain/model/circuit_breaker.py,sha256=rD5PmfIYvwIGPjCr1KXdYKJQsfq1Ss7AAdxxCY0uGm4,4409
|
|
68
|
+
mcp_hangar/domain/model/event_sourced_api_key.py,sha256=-ixYJj1PLYLz3GG1fP02ynPm0H8MxuAx4W1h_61gy5E,12876
|
|
69
|
+
mcp_hangar/domain/model/event_sourced_provider.py,sha256=uZRsGb-CIayJHvNMpQDCz1izeIXTCUWgAm0CEKeMtuM,14959
|
|
70
|
+
mcp_hangar/domain/model/event_sourced_role_assignment.py,sha256=dnwcPBHUBGIVjeoPZfdJ9QtpvhqirrsS4d2KNfW80jI,8117
|
|
71
|
+
mcp_hangar/domain/model/health_tracker.py,sha256=D1pIaNXeh-HrfR4l83HQNKRofG0SlYeOj_IotcZ8glQ,5904
|
|
72
|
+
mcp_hangar/domain/model/load_balancer.py,sha256=2ZpwZ9KJJAFbqwpSWg5i4Drc1DsQlTtc3cvB48W1b6Q,5475
|
|
73
|
+
mcp_hangar/domain/model/provider.py,sha256=RBHENW5LkeLAdHOHT_IUAMm9vRHecmZX6iDsSLezhxI,28155
|
|
74
|
+
mcp_hangar/domain/model/provider_group.py,sha256=YAzJa6BQQyMWW6kptUVgmi37Gteine4g2r7DIhywvTI,20333
|
|
75
|
+
mcp_hangar/domain/model/tool_catalog.py,sha256=STvfiUuMyaR3jUOAsjbx5FjnSUolnud7M5LnIH51XrI,3170
|
|
76
|
+
mcp_hangar/domain/policies/__init__.py,sha256=e0M5nkEsNAxthygH6NpB_RBKFrFEx8HpoidHHdoizok,517
|
|
77
|
+
mcp_hangar/domain/policies/provider_health.py,sha256=v-9o14j_1xatNyd2H6VEeOpn2WzfL2jvQT84xrUhPjg,5499
|
|
78
|
+
mcp_hangar/domain/security/__init__.py,sha256=t2ukZtUljHcPihYENYTNCV1aNL2PDFOBAD79qcHdARs,1982
|
|
79
|
+
mcp_hangar/domain/security/input_validator.py,sha256=GNnC4XoIDZ_vcgv6x86dPNYhm_BwUuuOgUfZ2HuwR8o,23449
|
|
80
|
+
mcp_hangar/domain/security/rate_limiter.py,sha256=x7wTkQlJJl1i8KOSPzac7bXyFEQ6UPqJgYlmGZKU7sg,12550
|
|
81
|
+
mcp_hangar/domain/security/roles.py,sha256=xVoYzj94Hnc_n38t-Ch34oBxSzO-BD1DFMdXtiVR_P4,7128
|
|
82
|
+
mcp_hangar/domain/security/sanitizer.py,sha256=hKTAAfa8sZQB1RCusGEyoelGZtw3Bjconyka-JcfeJw,11632
|
|
83
|
+
mcp_hangar/domain/security/secrets.py,sha256=qj0pJh5Xocv5PXxNFWP1cH4H3UdBSD_V1XoZ0BBBSq8,14097
|
|
84
|
+
mcp_hangar/domain/services/__init__.py,sha256=WqvYJiH8Mt2qVXMTlwQvEV_tD81v2P3zjftJOYuNJDE,650
|
|
85
|
+
mcp_hangar/domain/services/audit_service.py,sha256=zQSNaaA_r4aZUHnjYDVmpaRW3KDwOLOZRryleRvaiMo,12377
|
|
86
|
+
mcp_hangar/domain/services/image_builder.py,sha256=Kf4AQpGGPqwrAtJfcJfm3HSe6aLoSDBUwkVG2sdA7wE,9827
|
|
87
|
+
mcp_hangar/domain/services/provider_launcher.py,sha256=b2xVldb8jDx4WlBEUDmP5iKhb27DQMG__BWXpUskRXc,35558
|
|
88
|
+
mcp_hangar/infrastructure/__init__.py,sha256=wHxfzH6abMSbN4rvYg4mnpdFKENyeDZO800BlB5hlhA,2114
|
|
89
|
+
mcp_hangar/infrastructure/async_executor.py,sha256=pdTOnYFMTwPiWKdfjjTav1Vik3f6KOBSXSwU9k8fttI,4522
|
|
90
|
+
mcp_hangar/infrastructure/command_bus.py,sha256=ZmTAo4bmaz-xfgKsacQL9QEq2RvREMeqxu7vq_vxExw,3238
|
|
91
|
+
mcp_hangar/infrastructure/event_bus.py,sha256=_GFF-jzFKdKtZWt-lI7Ut3O52HmWnbBVnvBLbNG4HqE,8344
|
|
92
|
+
mcp_hangar/infrastructure/event_sourced_repository.py,sha256=mnwWl3Pj279lspZD51hG3RgkLAdQfNC3tyzrjB0YsnI,16283
|
|
93
|
+
mcp_hangar/infrastructure/event_store.py,sha256=9pWhHui1SnoTPHV35xskhBxuXTLZFrPW5Cz11joIuv0,13269
|
|
94
|
+
mcp_hangar/infrastructure/metrics_publisher.py,sha256=ZcJLt3Es6UnBb2t80yadxzY9HDkD8Yh9dxfBcE_a-wk,1253
|
|
95
|
+
mcp_hangar/infrastructure/query_bus.py,sha256=P1IHG_mpaUAJlLOqqNobB_OYUQmy8sQgvElLLZ4LflI,3900
|
|
96
|
+
mcp_hangar/infrastructure/saga_manager.py,sha256=LHMA2IpBzqV_bo2kZyhj-1f2zeyn4bNuCS2is7hSZXU,12828
|
|
97
|
+
mcp_hangar/infrastructure/auth/__init__.py,sha256=xBM_Uk8UVTXqoYJK9ZfFxtTio0psbRlkJRlWSDvx5_o,1255
|
|
98
|
+
mcp_hangar/infrastructure/auth/api_key_authenticator.py,sha256=4bGvLIgfCpcFqOhsKdb_PmBKfuFJ340ljgYHishuvss,13314
|
|
99
|
+
mcp_hangar/infrastructure/auth/event_sourced_store.py,sha256=_fZvBCCXVN32SiGKlQRWCOje7zQi_5mNxW7VuX9CQe4,18193
|
|
100
|
+
mcp_hangar/infrastructure/auth/jwt_authenticator.py,sha256=KWlP5PFe5o9lZPNl5dBE4XCUckpUzMbvkI7z8lX7Ne0,11659
|
|
101
|
+
mcp_hangar/infrastructure/auth/middleware.py,sha256=NewDPDo-bh7WWkJ2G5-xyFA4zjxhgY9ZCFtct0US1GM,11685
|
|
102
|
+
mcp_hangar/infrastructure/auth/opa_authorizer.py,sha256=tLHFhzzpJ4lU-J61trS-Y0PFgJ9_6S_NlGH5-YvgKmY,7828
|
|
103
|
+
mcp_hangar/infrastructure/auth/postgres_store.py,sha256=DQ5ioz4hmeovwCBvYyCqC-wRWEhzGAlsbKDrumGNsv0,23066
|
|
104
|
+
mcp_hangar/infrastructure/auth/projections.py,sha256=cJXS7qBLCreaoVL-y-dXTKIcFZug7Mdr0jxb-xtBS3I,13008
|
|
105
|
+
mcp_hangar/infrastructure/auth/rate_limiter.py,sha256=sJobE79x8Ysl9pRk2UQ6CdFlFvH30G1hXdyEvOe7iVM,9445
|
|
106
|
+
mcp_hangar/infrastructure/auth/rbac_authorizer.py,sha256=zzyI9-2qOQwCsxmqZ7k4Qga7jilzL4moCPJBQPiMl1I,10907
|
|
107
|
+
mcp_hangar/infrastructure/auth/sqlite_store.py,sha256=TH6sTPUoHvmDFZBM9mT4FDKi6Lp00OSDnWDfvNLutz4,20141
|
|
108
|
+
mcp_hangar/infrastructure/discovery/__init__.py,sha256=u1r6ejA2V3P_0g3H-aW8KXIC9_I7osEJpxa2DOioeoY,3606
|
|
109
|
+
mcp_hangar/infrastructure/discovery/docker_source.py,sha256=6zy8kJ1fB4ep8x8HsX5Jicck8VdaQwVoE6G3Rm1gng4,10178
|
|
110
|
+
mcp_hangar/infrastructure/discovery/entrypoint_source.py,sha256=UpK8DQh73lxlkh1R6PLJcfsf8fhNOvZbANNkLKAWd0w,8039
|
|
111
|
+
mcp_hangar/infrastructure/discovery/filesystem_source.py,sha256=YJhbXsyIQ3qCL6f4DoV4C8SQae_no7R5rejEmjLOYwI,13051
|
|
112
|
+
mcp_hangar/infrastructure/discovery/kubernetes_source.py,sha256=icZTDxWkYJdo_waFLmYopar_38tTGxSoNcbT5LO2lt0,8416
|
|
113
|
+
mcp_hangar/infrastructure/knowledge_base/__init__.py,sha256=-J66cIgp3C6uMaFsGNX8Bhwj7B8IsXVMCJlOH1-VFkA,6278
|
|
114
|
+
mcp_hangar/infrastructure/knowledge_base/contracts.py,sha256=4YHknZoeZSD3Gf-1gv3yNhvi4-vH0NrV7Cj4jgAgX2c,5490
|
|
115
|
+
mcp_hangar/infrastructure/knowledge_base/memory.py,sha256=ZMuS8bPkbTUHsjtDtrKku3Xb0lZgwqFMr7F9_5vi9NQ,6452
|
|
116
|
+
mcp_hangar/infrastructure/knowledge_base/postgres.py,sha256=lG7jnyWaHSdyYdi7JV3jAdyKz463q-b1x9tMdbGtujk,18606
|
|
117
|
+
mcp_hangar/infrastructure/knowledge_base/sqlite.py,sha256=hydGbuPpkm4CCWLAmb4J6-YUhnIKptyGkSWEgeaosNA,18959
|
|
118
|
+
mcp_hangar/infrastructure/observability/__init__.py,sha256=S1_OyXK1vu37H73nGL-zaT-D4GsXyAWr5fxSpepmI_Y,280
|
|
119
|
+
mcp_hangar/infrastructure/observability/langfuse_adapter.py,sha256=aSFWJ3dyal0vBLoFNGbrdt_cnJarKzNo-az80nnR1ME,15956
|
|
120
|
+
mcp_hangar/infrastructure/persistence/__init__.py,sha256=UQS-GdQ2T-06aJGLUggyr7TRiT1OwaJjxWjn_XQtrmA,1127
|
|
121
|
+
mcp_hangar/infrastructure/persistence/audit_repository.py,sha256=k-CbZoMYziWzs4zBetXaEWdNYF21_i755N6YjTFRKHs,13197
|
|
122
|
+
mcp_hangar/infrastructure/persistence/config_repository.py,sha256=SYPSznnQEWS7zV4ZzllEU9vdJkZkMpnSFzhoWzlwRo4,14436
|
|
123
|
+
mcp_hangar/infrastructure/persistence/database.py,sha256=T5JxyVj7NQVQQvqAEspmvQF-VMjgo_QDGLfCMgpzCN0,10770
|
|
124
|
+
mcp_hangar/infrastructure/persistence/database_common.py,sha256=0JkDCm1Qh0UWLCr6JrGDyj2mP_yUa8nV7pAqhe5SgT0,10125
|
|
125
|
+
mcp_hangar/infrastructure/persistence/event_serializer.py,sha256=5geDs6OJaNPCEaUYGiT5VLGR-tVSnURUuRD1eRPo0uo,9186
|
|
126
|
+
mcp_hangar/infrastructure/persistence/event_upcaster.py,sha256=l4Z6ehFcAm8GSzfDoyMA2DBzgnOb4_ERMn5nLbYOkm0,5398
|
|
127
|
+
mcp_hangar/infrastructure/persistence/in_memory_event_store.py,sha256=iIWSdzlzGGBQRmR3fYKyFHnKqt2NOb9e-ffgmPSxkyI,4441
|
|
128
|
+
mcp_hangar/infrastructure/persistence/recovery_service.py,sha256=Br2R9i0bfOEmCwWjSbiHo43uWbM9ZQ5LYZBYl8Vmg4U,11285
|
|
129
|
+
mcp_hangar/infrastructure/persistence/sqlite_event_store.py,sha256=rIIsGm06OuCFIzOnSbyIRGD4IcZxF0RFFPEMu5NAB0Q,12592
|
|
130
|
+
mcp_hangar/infrastructure/persistence/unit_of_work.py,sha256=uBOEPj-DL_nYX-py-y2xRZGao1WpKzoQeCrPnhZ1nPM,14254
|
|
131
|
+
mcp_hangar/infrastructure/persistence/upcasters/README.md,sha256=Lv6UQd-92s8PFCAH4TZMe1vE2hfh8CazLli_kSJed9Q,423
|
|
132
|
+
mcp_hangar/infrastructure/persistence/upcasters/__init__.py,sha256=DE7Ji3B12B_4NRDjrOdtiIOxUAEQdJPHyq8uHm6BYxc,219
|
|
133
|
+
mcp_hangar/observability/__init__.py,sha256=1eA6pYl62p8-3DZ8xUgTJaxGrdH2NBJTqFzEOfSJklU,1367
|
|
134
|
+
mcp_hangar/observability/health.py,sha256=OAMLcEKIJTsTV8nek7TDQi3nmUDUMnble5nQWAcrzKc,14850
|
|
135
|
+
mcp_hangar/observability/metrics.py,sha256=KJW6_V3OkyA-YRJRojMAPPuF7u_jemnFj8VfDJpJbyU,11078
|
|
136
|
+
mcp_hangar/observability/tracing.py,sha256=DblzgfazPkNdw1cUX52xi5G6wnWOOmfJdrx8b9SdNso,12396
|
|
137
|
+
mcp_hangar/server/__init__.py,sha256=PiKvzbr5X73pm1Mlh4y5wQSt4O-F92uIgcvQDn6Rhbc,3065
|
|
138
|
+
mcp_hangar/server/__main__.py,sha256=iN63OrhJdpfow21HBWlwzeNd_6YSZM6EBiiccGjZPNA,125
|
|
139
|
+
mcp_hangar/server/auth_bootstrap.py,sha256=zT8e4lvNLGP5Z7OQrQQDhYBgYoGfAafdlbzIkTNlJ70,11895
|
|
140
|
+
mcp_hangar/server/auth_cli.py,sha256=VBc8icxD_Tvn7nIe5kVFsmK_FZ633G-rXncr0EeUA3w,9556
|
|
141
|
+
mcp_hangar/server/auth_config.py,sha256=McTckCRT3cJRSu5aHRYVCdpP5dLtDt2p6A0TOtOOoeo,9668
|
|
142
|
+
mcp_hangar/server/bootstrap.py,sha256=ASae8Hrgle8kc7AMDL6_Kan78m0CDLlEAyZZWWMg7nw,23527
|
|
143
|
+
mcp_hangar/server/cli.py,sha256=lvSgjoQHxgeAQ8ZZUGRwMJbqZdhvb1BBdG-O8jPtZ8s,4599
|
|
144
|
+
mcp_hangar/server/config.py,sha256=jjCfKoirGYWVoA06Givw5JanvwyusihcbI_eaHVwb9U,7476
|
|
145
|
+
mcp_hangar/server/context.py,sha256=Hkpt7br6YohTPZOeQdgofkxRDb7MympSLPXFBXOvOGo,6044
|
|
146
|
+
mcp_hangar/server/http_auth_middleware.py,sha256=qw_AJ3XKXGsIGfBsuSx4NatRoSL9ZXkK_f4gywAhUWg,5314
|
|
147
|
+
mcp_hangar/server/lifecycle.py,sha256=p5-XsUfZq3p3S_BXEfo-_rDLCgNuaTsPMCTgF8WOZEw,15501
|
|
148
|
+
mcp_hangar/server/state.py,sha256=6eu4T8YbcazC0IxAGfDsAtovjz67d4lRN-7kgzbjPWQ,3371
|
|
149
|
+
mcp_hangar/server/validation.py,sha256=CWAMH1f3vX2rtDGSbR0QobmzTITcoc-Lk6eXdSHrc0E,4147
|
|
150
|
+
mcp_hangar/server/tools/__init__.py,sha256=caw_sF6dCvb8_D3fKibCMbPAbDWO26GTdD2vHG9ilMM,451
|
|
151
|
+
mcp_hangar/server/tools/discovery.py,sha256=In0D-kjdBLs_vnxTBTZAmqMV05noGkdiPBNLHmfeoQc,6782
|
|
152
|
+
mcp_hangar/server/tools/groups.py,sha256=PbG2oZR-A3IbmaOKQt1mu3YURMXPf0XgOtRREeyZuIA,2394
|
|
153
|
+
mcp_hangar/server/tools/health.py,sha256=BlxpvVr2zmAD9uEofGpyuEebZbCVZUupio8sFE0YVGo,9797
|
|
154
|
+
mcp_hangar/server/tools/provider.py,sha256=3x77yL3SvQmYBSy7nj1Fqatv72QbLH9dIyTA8QY-2gE,33868
|
|
155
|
+
mcp_hangar/server/tools/registry.py,sha256=8eCAhyXl-4ulqTrbf6eKi8-rFMyTpd3DAELJcLnigZo,10945
|
|
156
|
+
mcp_hangar-0.2.0.dist-info/METADATA,sha256=4vQ9D8NzxxT4be86uGm6l6BxS2i_fDbLW2_c5DpJvpI,14989
|
|
157
|
+
mcp_hangar-0.2.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
158
|
+
mcp_hangar-0.2.0.dist-info/entry_points.txt,sha256=QhiABrAln7SDHqbjuiKrCba1dZm5TSfTdlhS9daVP6g,54
|
|
159
|
+
mcp_hangar-0.2.0.dist-info/licenses/LICENSE,sha256=iLTJSWkL_9c20HmudHptyYXFY_9qTF2Ee869oAT598U,1062
|
|
160
|
+
mcp_hangar-0.2.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 mapyr
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|