Files
Murat Aslan 6b1775736a fix(openclaw): register MCP sidecar on install so ctx_* tools surface to agent (#339)
* fix(openclaw): register MCP sidecar on install so ctx_* tools surface to agent

context-mode's ctx_* tools live in server.bundle.mjs and are exposed over
stdio MCP. Other adapters (Claude Code, Codex, Cursor) spawn the bundle via
their platform's mcpServers config. The OpenClaw install script wrote
plugins.allow / plugins.entries to openclaw.json but never added
mcp.servers.context-mode, so the gateway never spawned the sidecar and
the agent never saw the ctx_* tool list — while openclaw plugins list,
openclaw doctor, and scripts/ctx-debug.sh all reported healthy state.

Changes
- scripts/lib/register-openclaw-config.mjs (new): extracts step 5 of the
  install script into a testable helper. Writes plugins.allow / .entries /
  cleans legacy plugins.load.paths (existing behavior) and additionally
  registers mcp.servers.context-mode pointing at
  <pluginRoot>/server.bundle.mjs. Idempotent: re-running is a no-op;
  stale server paths are refreshed.
- scripts/install-openclaw-plugin.sh: step 5 delegates to the helper.
- tests/plugins/openclaw.test.ts: 5 unit tests for the helper (MCP entry
  presence, idempotency, stale-path refresh, plugins.allow/entries contract,
  legacy plugins.load.paths cleanup).
- docs/adapters/openclaw.md: new troubleshooting entry documenting the MCP
  sidecar requirement and the manual openclaw mcp set recovery command.

Verification
- npm run typecheck: clean
- vitest tests/plugins/openclaw.test.ts tests/adapters/openclaw.test.ts:
  117/117 pass (baseline 112 + 5 new)
- Live: on OpenClaw 2026.4.22 + context-mode 1.0.89, after the fix the
  agent tool inventory includes context-mode__ctx_execute,
  context-mode__ctx_search, context-mode__ctx_fetch_and_index, and the
  rest of the ctx_* surface (OpenClaw prefixes MCP-sourced tools with
  the server name).

Debugging walkthrough (initial wrong diagnosis, cross-check with
@benzntech, server.ts trace that surfaced the registerTool calls,
final resolution):
https://gist.github.com/murataslan1/cd7b27577fcb535d56fe318c2339b400

Companion to issue #45 (follow-up comment:
https://github.com/mksglu/context-mode/issues/45#issuecomment-4313313422).

Pre-existing test failures in tests/hooks/integration.test.ts (Security
Policy Enforcement) are present on main too (reproduced by git-stashing
this PR and re-running), so they are not caused by this change. They
appear related to the PreToolUse relaxation commits (415ce57, 2731ca2,
ece3abb) and are out of scope here.

Scope is limited to OpenClaw adapter files and install path; hooks,
src/server.ts, the session layer, and all non-OpenClaw adapter tests
are untouched.

* fix(openclaw): prefix ctx_* names in AGENTS.md so the model invokes MCP variants

Complements the previous commit. With the MCP sidecar registered, OpenClaw
surfaces the plugin's tools as context-mode__ctx_* (server-name prefix is
automatically applied by OpenClaw's MCP aggregator). The routing guidance
injected via AGENTS.md still referenced the unprefixed names (ctx_execute,
ctx_search, ...), which left the model to bridge the naming gap on its own.

UI QA on OpenClaw 2026.4.22 + context-mode 1.0.89 confirmed this was costly
in practice: the model would invoke context-mode__ctx_fetch_and_index first
(good), but then redundantly fall back to the built-in web_fetch for the
raw content, and skip context-mode__ctx_search entirely in favor of a
web_fetch + ctx_execute combo. The unprefixed guidance made the built-ins
look like the closer match when under pressure.

This commit rewrites all 14 ctx_* mentions in configs/openclaw/AGENTS.md
to use the context-mode__ctx_* form the model actually sees. Sanity check:

  $ grep -c 'context-mode__ctx_' configs/openclaw/AGENTS.md   # 14
  $ grep -cE '\bctx_[a-z]' configs/openclaw/AGENTS.md         # 0

Scope is still OpenClaw-only — configs/pi/AGENTS.md and every other
adapter's AGENTS.md are untouched, because those platforms don't apply
the server-name prefix.

Tests unchanged; this is a system-prompt text-only change. typecheck and
the full tests/plugins/openclaw.test.ts + tests/adapters/openclaw.test.ts
suite still pass (117/117).

* fix(openclaw): preserve unrelated MCP server fields; add edge-case tests

Addressing the review points from Codex's independent CLI review of PR #339:

1. The helper previously did a full reset of mcp.servers["context-mode"] on
   every path refresh, which would silently drop user-supplied custom fields
   (env, cwd, timeout, anything OpenClaw adds in a future release). It now
   spreads the existing entry and only overwrites the two fields the helper
   owns (command + args).

2. Added two edge-case tests in tests/plugins/openclaw.test.ts:
   - "preserves unrelated fields on the existing mcp.servers entry when
     refreshing the path" — seeds env/cwd/timeout on the old entry, bumps
     pluginRoot, asserts all three survive alongside the new args[0].
   - "throws a useful error when the runtime config is not valid JSON" —
     exercises the previously-uncovered parse-error path.

Test count 117/117 → 119/119 on `tests/plugins/openclaw.test.ts` +
`tests/adapters/openclaw.test.ts`. Typecheck still clean.

Scope unchanged — still inside OpenClaw adapter/install/tests.

---------

Co-authored-by: Murat Aslan <murataslan1@users.noreply.github.com>
2026-04-25 19:01:24 +03:00
..