Content
# HCO — Hermes Code Operator
MIT License · v1.0.0

HCO is an MCP control plane that lets AI agents run Claude Code safely. It handles jobs, sessions, validation, and reporting through a single stdio server. No arbitrary shell. No credential handling. No destructive automation.
## What HCO does
HCO connects to any MCP client (Claude Code, Hermes Agent, or any other MCP host) and provides 11 tools:
- `hco_status` — system health, job counts, session info
- `hco_list_jobs` — list jobs, filter by status
- `hco_inspect_job` — full job detail with validations and approvals
- `hco_list_milestones` — milestone progress
- `hco_session_list` — list Claude Code sessions
- `hco_session_status` — session detail with event log
- `hco_session_wait` — wait for a session to finish
- `hco_session_stop` — abort a running session
- `hco_session_archive` — archive terminal session outputs
- `hco_session_start` — launch a Claude Code session
- `hco_task_start` — start a durable Claude Code task
Every tool has bounded input validation, output caps, and sanitized errors. Secrets are redacted before they reach the client.
## Architecture
```
src/
├── index.ts MCP server entrypoint
├── config/
│ ├── index.ts
│ └── schema.ts Zod config schema, loader, safe defaults
├── state/
│ ├── index.ts
│ └── db.ts SQLite migrations, WAL mode, FK pragmas
├── cli/
│ └── main.ts CLI: status, jobs, inspect, pause, resume, recover
├── daemon/
│ └── main.ts Daemon with systemd notify + job worker loop
├── core/
│ ├── index.ts
│ └── context.ts Shared AppContext (config + DB)
├── claude/
│ ├── launcher.ts Safe Claude Code process launcher
│ ├── runner.ts Process runner abstraction
│ └── session.ts Session CRUD and lifecycle
├── jobs/
│ ├── service.ts Job create, claim, renew, release
│ ├── worker.ts Durable worker loop with lease management
│ └── executor.ts Safe job-to-Claude executor
├── repos/
│ ├── service.ts Repository status (safe git read-only)
│ └── files.ts Repository file read (path validation)
├── validation/
│ ├── profile.ts Validation profile definitions
│ ├── runner.ts Fixed command profile runner
│ └── telegram.ts Report formatter with redaction
├── github/
│ └── policy.ts GitHub action allowlist and policy
├── reporting/
│ └── cli.ts CLI report integration
├── mcp/
│ ├── server.ts MCP stdio server, 11 tools
│ └── errors.ts Error types and output sanitization
├── deploy/
│ └── hco-mcp.service systemd unit template
tests/
├── claude.test.ts
├── cli.test.ts
├── config.test.ts
├── daemon.test.ts
├── db.test.ts
├── github-policy.test.ts
├── jobs-executor.test.ts
├── jobs-worker.test.ts
├── jobs.test.ts
├── mcp.test.ts
├── reporting-cli.test.ts
├── repos-files.test.ts
├── repos.test.ts
├── telegram-report.test.ts
├── validation-runner.test.ts
└── validation.test.ts
```
## Install
Requirements: Node.js 22 or later, npm 10 or later.
```bash
git clone https://github.com/nzkbuild/hco-mcp.git
cd hco-mcp
npm install
npm run build
```
The build produces compiled JavaScript in `dist/`. No additional native dependencies beyond what npm installs.
## Use with Hermes Agent
Paste this into your Hermes Agent chat to add HCO as an MCP server:
```
Add the HCO MCP server to my Hermes config. Use the npx command:
npx -y hco-mcp
The server uses stdio transport. Register all 11 tools. No additional config needed for read-only access.
```
Or configure manually in `~/.hermes/config.yaml`:
```yaml
mcp:
servers:
hco:
command: "npx"
args: ["-y", "hco-mcp"]
transport: "stdio"
```
## Use with Claude Code
Add to `.mcp.json` in your project root:
```json
{
"mcpServers": {
"hco": {
"command": "npx",
"args": ["-y", "hco-mcp"]
}
}
}
```
Restart Claude Code. Type `/mcp` to verify `hco` is connected with 11 tools.
## Uninstall
```bash
rm -rf hco-mcp
rm -rf ~/.hco
```
Remove the `hco` block from your MCP config file. No system-level files are modified outside the clone directory and `~/.hco`.
## Configuration
HCO looks for config in this order:
1. `./hco.json` (project local)
2. `~/.hco/config.json` (user global)
Environment variable overrides:
- `HCO_DATA_DIR` — SQLite and runtime data directory (default `~/.hco`)
- `HCO_TRANSPORT` — `stdio` (only supported transport)
- `HCO_LOG_LEVEL` — `debug`, `info`, `warn`, `error` (default `info`)
Example `~/.hco/config.json`:
```json
{
"dataDir": "/var/lib/hco",
"transport": "stdio",
"allowlist": [
{ "owner": "your-org", "repo": "your-repo", "trustLevel": "trusted" }
],
"authority": {
"mode": "interactive",
"requireApprovals": false
},
"logLevel": "info",
"maxConcurrency": 4
}
```
## CLI
```bash
hco status # System health and job summary
hco jobs # List recorded jobs
hco inspect <id> # Full job detail
hco pause <id> # Pause a running job
hco resume <id> # Resume a paused job
hco recover # Reset stuck running jobs
```
## Daemon
The daemon starts a durable worker loop that polls for queued jobs and launches Claude Code through the safe executor:
```bash
hco-daemon # Start daemon with job worker
```
When `NOTIFY_SOCKET` is set, the daemon signals systemd readiness (`READY=1`). Without systemd, it starts and waits for SIGTERM/SIGINT normally.
A systemd unit template is provided at `deploy/hco-mcp.service`.
## Develop
```bash
npm run dev # watch mode
npm run lint # eslint
npm run format # prettier check
npm run format:fix # prettier write
npm test # run all 126 tests
npm run build # compile TypeScript
npm run diff:check # verify no staged whitespace issues
```
## Safety boundaries
- **No secrets in events.** The events table stores structured payloads only. Tokens, keys, and credentials must not appear in event payloads or job inputs.
- **Bounded MCP tools.** All 11 tools have input validation with max lengths, output caps, and sanitized errors.
- **Repository allowlist.** Only explicitly listed repos can be operated on. Unknown repos are rejected.
- **No arbitrary execution.** The MCP server has no shell or exec capability. Claude Code is launched through fixed, validated spawn with shell disabled.
- **No destructive GitHub actions.** Publish, tag, release, deploy, billing, and secret rotation are permanently rejected by policy.
- **Path safety.** Repository file reads validate absolute paths, reject traversal (`..`), reject symlinks, and enforce byte caps.
## Version history
| Version | What changed |
|---------|-------------|
| 1.0.0 | Full MCP control plane: 11 tools, daemon worker loop, safe Claude executor, session lifecycle, validation profiles, GitHub policy, sanitized reporting |
| 0.1.0 | Initial foundation: MCP server with 4 read-only tools, SQLite store, CLI, config schema |
## License
MIT — see [LICENSE](./LICENSE).
Copyright (c) 2024 nzkbuild