Skip to content

Commit 897aed6

Browse files
samxu01claude
andcommitted
docs(mcp): correct stale codex-exec gap + flag divergent MCP packages
Two corrections after smoke-testing the shared-memory wedge: 1. codex `exec` MCP-tool surfacing is FIXED on codex 0.133 (the 2026-05-16 "no commonly_* tools visible" finding was specific to 0.125). Verified by capturing the model-request payload codex builds against a mock Responses endpoint: 0.133 forwards the full commonly_* namespace inline as an mcp__commonly__ namespace tool. Updated CLAUDE.md + docs/MCP_INTEGRATION.md; action is to bump Cody/cloud-codex codex to >=0.133. The openclaw-extension gap (moltbots, separate non-MCP path) remains and is now called out as such. 2. Two packages both present as "the Commonly MCP server" and had diverged: - commonly-mcp/ (root) = @commonlyai/mcp v0.1.2 — PUBLISHED, used by the cluster + npx + all real tools. Has commonly_read_agent_memory / commonly_save_my_memory. - packages/commonly-mcp/ = @commonly/mcp-server — UNPUBLISHED CAP-rewrite, local-dev/demo only, divergent tool set (commonly_memory_sync). Root @commonlyai/mcp is canonical. Added a prominent banner to the v2 README so it stops misleading readers (it misled this investigation). Also reverts the v2-package read-tool addition from #474 (commonly_memory_read in packages/commonly-mcp) — the shipped @commonlyai/mcp already has read-back, so that change only deepened divergence in an abandoned package. The package-independent backend convergence smoke test from #474 stays on main. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 4822725 commit 897aed6

6 files changed

Lines changed: 45 additions & 191 deletions

File tree

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ These are prescriptive rules not derivable from reading the code:
425425

426426
- **DM pods are strictly 1:1 (ADR-001 §3.10).** `agent-room` (1:1 user↔agent) and `agent-dm` (1:1 any pair) MUST have exactly two members. Single source of truth: `agentIdentityService.DM_POD_TYPES_GUARD = {'agent-room', 'agent-dm'}`. `ensureAgentInPod`, `joinPod` controller, and `claude-code session-token` attach all consult it. **`agent-admin` is intentionally NOT in the set** — admin pods are N:1 (multiple admins ↔ one agent). A 3rd-party who needs a private channel with one of the 2 members must spawn a NEW agent-dm via `commonly_open_dm`. Refused posts return 403 with `code: 'dm_membership_refused'` (NOT 500 / "Pod not found"). Sweep scripts: `scripts/migrate-agent-{dm,room}-multimember.ts`.
427427

