Orchestrate many agents as one — run them on your device, command them from anywhere.
agent-phonon is a device-side daemon that discovers local AI coding agents (Claude Code, Codex, GitHub Copilot CLI, OpenCode, OpenClaw, Hermes, and more) and exposes them to a server through one uniform WebSocket/JSON protocol.
The name comes from the phonon in condensed-matter physics: a collective quasiparticle that emerges when many atoms vibrate together. Individual agents act alone; orchestrated together they become one system. More is different.
Local AI agents are powerful but siloed. Each has a different CLI, session model, streaming format, model switch mechanism, and set of capabilities. agent-phonon puts a small daemon in front of them so a server can:
- discover which agents and models are available on a device,
- create/send/interrupt/terminate sessions through one protocol,
- stream output and receive unsolicited/proactive agent output,
- manage projects, worktrees, skills, files, env vars, and HITL hooks,
- orchestrate many devices while each device still enforces its own local policy,
- keep a built-in
phonon-rescuerecovery agent and deterministic maintenance plane available even when every external agent is broken.
Adapters declare their real capabilities; agent-phonon does not pretend every agent works the same way.
server(s) your device(s)
┌────────────────┐ wire protocol ┌────────────────────────────┐
│ server SDK │◄─────WS / JSON────►│ phonon daemon (core) │
│ (TS / Python) │ │ ├─ adapter: OpenClaw │
│ console / app │ │ ├─ adapter: Claude Code │
└────────────────┘ │ ├─ adapter: Codex │
│ ├─ adapter: Copilot CLI │
│ ├─ adapter: OpenCode │
│ └─ adapter: Hermes │
└────────────────────────────┘
| Directory | Published package | For |
|---|---|---|
packages/daemon |
agent-phonon (npm) |
Device daemon / CLI |
packages/protocol |
@agent-phonon/protocol (npm) |
Protocol types and zod schemas |
packages/sdk-server-ts |
@agent-phonon/server-sdk (npm) |
TypeScript/Node server SDK |
sdk-python |
agent-phonon-sdk (PyPI) |
Python server SDK |
@agent-phonon/core is bundled into the daemon package and is not published as a
separate runtime dependency. Console/test/plugin packages are kept in the repo
for development and integration testing.
- Node.js >= 22.5
- npm or pnpm
- Optional local agents:
- Claude Code:
claude - Codex CLI:
codex - GitHub Copilot CLI:
copilot - OpenCode:
opencode - Hermes:
hermes - OpenClaw Gateway/plugin for OpenClaw integration
- Claude Code:
Linux service management currently targets systemd --user. macOS launchd and Windows service support are planned separately.
npm install -g agent-phonon
agent-phonon --helpInitialize local config:
agent-phonon initThe config file is created at:
~/.agent-phonon/config.json
It contains the device id, local database path, adapter overrides, server connections, and local policy. Secrets are redacted by default when printed:
agent-phonon config
agent-phonon config --show-secrets # only when you really need itIf your server gives you a WebSocket URL and device key:
agent-phonon server add wss://your-server.example/phonon --device-key <device-key>For local development only, you can mark a server as trusted-local:
agent-phonon server add ws://127.0.0.1:4317/phonon --trust-localList configured servers:
agent-phonon server listInstall the systemd user unit:
agent-phonon service installStart it:
agent-phonon service startUseful service commands:
agent-phonon service status
agent-phonon service restart
agent-phonon service stop
agent-phonon service uninstallservice install writes:
~/.config/systemd/user/agent-phonon.service
and runs:
systemctl --user daemon-reload
systemctl --user enable agent-phonon.serviceIt does not start the daemon until you explicitly run service start.
If the daemon should run after logout on a Linux server, you may need to enable linger for your user:
loginctl enable-linger "$USER"For debugging or non-systemd environments:
agent-phonon startRun:
agent-phonon doctor
agent-phonon discoverdoctor checks whether local CLIs and integrations are available. discover
returns normalized agent descriptors, including available models and declared
capabilities.
Adapter auto-detection is conservative:
- CLI availability is checked by executing each CLI's version command.
- Commands are resolved to absolute paths when possible, so systemd/launchd PATH differences do not hide globally installed CLIs.
- Codex models are discovered from the user's Codex config provider endpoint
(
GET <base_url>/models) when available, with safe fallback models. - GitHub Copilot CLI models are parsed from
copilot help config; the adapter uses JSONL streaming and native named-session resume. - Hermes models are discovered from Hermes profile/config/catalog information with provider fallbacks when the catalog is incomplete.
- No user-specific provider names, endpoints, or local machine paths are hard-coded.
phonon-rescue is built into the daemon. It does not depend on OpenClaw,
Claude Code, Codex, Copilot, OpenCode, or Hermes. Configure any endpoint that
supports OpenAI Chat Completions plus tool calling:
agent-phonon rescue configure \
--base-url https://your-endpoint.example/v1 \
--model your-tool-capable-model \
--api-key-ref ~/.agent-phonon/rescue.keyThe CLI probes Chat Completions and tool calling before saving. --api-key-env
or --api-key are also supported; a 0600 key file is recommended for a
background service.
The rescue agent has no arbitrary shell or host filesystem tool. It can only
invoke locally registered semantic maintenance operations. The same operations
are also exposed directly through the server SDK as device.maintenance.*, so
recovery still works when the rescue model endpoint is unavailable:
- inventory and diagnostics,
- redacted JSON config reads,
- optimistic-lock JSON merge patch with automatic backup,
- checksum-verified rollback,
- allowlisted user-level npm/pnpm package updates,
- allowlisted user-service status and restart.
All maintenance capabilities are controlled by independent device policy flags
and default to off. trustLocal does not enable host maintenance;
each server must opt in explicitly with its local policy. Raw paths, package names, service names,
and shell strings are never accepted over the wire.
Most users should rely on auto-detection. Add an adapter override only when you need to force a path/model/provider:
agent-phonon adapter add codex --bin /path/to/codex --model default
agent-phonon adapter add claude-code --bin /path/to/claude --model default
agent-phonon adapter add copilot --bin /path/to/copilot --model default
agent-phonon adapter add hermes --bin /path/to/hermes
agent-phonon adapter add opencode --bin /path/to/opencodeOpenClaw integration:
agent-phonon plugin install openclaw
agent-phonon adapter add openclaw --agent mainnpm install @agent-phonon/server-sdkimport { PhononServer } from "@agent-phonon/server-sdk";
const server = new PhononServer({ port: 4317 });
server.listen();pip install agent-phonon-sdkfrom agent_phonon import PhononServer
server = PhononServer(port=4317)
server.run()pnpm install
pnpm run consistency
pnpm -r build
pnpm -r testBefore committing or tagging releases, install the project git hook:
pnpm run install-hooksRelease guardrails live in:
AGENTS.mddocs/COMMIT_RELEASE_CHECKLIST.mdscripts/check-consistency.mjsscripts/release-guard.mjs
- Wire protocol
- L3 orchestration protocol
- Design decisions
- Agent CLI integration
- Release checklist
- Security
agent-phonon is a remote control plane for local agents. The local device owner is the authorization boundary. Filesystem access is policy-gated, secrets are redacted by default and encrypted at rest where stored by phonon, and dangerous operations are denied unless local policy explicitly allows them.
MIT © agent-phonon contributors