Metadata-Version: 2.4
Name: mcp-host-agent
Version: 1.1.4
Summary: Host-level deployment and supervision agent for the MCP Worker platform: manage local Worker services (git/pip/systemd/launchd), health polling, heartbeat aggregation, and self-healing.
Author: Mavis AI Platform
License: Apache-2.0
Keywords: mcp,host-agent,worker,deployment,supervision,self-healing
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: mcp-worker-protocol>=1.1.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: httpx>=0.24.0
Requires-Dist: PyYAML>=6.0
Requires-Dist: fastapi>=0.100.0
Requires-Dist: uvicorn>=0.23.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: pytest-cov>=5.0; extra == "dev"
Requires-Dist: respx>=0.21; extra == "dev"
Requires-Dist: ruff>=0.4; extra == "dev"
Requires-Dist: build>=1.0; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"
Dynamic: license-file

# mcp-host-agent

<div align="center">

**The host-level deployment & supervision agent for the MCP Worker platform.**

Install once per host, manage every local Worker service end to end —
deployment, health polling, heartbeat aggregation, crash self-healing, and
Git-service-driven continuous delivery.

[![PyPI](https://img.shields.io/pypi/v/mcp-host-agent)](https://pypi.org/project/mcp-host-agent/)
[![Python](https://img.shields.io/pypi/pyversions/mcp-host-agent)](https://pypi.org/project/mcp-host-agent/)
[![License](https://img.shields.io/pypi/l/mcp-host-agent)](https://opensource.org/licenses/Apache-2.0)

</div>

---

## What this is

`mcp-host-agent` is a **system CLI you install** — not a Python project you write.
The thing you build is a **Worker** (a small
[`mcp-worker-sdk`](https://pypi.org/project/mcp-worker-sdk/) repo exposing
`/health /tools /execute /meta`). This CLI points at your Worker's Git repo and
does the clone / install / run / supervise / heal for you.

So no “worker directory structure” lives here — that belongs to
[`mcp-worker-sdk`](https://pypi.org/project/mcp-worker-sdk/).

## Built on

| Layer | Technology |
|-------|-----------|
| Runtime | Python 3.10+ |
| Control plane (HTTP API) | FastAPI + uvicorn |
| Worker deployment | subprocess — `git` / `pip` / `systemctl` / `launchctl` |
| Config & validation | pydantic + PyYAML |
| Hub / Worker polling | httpx |
| Shared protocol | [`mcp-worker-protocol`](https://pypi.org/project/mcp-worker-protocol/) |

---

## Why

Deploying MCP Workers by hand means writing the same `git clone + pip install +
systemctl restart + heartbeat + self-healing` glue every time — multiplied by the
number of Workers and hosts you manage. `mcp-host-agent` turns that glue into a
single, declarative, docker-style CLI.

- **One agent per host** manages **N Worker services**.
- **Coolify-like Git UX** — private/public Git repos plus push-to-deploy webhooks.
- **Rich three-tier health** — status, queue backpressure, and latency/reliability
  profile flow up to the Hub for smarter scheduling.
- **Self-healing** — process-level restart, rollback to the previous commit, and
  structured escalation.

---

## Install

```bash
pip install mcp-host-agent
```

Requires Python 3.10+.

---

## Quick start

```bash
# 1. Generate the config (--config defaults to /etc/mavis/agent.yaml).
mcp-host-agent config init --hub-url https://hub.example.com --agent-id agent-sandbox

# 2. Add a worker (writes back to agent.yaml atomically).
mcp-host-agent worker add --name demo-worker --repo https://git.example.com/owner/demo-worker.git --port 9101

# 3. Install as a system service: auto start-on-boot + crash-restart.
sudo mcp-host-agent deploy install-service

# 4. That's it — the agent is now running as a daemon.
```

Verify:

```bash
curl http://127.0.0.1:9200/health
curl http://127.0.0.1:9200/meta
curl -H "X-Agent-Token: <agent-token>" http://127.0.0.1:9200/api/v1/agent/status
```

> `deploy install-service` is the recommended production path (same philosophy as
> `docker`/`tailscale`: install → auto-enabled → boot + crash resilient). If you
> just want to run it in the foreground for a test, use `mcp-host-agent deploy run`.

---

## Adding more Workers

```bash
# Add a second worker, then hot-reload (no restart).
mcp-host-agent worker add --name neo4j-worker --repo https://git.example.com/owner/worker-neo4j.git --port 9102
mcp-host-agent deploy reload
```

> `--config` defaults to `/etc/mavis/agent.yaml`, so `deploy run` / `reload` /
> `status` / `worker ls` can all be invoked without repeating the path.

---

## Features

| Capability | Description |
|-----------|-------------|
| **Deployment** | `git clone/pull`, `pip install`, and `systemd`/`launchd` service management |
| **System service** | `deploy install-service` auto-enables and makes the agent boot/crash resilient |
| **Supervision** | Polls each Worker's `/health` + `/meta`, derives status, aggregates heartbeat |
| **Self-healing** | Decision tree: restart → rollback (`git checkout HEAD~1`) → give up + escalate |
| **Rich telemetry** | Forwards `degraded_reason`, `avg/p95` latency, `estimated_wait_ms`, `success_rate` through `Heartbeat.health` |
| **Git CD** | Gitea **and** GitHub webhook push-to-deploy with HMAC signature verification |
| **Private repos** | Credentials via `git_username` + `git_token_env` (token stays out of YAML) or the host credential helper |
| **Docker-style CLI** | `config / worker / deploy` grouped subcommands |
| **Hot reload** | `deploy reload` sends SIGHUP; newly added Workers bootstrap without a restart |

---

## Configuration

The agent is driven by a single `agent.yaml` (default `/etc/mavis/agent.yaml`):

```yaml
hub_url: "https://hub.example.com"
agent_id: "agent-sandbox"
jwt_token: "<jwt>"               # register with the Hub
agent_token: "<agent-token>"     # protect control endpoints
webhook_secret: "<webhook-secret>"  # Gitea/GitHub webhook signature

platform: linux                  # linux | macos
agent_port: 9200                 # control API port

workers:
  - name: sandbox-worker
    repo: "https://git.example.com/owner/worker-sandbox.git"
    branch: main
    port: 9101
    git_username: "will"         # private repo username
    git_token_env: "GITEA_TOKEN" # token read from env, never written to YAML
    # self-healing defaults (overridable by Worker /meta.recovery)
    auto_restart: true
    max_restart: 3
    restart_interval: 5
    fail_threshold: 3
    graceful_timeout: 10

  - name: neo4j-worker
    repo: "https://git.example.com/owner/worker-neo4j.git"
    port: 9102
```

> The token referenced by `git_token_env` is read from the environment at clone
> time and is **not** persisted to disk. If both `git_username` and
> `git_token_env` are omitted, the host's own Git credential helper (or SSH
> config) is used.

---

## Set up push-to-deploy (Gitea / GitHub)

1. Point your webhook at the agent:

   - Payload URL: `http://<host-agent-ip>:9200/webhook`
   - Content type: `application/json`
   - Secret: the same value as `webhook_secret` in `agent.yaml`

2. **Gitea** — enable “Push” events.
3. **GitHub** — enable “Just the push event”.

Every push with a valid signature triggers `git pull → pip install → service
restart` and reports commit status back.

---

## Supported platforms

| Platform | Runner | System service |
|----------|--------|----------------|
| Linux | systemd | `mavis-agent.service` |
| macOS | launchd | `mavis.agent.plist` |

> Windows is not supported in v1. The agent manages **native host processes**
> (systemd/launchd). Containers such as Docker/K3s pods are self-healed by their
> own orchestrators, not by the agent.

---

## Programmatic API

```python
from mcp_host_agent import (
    AgentConfig,
    WorkerConfig,
    WorkerManager,
    Supervisor,
    create_app,
)

config = AgentConfig(
    hub_url="https://hub.example.com",
    agent_id="agent-sandbox",
    jwt_token="<jwt>",
    workers=[WorkerConfig(name="demo", repo="https://git.example.com/o/demo.git", port=9101)],
)

manager = WorkerManager(config)
manager.ensure_cloned(config.workers[0])
manager.install_deps(config.workers[0])
manager.start(config.workers[0])

supervisor = Supervisor(config, manager)
supervisor.poll_all()
heartbeats = supervisor.build_heartbeats("2026-08-16T00:00:00+00:00")

app = create_app(config, supervisor, manager)  # FastAPI control plane
```

See the full integration guide at
[`docs/mcp-host-agent/DELIVERY_INTEGRATION.md`](docs/mcp-host-agent/DELIVERY_INTEGRATION.md)
and the CLI reference at
[`docs/mcp-host-agent/CLI_REFERENCE.md`](docs/mcp-host-agent/CLI_REFERENCE.md).

---

## Development

```bash
pip install -e ".[dev]"
pytest            # unit + integration + contract + compatibility
ruff check .
```

---

## License

[Apache-2.0](LICENSE)
