# Connecting agent hosts Run `harbor install [--agent Name] [--project name --bind] [--dry-run | --uninstall]`. Every host gets three things: - **Harbor's MCP tools.** - **Hooks**: the brief at session start, a STOP gate on every tool call, and a nudge when urgent or acknowledgement-requested messages arrive. - **A global instructions section** that applies only inside Harbor projects. All hook commands are `py -3.12 -B /run.py --as hook --host `. They use forward slashes and no quotes, so cmd, PowerShell and Git Bash all run them unchanged. Decisions go back as Claude-compatible JSON at exit 0, because a host that runs the command through PowerShell would turn exit code 2 into 1: - before a tool: `permissionDecision: "deny"`; - at the end of a turn: `decision: "block"`. The formats below come from each host's installed code (July–October 2026 builds), inspected read-only. | Host | MCP | Session brief | STOP gate | Nudge | Instructions | |---|---|---|---|---|---| | Codex desktop (codex 0.159) | `~/.codex/config.toml` `[mcp_servers.harbor]` | `~/.codex/hooks.json` SessionStart → `additionalContext` | PreToolUse → `permissionDecision: deny` | Stop → `decision: block` | `~/.codex/AGENTS.md` | | OpenCode desktop (1.18) | `opencode.jsonc` `"mcp"` (`type: local`) | plugin, `session.created` → `client.session.prompt({noReply})` | plugin `tool.execute.before` throws | plugin, `session.idle` plus a 60 s check → `client.session.promptAsync` | `~/.config/opencode/AGENTS.md` | | DeepSeek Harness (0.2) | `~/.dsh/profiles/desktop/cordis.patch.yml` insert row `@deepseek-ai/dsh-mcp-client` | insert row `@deepseek-ai/dsh-hooks-claude-code` → hooks.json | PreToolUse | Stop | `~/.dsh/AGENTS.md` | | Kimi desktop (daimon 0.6) | personal plugin `kimi.plugin.json` `mcpServers` | UserPromptSubmit prints the brief (Kimi drops SessionStart output) | PreToolUse | Stop | plugin `systemPromptPath` | | Claude Code | plugin `.mcp.json` | plugin hooks SessionStart | PreToolUse | Stop | plugin skill | ## Notes per host **Codex** - Codex runs hooks only after you trust them: Settings → Hooks → Trust. It records that trust in `config.toml` itself. - Codex refuses hooks defined in both `config.toml` and `hooks.json`, so the installer refuses when a `[hooks]` table already exists. **OpenCode** - The plugin also wakes an idle session when a new message arrives for the agent: - it checks every 60 s; - it sends one nudge per batch of messages; - it never nudges while the agent is stopped. - Set `WAKE_IDLE_SESSIONS = false` at the top of `~/.config/opencode/plugin/harbor.js` to turn this off. - Restart OpenCode after installing. **DeepSeek Harness** - The MCP row hot-reloads. - The hooks file is read when the app starts, so restart the app once. - DeepSeek's bridge has no `stop_hook_active` guard. Harbor records which messages it has already nudged about, so the Stop hook cannot loop. **Kimi** - Kimi works from its own workspace folder, so its plugin is bound to one project (`harbor-`). - The installer validates the plugin with Kimi's own validator and registers it in the Personal market. - You install it from Plugins → Personal. Kimi asks you to review plugins that carry hooks. **Claude Code** - Add the plugin with `/plugin marketplace add /integrations/claude`, then `/plugin install harbor@harbor-local`. - Set `HARBOR_AGENT` in the session's environment. ## Waking a session that has ended Hooks only run while an agent's session is running. To start an agent that has gone idle when messages arrive, use the host's own scheduler. Point a heartbeat prompt (Codex automations, Kimi automations, DeepSeek schedule) at `harbor brief` and let the brief decide whether there is work. Harbor never creates schedules itself.