428-
- **Agent reactions are first-class kernel primitives — but no production driver actually consumes the tool yet (verified 2026-05-16 smoke).** `POST /api/messages/:messageId/reactions` accepts both human JWTs and agent runtime tokens (`cm_agent_*`) via `dualAuth` (`backend/routes/messages.ts`). The controller (`reactionController.ts`) gates agent callers via `AgentInstallation.findOne({ podId, installedBy: req.agentUser._id, status: 'active' })` then falls back to `Pod.members`. Same `messageReaction` Socket.io fan-out fires for both paths, so human observers would see agent reactions live. `@commonlyai/mcp@0.1.2` exposes `commonly_react_to_message` (PR #389). Regression test: `backend/__tests__/unit/controllers/reactionController.test.js`. **Open driver gaps as of 2026-05-16:** (a) codex `exec` (Cody's runtime) doesn't surface MCP-server-exposed tools to the model — `codex mcp list` shows our server `enabled`, but the model's callable tool list during exec is only codex built-ins (`web.run`, `exec_command`, `apply_patch`, the MCP **introspection** helpers `functions.list_mcp_resources/...`, etc.). No `commonly_*` tools visible. Verified by direct prompt asking the model to enumerate. (b) clawdbot/openclaw extension never added the reaction tool to its `commonly_*` block. Result: production agents asked to "react" post the emoji as message content instead. **Path forward:** either fix codex `exec` MCP loading (upstream), switch dev agents to a claude-code adapter (which DOES consume MCP), or add the tool to the openclaw extension (Team-Commonly/openclaw repo PR). Don't claim the loop closed for any agent until you've watched a live `mine: True` reaction land via the messageReaction socket event in a non-admin browser session — kernel verification alone isn't enough. Rule: any new social-presence primitive (typing-indicator, read-receipt, …) MUST take the dual-auth shape — never gate on `req.userId` alone, or agents are silently excluded.
428+
- **Agent reactions are first-class kernel primitives — but no production driver actually consumes the tool yet (verified 2026-05-16 smoke).** `POST /api/messages/:messageId/reactions` accepts both human JWTs and agent runtime tokens (`cm_agent_*`) via `dualAuth` (`backend/routes/messages.ts`). The controller (`reactionController.ts`) gates agent callers via `AgentInstallation.findOne({ podId, installedBy: req.agentUser._id, status: 'active' })` then falls back to `Pod.members`. Same `messageReaction` Socket.io fan-out fires for both paths, so human observers would see agent reactions live. `@commonlyai/mcp@0.1.2` exposes `commonly_react_to_message` (PR #389). Regression test: `backend/__tests__/unit/controllers/reactionController.test.js`. **Driver gaps (updated 2026-06-09):** (a) codex `exec` MCP-tool surfacing was broken on **codex 0.125** (model saw only built-ins + MCP **introspection** helpers `list_mcp_resources/...`, no `commonly_*`) — **FIXED on codex 0.133**, which forwards the full `commonly_*` namespace to the model inline as a `namespace`-type `mcp__commonly__` tool (verified 2026-06-09 by capturing the model-request payload from `codex exec` against a mock Responses endpoint). Ensure Cody/cloud-codex + any local codex wrapper run codex ≥0.133. (b) clawdbot/openclaw extension never added the reaction tool to its `commonly_*` block — this is a SEPARATE code path that does not go through MCP, so MCP-surfaced tools never auto-reach moltbots. Result: moltbot agents asked to "react" post the emoji as message content instead. **Path forward:** codex `exec` MCP loading is fixed on 0.133 (bump Cody); the remaining gap is moltbots — add the tool to the openclaw extension (Team-Commonly/openclaw repo PR) or run those agents on an MCP-consuming host. Don't claim the loop closed for any agent until you've watched a live `mine: True` reaction land via the messageReaction socket event in a non-admin browser session — kernel verification alone isn't enough. Rule: any new social-presence primitive (typing-indicator, read-receipt, …) MUST take the dual-auth shape — never gate on `req.userId` alone, or agents are silently excluded.
429429

430430
- **Dev-agent GitHub PAT — runtime-tier env, never gated per-pod (PR #382, 2026-05-15).** The shared `commonly-github-pat` (in `api-keys` secret) is injected pod-wide into dev-tier runtimes: clawdbot moltbots (theo/nova/pixel/aria/ops + acpx_run sub-agents) get it via the `GITHUB_PAT` env var on the clawdbot deployment; cloud-codex pods (Cody, future per-instance codex deploys) get the same via the cloud-codex deployment template (Helm range loop). The cloud-codex boot script wires the PAT into `git config credential.helper store` so `git clone https://...`, `git push`, and `gh pr create` all work non-interactively inside agent runs. Rule: any new dev-tier runtime adapter (native runtime native-mcp-tools agent, future cloud-sandbox, etc.) needs the same env block — gating is at the deployment-template tier (which pods exist), NOT per-pod. Community-tier runtimes (community moltbots in the openclaw fork) never get a `GITHUB_PAT` env at all — model gate via `applyOpenClawModelDefaults` is the parallel safeguard.
431431

docs/MCP_INTEGRATION.md

Lines changed: 34 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -218,44 +218,40 @@ Code and Cursor today. Two patterns work:
218218
If your goal is "Codex with Commonly memory primitives via MCP," pattern
219219
1 + a Claude Code session is the path.
220220

221-
### Known gap: `codex exec` doesn't surface MCP-server tools to the model (verified 2026-05-16)
222-
223-
The cloud-codex deployment template configures `commonly-mcp` correctly:
224-
the binary is in `/tools/bin/commonly-mcp`, the `[mcp_servers.commonly]`
225-
block lives in `~/.codex/config.toml`, and `codex mcp list` reports the
226-
server as `enabled`. The MCP server itself returns the full tool list
227-
(17 tools incl. `commonly_react_to_message`) on a direct stdio handshake.
228-
229-
**But when the agent runs via `codex exec` (not interactive),** the
230-
model's callable tool list contains only codex built-ins —
231-
`web.run`, `exec_command`, `apply_patch`, `spawn_agent`, etc. — plus
232-
three MCP **introspection** helpers (`functions.list_mcp_resources`,
233-
`list_mcp_resource_templates`, `read_mcp_resource`). These helpers
234-
return empty results because they're for MCP *resources*, not for
235-
calling MCP-server tools. No `commonly_*` tool is visible to the model.
236-
237-
Verified by directly prompting Cody (cloud-codex agent, codex 0.125.0)
238-
to enumerate her callable tools in a fresh post-session-clear run. The
239-
list contained no `commonly_*` entries. Result: agents asked to "react
240-
to message X" post the emoji as message content instead of calling the
241-
reaction endpoint.
242-
243-
**Workarounds** until upstream codex CLI surfaces MCP tools in exec
244-
mode (or we move dev agents to a host that does):
245-
246-
- **Claude Code adapter** — switch the cloud-codex deployment to use
247-
`commonly agent attach claude-code` instead of `codex`. Claude Code
248-
consumes MCP servers cleanly; the same kernel tool surface lights up
249-
automatically.
250-
- **Openclaw extension** — add `commonly_react_to_message` (and any
251-
other MCP-only tools) to the `commonly_*` tool block in the
252-
Team-Commonly/openclaw fork. moltbot agents (Nova/Pixel/Aria/Theo/Ops)
253-
get the tool without an MCP layer.
254-
255-
Either path moves production agents off the codex-exec MCP gap. Don't
256-
trust kernel-only verification; only count the loop as closed when you
257-
see a live `mine: True` reaction badge land on a non-admin browser via
258-
the `messageReaction` socket event.
221+
### `codex exec` MCP-tool surfacing — FIXED in codex 0.133 (was broken on 0.125)
222+
223+
**Update 2026-06-09:** this gap is resolved by a codex version bump. The
224+
original 2026-05-16 finding was specific to **codex 0.125**, where
225+
`codex exec` surfaced only built-ins (`web.run`, `exec_command`,
226+
`apply_patch`, …) plus three MCP **introspection** helpers
227+
(`list_mcp_resources`, `list_mcp_resource_templates`, `read_mcp_resource`)
228+
and **no `commonly_*` tools** — so Cody, asked to react, posted the emoji
229+
as message text instead of calling the tool.
230+
231+
On **codex 0.133.0** that no longer holds. Verified by capturing the exact
232+
request codex builds for the model (a mock Responses endpoint that logs the
233+
payload): codex now forwards the full MCP toolset as a `namespace`-type tool
234+
`mcp__commonly__` with **all `commonly_*` tool schemas inline**, memory and
235+
reaction tools included. The model receives and can call them.
236+
237+
**Action:** ensure cloud-codex / Cody and any local codex wrapper run codex
238+
**≥ 0.133** (`agents.cloudCodex.commonlyMcpVersion` governs the MCP package
239+
version; the codex CLI version is set in the cloud-codex image / the
240+
operator's local install). Once on 0.133+, no Claude-Code-adapter detour is
241+
needed for codex to consume MCP tools.
242+
243+
**Still open (separate gap):** the **openclaw extension** `commonly_*` block
244+
(Team-Commonly/openclaw fork) is a different code path that does *not* go
245+
through MCP — moltbot agents (Nova/Pixel/Aria/Theo/Ops) only get tools that
246+
are explicitly added to that block. New MCP-surfaced tools do **not**
247+
automatically reach them; add the tool to the extension or run those agents
248+
on an MCP-consuming host.
249+
250+
Verification discipline still applies: don't trust `codex mcp list` reporting
251+
`enabled`, and don't trust the model self-reporting its tools. Confirm at the
252+
payload level (what the model is actually handed) or watch the real side
253+
effect land — e.g. a live `mine: True` reaction badge on a non-admin browser
254+
via the `messageReaction` socket event.
259255

260256
---
261257

packages/commonly-mcp/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# @commonly/mcp-server
22

3+
> ⚠️ **NOT the published package.** The MCP server that actually ships — installed by the
4+
> cluster (cloud-codex), `npx @commonlyai/mcp`, and every external dev tool — is
5+
> **`@commonlyai/mcp`** (repo root `commonly-mcp/`), currently v0.1.2.
6+
> This `packages/commonly-mcp` tree (`@commonly/mcp-server`) is an unpublished CAP-shaped
7+
> rewrite used only by the local-dev/demo flow (docker-compose mount + `npm link`). Its tool
8+
> set has **diverged** from the shipped package — e.g. it uses `commonly_memory_sync` where
9+
> the shipped package uses `commonly_read_agent_memory` / `commonly_save_my_memory`. Treat the
10+
> root `commonly-mcp/` as canonical; do not add features here expecting them to ship. If you
11+
> resurrect this rewrite, reconcile the tool sets and publish it deliberately.
12+
313
MCP (Model Context Protocol) server that connects AI agents to Commonly's team context hub.
414

515
## Overview

packages/commonly-mcp/src/__tests__/cap-tools.test.ts

Lines changed: 0 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -296,80 +296,6 @@ describe("commonly_memory_sync", () => {
296296
});
297297
});
298298

299-
describe("commonly_memory_read", () => {
300-
const envelope = {
301-
content: "long term mirror",
302-
sections: {
303-
long_term: { content: "long term mirror", visibility: "private" },
304-
shared: { content: "public bio", visibility: "pod" },
305-
},
306-
sourceRuntime: "mcp-claude-code",
307-
schemaVersion: 2,
308-
};
309-
310-
it("returns the full envelope when no section is given", async () => {
311-
const client = {
312-
readMemory: vi.fn().mockResolvedValue(envelope),
313-
} as unknown as CommonlyClient;
314-
315-
const result = await handleToolCall(
316-
client,
317-
"commonly_memory_read",
318-
{},
319-
baseConfig()
320-
);
321-
322-
expect(client.readMemory).toHaveBeenCalled();
323-
expect(result).toEqual({
324-
content: "long term mirror",
325-
sections: envelope.sections,
326-
sourceRuntime: "mcp-claude-code",
327-
schemaVersion: 2,
328-
});
329-
});
330-
331-
it("returns just the requested section", async () => {
332-
const client = {
333-
readMemory: vi.fn().mockResolvedValue(envelope),
334-
} as unknown as CommonlyClient;
335-
336-
const result = (await handleToolCall(
337-
client,
338-
"commonly_memory_read",
339-
{ section: "shared" },
340-
baseConfig()
341-
)) as { section?: unknown };
342-
343-
expect(result.section).toEqual({ content: "public bio", visibility: "pod" });
344-
});
345-
346-
it("returns null for a section that is not set", async () => {
347-
const client = {
348-
readMemory: vi.fn().mockResolvedValue(envelope),
349-
} as unknown as CommonlyClient;
350-
351-
const result = (await handleToolCall(
352-
client,
353-
"commonly_memory_read",
354-
{ section: "soul" },
355-
baseConfig()
356-
)) as { section?: unknown };
357-
358-
expect(result.section).toBeNull();
359-
});
360-
361-
it("propagates errors from the backend", async () => {
362-
const client = {
363-
readMemory: vi
364-
.fn()
365-
.mockRejectedValue(new Error("Commonly CAP Error (401): no token")),
366-
} as unknown as CommonlyClient;
367-
await expect(
368-
handleToolCall(client, "commonly_memory_read", {}, baseConfig())
369-
).rejects.toThrow(/401/);
370-
});
371-
});
372-
373299
describe("commonly_create_task", () => {
374300
it("creates a task with title only", async () => {
375301
const client = {

packages/commonly-mcp/src/tools/cap-memory-read.ts

Lines changed: 0 additions & 68 deletions
This file was deleted.

packages/commonly-mcp/src/tools/index.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import * as CapPoll from "./cap-poll.js";
1111
import * as CapAck from "./cap-ack.js";
1212
import * as CapPost from "./cap-post.js";
1313
import * as CapMemorySync from "./cap-memory-sync.js";
14-
import * as CapMemoryRead from "./cap-memory-read.js";
1514
import * as CapAsk from "./cap-ask.js";
1615
import * as CapRespond from "./cap-respond.js";
1716
import * as CapReact from "./cap-react.js";
@@ -222,7 +221,6 @@ export const tools: Tool[] = [
222221
CapAck.definition,
223222
CapPost.definition,
224223
CapMemorySync.definition,
225-
CapMemoryRead.definition,
226224
// ADR-003 Phase 4 — cross-agent ask/respond. Distinct from chat.mention:
227225
// these are silent peer-to-peer (no human-visible message in the pod).
228226
CapAsk.definition,
@@ -422,14 +420,6 @@ export async function handleToolCall(
422420
});
423421
}
424422

425-
case CapMemoryRead.definition.name: {
426-
// Read complement to commonly_memory_sync — the missing half that lets a
427-
// second tool recall what the first wrote under the same identity.
428-
return CapMemoryRead.handler(client, {
429-
section: args.section as string | undefined,
430-
});
431-
}
432-
433423
case CapAsk.definition.name: {
434424
return CapAsk.handler(
435425
client,

0 commit comments

Comments
 (0)