{
  "markdown": "# Myrmex Hive: Secure Agent Orchestrator & Gateway\n\nMyrmex Hive is a decentralized, secure, and geeky agent orchestration framework built on top of the **Model Context Protocol (MCP)**. It is designed to securely monitor, query, and manage distributed edge servers, Docker hosts, and Kubernetes nodes without exposing any ingress ports on your target systems.\n\n---\n\n## 1. Architecture & Security Model\n\nMyrmex Hive is designed for zero-trust environments where target edge systems (agents) must remain completely isolated from direct inbound network traffic.\n\n```mermaid\nflowchart TD\n    %% Node Definitions\n    subgraph Edge [\"Target Edge Node (Myrmex Agent)\"]\n        Agent[\"Myrmex Agent<br/>(CPU/Mem/Disk, strict allowlist)\"]\n    end\n\n    subgraph Gateway [\"Central Hive Gateway\"]\n        SSHD[\"Secure SSHD Receiver<br/>(Port 2222)\"]\n        Orch[\"Myrmex Hive Orchestrator\"]\n        LLM[\"Ollama LLM<br/>(Gemma 4/2)\"]\n    end\n\n    Client[\"Client / CLI / Portal<br/>(Stdio / SSE MCP Interface)\"]\n\n    %% Connections\n    Agent -- \"SSH Outbound Tunnel\" --> SSHD\n    SSHD -- \"JSON-RPC over SSH channel\" --> Orch\n    Orch <--> LLM\n    Client <--> Orch\n\n    %% Styling / Colors\n    classDef edgeNode fill:#282828,stroke:#fabd2f,stroke-width:2px,color:#ebdbb2;\n    classDef gatewayNode fill:#282828,stroke:#fe8019,stroke-width:2px,color:#ebdbb2;\n    classDef clientNode fill:#282828,stroke:#b8bb26,stroke-width:2px,color:#ebdbb2;\n\n    class Agent edgeNode;\n    class SSHD,Orch,LLM gatewayNode;\n    class Client clientNode;\n```\n\n### Security Principles (Why We Made These Choices)\n* **Zero Inbound Ports**: Instead of running an SSH daemon or exposing management ports (like HTTP/gRPC) on your target servers, the **Myrmex Agent** initiates a secure, outbound connection to the **Myrmex Gateway**. This eliminates the primary attack vector of public scanner discovery and automated brute-force attacks.\n* **OS-Grade Encryption**: Outbound tunnels utilize standard SSH protocol channels managed via Go's native `crypto/ssh` package, enforcing secure Ed25519 signature validation and high-grade ciphers (ChaCha20-Poly1305, AES-GCM).\n* **Defense-in-Depth Allowlist**: The Agent executes binaries directly via OS process forks (`os/exec`) rather than invoking a shell (like `/bin/sh` or `bash`). This completely bypasses shell expansion, neutralizing shell injection vulnerabilities. Arguments are strictly validated against developer-defined regular expressions in `config.json`.\n* **Central Token Authorization**: Access to the Gateway's control API is guarded via secure bearer token authentication.\n\n---\n\n## 2. Quickstart & Installation\n\nMyrmex Hive supports Go, Nix, Linux, macOS, and Windows environments.\n\n### Nix / NixOS (Declarative Flake)\nAdd Myrmex Hive to your `flake.nix` inputs:\n```nix\ninputs.myrmex-hive.url = \"github:olafkfreund/myrmex-hive\";\n```\n\nYou can then run the CLI tool directly:\n```bash\nnix run github:olafkfreund/myrmex-hive#myrmex -- --help\n```\n\nTo deploy a Myrmex Agent or Gateway as a declarative systemd service on NixOS, enable the module in your `configuration.nix`:\n```nix\n{ inputs, config, pkgs, ... }: {\n  imports = [ inputs.myrmex-hive.nixosModules.default ];\n\n  services.myrmex-hive = {\n    enable = true;\n    role = \"agent\"; # Or \"gateway\"\n    configPath = \"/etc/myrmex/agent_config.json\";\n  };\n}\n```\n\n### macOS (Homebrew)\n\n```bash\nbrew tap olafkfreund/myrmex\nbrew install --cask myrmex-hive\n```\n\nInstalls all three binaries: `myrmex` (operator CLI), `myrmex-gateway`, and `myrmex-agent`.\n\n*macOS only — Homebrew casks are not supported on Linuxbrew. On Linux use the deb/rpm packages from the [releases page](https://github.com/olafkfreund/myrmex-hive/releases), the Nix flake, `install.sh`, or the container images.*\n\n### Linux & macOS (Direct Install)\nTo download, compile, and configure the Agent as a background daemon (systemd on Linux, LaunchDaemon on macOS):\n```bash\nsudo ./install.sh\n```\n*The installer automatically compiles the agent binary, generates secure Ed25519 keys, writes the `config.json`, and boots the service.*\n\n### Windows (PowerShell Script)\nTo install the Agent on Windows Server or Windows 10/11, launch PowerShell as **Administrator** and run:\n```powershell\nSet-ExecutionPolicy Bypass -Scope Process -Force\n.\\install.ps1\n```\n*The PowerShell script compiles the binary, registers the agent configuration under `C:\\ProgramData\\mcp-agent\\`, generates OpenSSH keys, and schedules a background task to launch the agent at system startup.*\n\n### Kubernetes (Helm)\n\nVersioned container images and a Helm chart are published to GHCR on every release:\n\n```bash\nhelm install hive oci://ghcr.io/olafkfreund/charts/myrmex-hive \\\n  --version 1.2.0 \\\n  --namespace myrmex --create-namespace\n```\n\n`--version` pins the chart and the images together (v1.0.1+; v1.0.0 predates\nimage/chart publishing). See\n[docs/DEPLOYMENT.md](docs/DEPLOYMENT.md) for the image list, a working install\nwith agent keys, and the TLS/Service/`agent_id` caveats.\n\n---\n\n## 3. Configuration\n\n### Agent Configuration (`agent_config.json`)\nAllows you to define a single gateway or a list of multiple gateway addresses for High Availability (HA) failover cycling:\n```json\n{\n  \"agent_id\": \"agent-nginx\",\n  \"gateway_addr\": \"gateway-1.internal:2222\",\n  \"gateway_addrs\": [\n    \"gateway-1.internal:2222\",\n    \"gateway-2.internal:2222\"\n  ],\n  \"private_key_path\": \"/etc/mcp-agent/id_ed25519\",\n  \"allowed_commands\": [\n    {\n      \"name\": \"uptime\",\n      \"args_regex\": \"^$\"\n    },\n    {\n      \"name\": \"systemctl\",\n      \"args_regex\": \"^(status|restart) (nginx|postgresql)$\"\n    }\n  ]\n}\n```\n\n### Gateway Configuration (`gateway_config.json`)\nConfigures the receiver, TLS certs, OIDC/Tokens RBAC role mapping (`admin`, `operator`, `read-only`), and signed audit log path:\n```json\n{\n  \"listen_addr\": \":2222\",\n  \"http_addr\": \":8080\",\n  \"host_key_path\": \"host_key\",\n  \"authorized_keys_path\": \"authorized_keys\",\n  \"ollama_url\": \"http://localhost:11434\",\n  \"ollama_model\": \"gemma4:e4b\",\n  \"auth_token\": \"fallback_admin_token\",\n  \"tokens\": {\n    \"admin-token-123\": \"admin\",\n    \"operator-token-456\": \"operator\",\n    \"read-token-789\": \"read-only\"\n  },\n  \"audit_log_path\": \"audit.log\",\n  \"metrics_enabled\": true\n}\n```\n*Note: If `audit_log_path` is set, Myrmex Gateway records all `/api/call` and `/api/chat` executions alongside a cryptographic signature generated using the Gateway's private SSH host key.*\n\n*Note: `oidc_issuer` enables native OIDC/JWKS validation of real SSO tokens (opt-in; static tokens keep working alongside). See [docs/SECRETS.md](docs/SECRETS.md).*\n\n*Note: `metrics_enabled` exposes a Prometheus endpoint at `/metrics` (opt-in; behind the same bearer-token auth as the rest of the API). Myrmex Gateway can also route threshold alerts to a webhook/Alertmanager and export OpenTelemetry traces over OTLP — all opt-in. See [docs/OBSERVABILITY.md](docs/OBSERVABILITY.md) for the metric reference, a `scrape_config`, the Grafana dashboard, alert routing and tracing.*\n\n**Governance & scheduling (all opt-in, backward-compatible — empty/unset means off):**\n```json\n{\n  \"risk_tiers\": { \"run_command\": \"admin\", \"service_control\": \"write\" },\n  \"require_approval_tiers\": [\"write\", \"admin\"],\n  \"rate_limit_per_minute\": 30,\n  \"scheduled_tasks\": [\n    { \"name\": \"nightly-disk-check\", \"agent_id\": \"agent-nginx\",\n      \"prompt\": \"Report disk usage and flag anything over 85%\", \"interval_seconds\": 3600 }\n  ]\n}\n```\n- `risk_tiers` classifies each tool (`read`/`write`/`admin`). Built-in mutating tools (`service_control`, `run_command`) now default to a non-`read` tier even when unlisted, so they can't slip past gating unclassified; your explicit entries still override.\n- `require_approval_tiers` makes calls in those tiers wait for a second operator (`myrmex approvals`), and a new pending approval also **pages your configured alert targets** so it can't expire unnoticed. 15-minute TTL.\n- `rate_limit_per_minute` caps tool calls in a sliding 60-second window.\n- `scheduled_tasks` periodically run an LLM orchestration prompt against an agent and route the summary through the alerting subsystem — unattended fleet health checks. `interval_seconds` only (no cron).\n\nSee [Golden Path](docs/GOLDEN_PATH.md) for how these six gates fit together and a staged rollout.\n\n### Fail-closed defaults\n\nMyrmex Gateway **fails closed**: it refuses to start (or rejects a connection) rather than run in an insecure state. When preparing configs and keys, three rules are enforced:\n\n1. **`authorized_keys` comment = agent-id (identity binding).** The Gateway takes each connected agent's identity from the **comment** on its `authorized_keys` entry, and rejects any key whose comment is empty or does not match the `agent_id` the agent presents. Generate every agent key with its agent-id as the comment:\n   ```bash\n   ssh-keygen -t ed25519 -f id_ed25519 -N \"\" -C \"agent-nginx\"\n   ```\n   Then the public line in `authorized_keys` must keep that comment (`ssh-ed25519 AAAA... agent-nginx`).\n\n2. **Persistent `host_key_path` required when `audit_log_path` is set.** Audit entries are signed with the Gateway's SSH host key, so a transient (regenerated-on-restart) key would make past signatures unverifiable. The Gateway **refuses to start** if `audit_log_path` is set but `host_key_path` is empty. Generate a stable host key once and point `host_key_path` at it:\n   ```bash\n   ssh-keygen -t ed25519 -f host_key -N \"\" -C \"myrmex-gateway\"\n   ```\n   The Gateway also refuses to start without `authorized_keys_path` (no agent allowlist).\n\n3. **Agents verify the Gateway host key.** By default agents use **trust-on-first-use (TOFU)**: on first connect they learn and persist the Gateway host key to `<private_key_path>.gateway_hostkey` (override with `known_host_key_path`) and require a matching key thereafter — no config change needed. To pin explicitly instead, set `gateway_host_key` in `agent_config.json` to the Gateway host public-key line:\n   ```json\n   { \"gateway_host_key\": \"ssh-ed25519 AAAA... myrmex-gateway\" }\n   ```\n\nThe local test fixtures (`generate_keys.sh`, `setup_test_env.sh`) already satisfy all three: agent keys are commented with their agent-ids, a persistent `test_env/gateway/host_key` is generated and mounted, and agents rely on TOFU.\n\n---\n\n## 4. Local LLM Setup (Ollama & Gemma 4)\n\nMyrmex Hive orchestrates actions and interprets output using local LLMs.\n\n### Option A: Running as Docker Side-Services (Recommended)\nAn optional Docker setup is available via profiles in `docker-compose.test.yml` preloaded with the `gemma4:e4b` model (offline-ready):\n\n* **CPU-only mode**:\n  ```bash\n  docker compose --profile ollama-cpu up -d\n  ```\n* **GPU-accelerated mode** (requires NVIDIA Container Toolkit):\n  ```bash\n  docker compose --profile ollama-gpu up -d\n  ```\n\n### Option B: Manual Host Setup\n1. Install [Ollama](https://ollama.com/) on your Gateway server.\n2. Pull the desired model (Gemma 4):\n   ```bash\n   ollama pull gemma4:e4b\n   ```\n3. Ensure Ollama is running and accessible (default `http://localhost:11434`). Link it in `gateway_config.json`.\n\n---\n\n## 5. Using the Myrmex CLI (`myrmex`)\n\nThe Go-based Myrmex CLI allows operators to interact with the gateway, view agents, invoke tools, and launch the assistant directly from the terminal.\n\n### Global Options\n* `--url`: Gateway API base URL (default: `https://localhost:8080`)\n* `--token`: Gateway token (or `MYRMEX_TOKEN` environment variable)\n* `-o`, `--output`: Output format (`text` or `json`)\n\n### CLI Command Reference\n* **Status**: View connected edge agents and configured upstream servers:\n  ```bash\n  myrmex status\n  ```\n* **Agents**: List detailed specifications of all connected agents:\n  ```bash\n  myrmex agents\n  ```\n* **Tools**: List all available tools across the swarm:\n  ```bash\n  myrmex tools\n  ```\n* **Call**: Execute a tool on a specific agent. Automatically unmasks and un-escapes payloads:\n  ```bash\n  myrmex call agent-nginx__get_metrics\n  ```\n* **Call with JSON output**: Outputs a clean, raw JSON payload directly to stdout (perfect for piping to `jq`):\n  ```bash\n  myrmex call agent-nginx__get_metrics -o json | jq '.cpu_usage_percent'\n  ```\n* **Ask**: Prompt the Myrmex AI assistant to analyze and perform actions. Terminal output is beautifully styled in monospace markdown:\n  ```bash\n  myrmex ask \"Is nginx running on agent-nginx? If not, restart it.\"\n  ```\n* **Ask with JSON output**: Forward the final AI response directly to other automated tools or agents:\n  ```bash\n  myrmex ask \"Check system metrics\" -o json\n  ```\n* **Ask in plan (dry-run) mode**: The model is still consulted at every step, but no tool is executed — the response lists the calls it *would* have made. Use it to preview an action before trusting the loop:\n  ```bash\n  myrmex ask --plan \"Restart nginx on agent-nginx if it looks wedged\"\n  ```\n* **Fleet-wide orchestration**: Run the same orchestration across many agents and aggregate the per-agent summaries. Use `--all` for every connected agent or `--agents` for a subset (combine with `--plan` to preview fleet-wide):\n  ```bash\n  myrmex ask --all \"Report disk usage and flag anything over 85%\"\n  myrmex ask --agents agent-1,agent-2 \"How busy are these two?\"\n  ```\n\n---\n\n## 6. Real-Life Orchestration Scenarios\n\n### Scenario A: Automated Cluster Recovery\nAn operator issues a query:\n`myrmex ask \"Check load average on agent-db. If it's over 4.0, run diagnostic logs and let me know what process is consuming CPU.\"`\n1. The orchestrator calls `agent-db__get_metrics`.\n2. The orchestrator parses the returned metrics JSON.\n3. If the load is over `4.0`, the local Gemma model identifies that `agent-db__run_command` with argument `{\"cmd\":\"top\"}` (or an allowed diagnostics script) is available in the allowlist.\n4. The orchestrator executes the tool, parses the logs, and presents a clean, formatted report directly to the terminal.\n\n### Scenario B: Integration with Antigravity SDK\nYou can easily drive Myrmex Hive programmatically from other automated AI systems, such as **Antigravity SDK** agents. \nThe gateway exposes standard endpoints (`/api/chat` and `/api/call`) protected by the secure bearer token. Your Antigravity agents can query the endpoint, receive structured tool list payloads, and trigger actions over the SSH tunnel.\n\n### Scenario C: Airgapped Gemma 4 Setup & Cryptographic Auditing\nAn enterprise administrator configures a secure, fully compliance-audited local assistant using the offline-ready Ollama side-service:\n1. **Launch Ollama**: The administrator starts the preloaded CPU-only Gemma 4 side-service in Docker:\n   ```bash\n   docker compose --profile ollama-cpu up -d\n   ```\n2. **Configure Gateway**: In `gateway_config.json`, the gateway is linked to the Ollama endpoint:\n   ```json\n   \"ollama_url\": \"http://myrmex-ollama-cpu:11434\",\n   \"ollama_model\": \"gemma4:e4b\"\n   ```\n3. **Execute Operator Request**: An operator executes a compliance-audited CLI query:\n   ```bash\n   myrmex ask \"Verify the nginx server is running on agent-nginx\" --token \"operator-token-456\"\n   ```\n4. **Log & Verify Audit Event**: Since the request has write-like evaluation steps, the gateway logs a cryptographically signed entry in `audit.log` showing the timestamp, token role (`operator`), API route (`/api/chat`), and base64 signature. The security auditor verifies the log authenticity using the gateway's public SSH host key.\n\n### Scenario D: Testing and chaos-testing your own service\nA developer wants to run, break, observe and restart a service on a real host without SSHing in.\n1. **Allowlist the harness**, don't build a feature. Copy the entries from [`examples/service-test-harness/`](examples/service-test-harness/): a `chaos.sh` with a fixed verb set (`cpu`, `mem`, `latency`, `loss`, `kill`), probes pinned to hosts you name, and an apply script for config variants.\n2. **Verify recovery before breaking anything.** Restart the service through the Gateway first — if the restart path doesn't work, you have no business injecting a fault.\n3. **Inject and observe.** Faults are time-bounded and self-reverting, and return immediately so you can watch the effect while it happens:\n   ```bash\n   myrmex call web-1__run_command --arguments '{\"name\":\"/opt/myrmex/chaos.sh\",\"args\":[\"latency\",\"60\",\"250\",\"eth0\"]}'\n   # → latency: applied 250 on eth0, auto-reverts in 60s\n   ```\n4. **Get a record.** Every injection lands in the signed audit log, so a chaos run leaves tamper-evident evidence of which fault hit which host and when.\n\nFull guide: [docs/SERVICE_TESTING.md](docs/SERVICE_TESTING.md).\n\n---\n\n## 7. GCP Best Practices\n\nFor cloud deployments on Google Cloud Platform:\n1. **VM Isolation**: Deploy the Myrmex Gateway on a secure Compute Engine VM inside a private VPC. Expose the Gateway's control interface (`:8080`) only through **Identity-Aware Proxy (IAP)** to enforce IAM roles.\n2. **Kubernetes Agents**: Deploy Myrmex Agents on Google Kubernetes Engine (GKE) as a DaemonSet to automatically monitor and manage GKE node resources.\n3. **Secret Security**: Avoid storing the Gateway auth token in config files. Fetch the token dynamically at startup from **Google Secret Manager**.\n\n---\n\n## 8. Airgapped Datacenters\n\nIn highly secure, airgapped systems:\n* Myrmex Hive requires no public DNS or external internet access.\n* Deploy **Ollama** locally on the Gateway server. Since Ollama and the Myrmex Gateway run in the same local network, LLM inference occurs entirely within the airgapped perimeter.\n* Agents establish SSH tunnels internally over local subnets, maintaining a completely airgapped, auditable management plane.\n",
  "bytes": 17574,
  "sha": "8b69d64beca455169e610c698d2970e6f1855bd54fe2615d6eaf3bd2bf6dae7a",
  "repo_slug": "olafkfreund/myrmex-hive",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_olafkfreund_myrmex_hive_d7134fe3/readme"
}