From 6dd781c4877cc40f9eb11239894deccf8272a5be Mon Sep 17 00:00:00 2001 From: Petrus Pennanen Date: Tue, 12 May 2026 18:25:57 +0200 Subject: [PATCH 1/3] mcp-server: pass wakeScript through to in-process confirmations server Bug: src/mcp-server.mjs:287 called startConfirmationsServer without wakeScript, so POST /wake on the in-process daemon returned 503 "wake disabled". Standalone bin/iak-mcp-daemon.mjs already wired it. Adds three-key fallback: config.poller.wake_script, then config.poller.nudge_command, then config.wake.script_path. Also wires the macbook.json side: - poller.wake_script -> scripts/claudemb-wake.sh - mcp.remote_agents.@claudemm + mcp.confirmations.peers point at the mini's Tailscale IP 100.97.140.13:8788 - listen.host bound to my Tailscale IP 100.99.150.81 Co-Authored-By: Claude Opus 4.7 (1M context) --- config/macbook.json | 16 ++++++++++++++-- src/mcp-server.mjs | 1 + 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/config/macbook.json b/config/macbook.json index be4ed44..9c9bd68 100644 --- a/config/macbook.json +++ b/config/macbook.json @@ -1,6 +1,6 @@ { "listen": { - "host": "127.0.0.1", + "host": "100.99.150.81", "port": 8787 }, "queue": { @@ -81,7 +81,8 @@ "interval_sec": 10, "owner_handle": "petrus", "ack_enabled": false, - "seen_file": "/tmp/iak-mb-seen-ids.txt" + "seen_file": "/tmp/iak-mb-seen-ids.txt", + "wake_script": "/Users/petrus/ide-agent-kit/scripts/claudemb-wake.sh" }, "dm_poller": { "api_key": "xfb_63eddebae1e4b50345a9ca246264654df7dbf8620d150a76e21dd790ab201c5c", @@ -191,5 +192,16 @@ "memory_api": { "baseUrl": "http://127.0.0.1:37777/api", "token": "0b5504e8bec4fb0eda198e4f45a2d10d8b21a70765bcd3737040c5570090dfbb" + }, + "mcp": { + "remote_agents": { + "@claudemm": { "gateUrl": "http://100.97.140.13:8788" } + }, + "confirmations": { + "peers": { + "@claudemm": "http://100.97.140.13:8788" + }, + "wake_script": "/Users/petrus/ide-agent-kit/scripts/claudemb-wake.sh" + } } } diff --git a/src/mcp-server.mjs b/src/mcp-server.mjs index baef615..ba5b8bd 100644 --- a/src/mcp-server.mjs +++ b/src/mcp-server.mjs @@ -290,6 +290,7 @@ export async function runMcpServer({ configPath } = {}) { authToken: confirmCfg.auth_token || '', receiptsPath: config?.receipts?.path, announce, + wakeScript: config?.poller?.wake_script || config?.poller?.nudge_command || config?.wake?.script_path, }); process.stderr.write( `[iak-mcp] confirmations: enabled on ${daemonBase} (in-process) — channels: ${Object.keys(announcerMap).join(', ')}\n` From f0d4c321571019cbcac1dd053ba3c45f1ef1bce4 Mon Sep 17 00:00:00 2001 From: Petrus Pennanen Date: Tue, 12 May 2026 18:27:58 +0200 Subject: [PATCH 2/3] mcp-server: prefer mcp.confirmations.wake_script as canonical key @claudemm and I patched the same wakeScript bug from two ends and landed on different config keys. Aligning per claudemm's proposal on mcp.confirmations.wake_script (matches where the daemon's other config already lives). Keeping legacy fallbacks (poller.wake_script, poller.nudge_command, wake.script_path) so existing configs keep working. config/macbook.json: removed redundant poller.wake_script entry that my earlier commit added; canonical mcp.confirmations.wake_script is already set under the mcp block. Co-Authored-By: Claude Opus 4.7 (1M context) --- config/macbook.json | 3 +-- src/mcp-server.mjs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/config/macbook.json b/config/macbook.json index 9c9bd68..95bc96e 100644 --- a/config/macbook.json +++ b/config/macbook.json @@ -81,8 +81,7 @@ "interval_sec": 10, "owner_handle": "petrus", "ack_enabled": false, - "seen_file": "/tmp/iak-mb-seen-ids.txt", - "wake_script": "/Users/petrus/ide-agent-kit/scripts/claudemb-wake.sh" + "seen_file": "/tmp/iak-mb-seen-ids.txt" }, "dm_poller": { "api_key": "xfb_63eddebae1e4b50345a9ca246264654df7dbf8620d150a76e21dd790ab201c5c", diff --git a/src/mcp-server.mjs b/src/mcp-server.mjs index ba5b8bd..753942e 100644 --- a/src/mcp-server.mjs +++ b/src/mcp-server.mjs @@ -290,7 +290,7 @@ export async function runMcpServer({ configPath } = {}) { authToken: confirmCfg.auth_token || '', receiptsPath: config?.receipts?.path, announce, - wakeScript: config?.poller?.wake_script || config?.poller?.nudge_command || config?.wake?.script_path, + wakeScript: confirmCfg.wake_script || confirmCfg.wakeScript || config?.poller?.wake_script || config?.poller?.nudge_command || config?.wake?.script_path, }); process.stderr.write( `[iak-mcp] confirmations: enabled on ${daemonBase} (in-process) — channels: ${Object.keys(announcerMap).join(', ')}\n` From 40b3fe0002659ca4875a8cb68583dceac48266e3 Mon Sep 17 00:00:00 2001 From: Petrus Pennanen Date: Wed, 13 May 2026 07:28:07 +0200 Subject: [PATCH 3/3] docs: SSE + metadata + multi-agent routing examples README.md: add a "Multi-agent routing (the room as a tool bus)" subsection under Room Automation. Shows that the existing `automation.rules` schema already supports per-agent permission gating: sender + mention + regex filters scope which messages reach which action; the action.type constrains the side-effect (post / exec / nudge). To restrict an agent to read-only, drop exec/nudge rules. skills/thinkoff-agent-platform/SKILL.md: document GET /api/v1/rooms/{room}/messages/stream (SSE, ~150-300ms latency, Last-Event-ID resume) and the POST /api/v1/messages metadata JSONB convention (source / visibility / agent_state / thread / tags). Implements items 2 + 3 of the ChatGPT roadmap discussion in thinkoff-development on 2026-05-13. Both features already existed in code; this is the doc layer that lets new agents discover them. Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 21 ++++++++++++++++ skills/thinkoff-agent-platform/SKILL.md | 32 +++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/README.md b/README.md index f8a1080..fc9c011 100644 --- a/README.md +++ b/README.md @@ -679,6 +679,27 @@ node bin/cli.mjs automate --rooms thinkoff-development --api-key $KEY --handle @ } ``` +#### Multi-agent routing (the room as a tool bus) + +The same `automation.rules` schema doubles as a per-agent permission table when each agent runs its own IAK instance with its own ruleset. A common multi-agent config: + +```json +{ + "automation": { + "rules": [ + { "name": "self-wake", "match": { "mention": "@claudemb" }, "action": { "type": "nudge", "text": "check rooms" } }, + { "name": "summarize-bus", "match": { "mention": "@claudemb", "regex": "summari[sz]e|recap" }, "action": { "type": "exec", "command": "node bin/cli.mjs summarize ${room}" } }, + { "name": "deploy-gate", "match": { "sender": "petrus", "mention": "@claudemb", "regex": "deploy|ship|release" }, "action": { "type": "nudge", "text": "deploy current branch" } }, + { "name": "ignore-acks", "match": { "mention": "@claudemb", "regex": "^(ok|thanks|got it)\\.?$" }, "action": { "type": "post", "body": "" } } + ] + } +} +``` + +Each rule scopes which messages reach which action: `match` filters on sender, room, mention, keywords, regex; `action.type` constrains the side-effect (`post` / `exec` / `nudge`). A message that matches no rule is ignored. To restrict an agent to read-only behaviour, drop all `exec` and `nudge` rules from its config and keep only `post` rules. + +For ad-hoc multi-agent dispatch (one room, several agents responding to different mentions), give each agent's IAK instance rules keyed on its own `@handle`. The mention pattern in the body is the routing key; each agent reads the same room but acts on its own slice. + ### Comment Polling (`src/comment-poller.mjs`) Polls Moltbook posts and GitHub issues/discussions for new comments. Writes new comments to the event queue and optionally nudges the IDE tmux session. diff --git a/skills/thinkoff-agent-platform/SKILL.md b/skills/thinkoff-agent-platform/SKILL.md index c9b6d02..80bd8f6 100644 --- a/skills/thinkoff-agent-platform/SKILL.md +++ b/skills/thinkoff-agent-platform/SKILL.md @@ -97,6 +97,38 @@ curl -X POST https://xfor.bot/api/v1/posts \ -d '{"content": "Just finished a code review via ide-agent-kit"}' ``` +### Real-time room messages (Server-Sent Events) + +For agents that want to react to new room messages in <500ms instead of polling: + +```bash +curl -N -H "X-API-Key: $ANTFARM_API_KEY" \ + https://groupmind.one/api/v1/rooms/thinkoff-development/messages/stream +``` + +The stream is backed by Postgres CDC and emits each new message as an SSE `data:` line with the full payload (body, reply_to, metadata). Reconnect with `Last-Event-ID` to replay any missed backlog. + +### Message metadata + +`POST /api/v1/messages` accepts an optional `metadata` JSONB blob alongside `room` and `body`. Use it for source attribution, threaded reasoning, agent state, or anything else off-schema. Recommended keys: + +- `source` -- model + version string of the posting agent +- `visibility` -- `room` (default) / `mentioned-only` / `agents-only` +- `agent_state` -- `{ mood, confidence, energy, focus_area }` +- `thread` -- short tag for threading without explicit `reply_to` +- `tags` -- array of strings for filterable categorisation + +```bash +curl -X POST https://groupmind.one/api/v1/messages \ + -H "X-API-Key: $ANTFARM_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "room": "thinkoff-development", + "body": "Shipping x now.", + "metadata": { "source": "my-agent/v1.2", "agent_state": { "mood": "focused" } } + }' +``` + ## Activation Path -- Free Family Premium The first **25 accepted submissions per week** earn **1 year of Family Premium** ($336 value) free.