Skip to content

buildCliAgentSystemPrompt invoked with tools: [], suppresses plugin-side prompt sections like Memory Recall #83210

@adele-with-a-b

Description

@adele-with-a-b

Summary

buildCliAgentSystemPrompt is invoked with tools: [] in prepare.runtime, which causes buildAgentSystemPrompt to compute availableTools = new Set([]). Plugins that gate their auto-injected system-prompt sections on tool availability (notably memory-core's "Memory Recall" guidance) then return empty, so claude-cli-backed agents never receive the prompt-side documentation about tools they actually have access to via the openclaw MCP loopback.

The user-visible symptom: claude-cli agents have mcp__openclaw__memory_search and mcp__openclaw__memory_get available (allowed by the default --allowedTools mcp__*,... and surfaced via the MCP loopback), but never call them, because the system prompt contains zero hint that they exist or how to use them.

Trace

prepare.runtime (in current 2026.5.12 bundle, file dist/prepare.runtime-DzWXf1k1.js line 715) builds the claude-cli system prompt:

buildCliAgentSystemPrompt({
    ...,
    tools: [],   // empty
    ...
})

That flows into helpers (dist/helpers-B1ZH_nQ4.js:117):

toolNames: params.tools.map((tool) => tool.name)

Which lands in buildAgentSystemPrompt (dist/system-prompt-config-DpjdHIUy.js:443):

availableTools = new Set(normalizedTools)   // empty set

buildMemorySection (dist/system-prompt-config-DpjdHIUy.js:160-166) calls buildPromptSection from extensions/memory-core/index.js:99-110:

const hasMemorySearch = availableTools.has("memory_search");
const hasMemoryGet = availableTools.has("memory_get");
if (!hasMemorySearch && !hasMemoryGet) return [];

With an empty set, this returns []. The "Memory Recall" guidance — "Mandatory recall step: semantically search MEMORY.md + memory/.md… Before answering anything about prior work, decisions, dates…"* — is never injected. Same shape applies to any other plugin section that gates on tool availability.

Meanwhile, the loopback's tools/list (mcp-http-CqosJaju.js:69) IS wired to resolveGatewayScopedTools(...) (tool-resolution-D_3lVp4s.js:13-103) and serves the real tool list. So tools/list and the system-prompt's availableTools are inconsistent: tools/list has memory_search; the system prompt acts as if it doesn't.

Reproducer

  1. Configure a claude-cli-backed agent with default --allowedTools mcp__*,... (matches gh-ship default at cli-backend-BDU6UI9e.js:5-69).
  2. Enable the memory-core plugin (default-enabled in shipped configs).
  3. Start a session with the agent and run a turn.
  4. Inspect the system prompt OC sends to claude-cli (the temp file under ~/.openclaw/tmp/openclaw-cli-mcp-*/mcp.json is the MCP-config side; the system prompt itself is constructed in buildCliAgentSystemPrompt).

Expected: system prompt includes a "Memory Recall" section explaining memory_search / memory_get and how to use them.
Actual: section is absent because availableTools is empty.

Indirect evidence: with default config, gateway.log shows zero memory_search invocations from claude-cli backed agents over multi-week windows, while non-CLI (agent/embedded) backed agents call it normally. (Verified locally: 4 memory_search calls in 6 weeks of logs, all from [agent/embedded], zero from claude-cli.)

Suggested fix

Populate tools in the buildCliAgentSystemPrompt(...) call at prepare.runtime-DzWXf1k1.js:715 from the gateway-scoped tool list — the same list the MCP loopback already serves via resolveGatewayScopedTools(...) at mcp-http-CqosJaju.js:343-356.

Roughly:

const { tools: gatewayTools } = await resolveGatewayScopedTools({
    cfg,
    sessionKey,
    // ...whatever else resolveGatewayScopedTools needs from the existing prepare ctx
});

buildCliAgentSystemPrompt({
    ...,
    tools: gatewayTools,
    ...
})

Then the availableTools set in buildAgentSystemPrompt will accurately reflect what the agent actually has, and the plugin-side buildPromptSection calls will inject the right guidance.

Related

Stack

  • OpenClaw 2026.5.12, brew-installed at /opt/homebrew/lib/node_modules/openclaw/
  • macOS Sequoia 15.x, M5 Max
  • Three claude-cli-backed agents (claude-cli/claude-opus-4-7)
  • Claude CLI 2.1.143

Happy to provide the agent configs, redacted log excerpts, or work on a PR if useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions