Skip to content

feat: carry gateway client capabilities through the CLI loopback backend#102835

Merged
steipete merged 2 commits into
mainfrom
feat/cli-loopback-client-caps-102577
Jul 9, 2026
Merged

feat: carry gateway client capabilities through the CLI loopback backend#102835
steipete merged 2 commits into
mainfrom
feat/cli-loopback-client-caps-102577

Conversation

@steipete

@steipete steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Closes #102577

What Problem This Solves

Capability-gated agent tools (such as show_widget, gated on the inline-widgets gateway client capability) were unavailable on CLI-backed model backends: the CLI/bundle-MCP loopback never transported the originating client's declared capabilities, so tool assembly ran capless and dropped gated tools even for Control UI conversations whose client had advertised support. This was the documented fail-closed limitation left open by the inline-widgets work.

Why This Change Was Made

Threads clientCaps along the loopback's existing per-field string transport, mirroring how messageProvider travels: RunCliAgentParams gains the field (forwarded from the queued run at both dispatch sites), prepare emits OPENCLAW_MCP_CLIENT_CAPS, the loopback header template adds x-openclaw-client-caps, the request context parses it (trim, dedupe, empty → undefined) in the gateway-launched loopback branch only — grant-authenticated callers keep nulling spoofable context headers — and the loopback tool cache includes a stable sorted serialization of the caps in its key so capless and capped requests never share cached tool lists. resolveGatewayScopedTools already accepted clientCaps, so the resolver end needed no changes. The CLI session binding hash includes caps, consistent with messageProvider (surface-dependent tool lists already participate in reuse decisions). Cron and command-attempt runs have no gateway client and stay capless (fail closed). ACP dispatch is out of scope — it cannot enforce OpenClaw tool policy at all — and direct HTTP tools-invoke callers remain fail closed because they declare no capabilities.

User Impact

Control UI conversations running on CLI-backed model backends (Claude CLI, Gemini CLI, and other bundle-MCP harnesses) can now use capability-gated tools like show_widget, matching the embedded and Codex app-server backends. No configuration changes; no behavior change for channels, cron, or grant-authenticated MCP callers.

Evidence

  • src/gateway/mcp-http.test.ts (280 tests): header reaches the resolver as a parsed array; whitespace/duplicate/empty header normalization; grant-authenticated branch ignores the header; capless and capped requests resolve separately (no cache cross-serving).
  • src/agents/cli-runner/prepare.test.ts (64) and bundle-mcp.gemini.test.ts: env var emitted from RunCliAgentParams.clientCaps; header template substitutes it into the generated MCP server config.
  • src/auto-reply/reply/followup-runner.test.ts (130) and agent-runner-execution.test.ts (242): both CLI dispatch sites forward run.clientCaps.
  • src/gateway/tool-resolution.exclude.test.ts: caps passthrough at the resolver seam.
  • oxfmt/oxlint clean on touched files; git diff --check clean; structured autoreview clean (no actionable findings).
  • The docs limitation note in docs/tools/show-widget.md is updated to reflect the covered backends.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation gateway Gateway runtime agents Agent runtime and tooling size: S maintainer Maintainer-authored PR labels Jul 9, 2026
@clawsweeper

clawsweeper Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 9, 2026, 9:46 AM ET / 13:46 UTC.

Summary
The PR threads gateway client capability IDs through CLI/bundle-MCP loopback env/header/request scope/cache handling and updates show_widget docs and focused tests.

PR surface: Source +24, Tests +89, Docs 0. Total +113 across 16 files.

Reproducibility: yes. from source for the linked feature gap: current main preserves client caps on queued runs and filters tools by caps, but the CLI loopback request/scope/prepare path omits caps.

Review metrics: 1 noteworthy metric.

  • Loopback transport surfaces: 1 internal env var and 1 loopback header added. Capability propagation depends on forwarding a new scoped header through the CLI loopback trust boundary.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #102577
Summary: this PR is the candidate implementation for the open CLI/bundle-MCP client-capability propagation issue #102577.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🦪 silver shellfish
Proof: 🧂 unranked krab
Patch quality: 🐚 platinum hermit
Result: blocked until real behavior proof from a real setup is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Add redacted live proof from a CLI-backed Control UI conversation or loopback tool-list call showing capability-gated tools appear only with declared caps.
  • Rebase on current main and refresh exact-head CI/proof before maintainer merge review.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR body provides tests and static checks only; it needs redacted live output, logs, or a screenshot/recording from a real CLI-backed Control UI or loopback run showing the gated tool path after the fix. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] Contributor-provided real behavior proof is absent; the PR body lists tests/static checks but no live Control UI or CLI-backed run evidence.
  • [P1] The branch is behind current main, so exact-head review, CI, and proof should be refreshed after rebase.

Maintainer options:

  1. Decide the mitigation before merge
    Merge after maintainer accepts the CLI loopback capability contract and the author adds redacted live Control UI or CLI-backed proof; keep grant-authenticated MCP and direct HTTP callers capless.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P1] Needs maintainer review because it changes the backend capability contract and lacks contributor real-behavior proof; no automated repair is indicated.

Maintainer decision needed

  • Question: Should CLI/bundle-MCP loopback accept gateway client capabilities as part of the supported backend contract once live proof is added?
  • Rationale: The change makes client capabilities part of loopback tool availability, and the linked issue plus protected maintainer label make that API/security-boundary direction maintainer-owned.
  • Likely owner: steipete — He authored the capability-gated widget path and this follow-up PR, so he has the clearest current product/API context.
  • Options:
    • Accept After Live Proof (recommended): Keep this PR open and merge once the author shows a real CLI-backed Control UI or loopback run where a capped tool becomes available only with declared caps.
    • Require Broader Backend Proof: Ask for broader exact-head proof across at least one Codex/Claude/Gemini CLI backend before accepting the new contract.
    • Keep CLI Backends Capless: Reject the backend parity change and keep the docs saying capability-gated tools fail closed on CLI-backed runs.

Security
Cleared: No concrete supply-chain concern: no workflow, lockfile, dependency, or package metadata changes, and the new header is scoped to bearer-token loopback while grant-auth ignores spoofable headers.

Review details

Best possible solution:

Merge after maintainer accepts the CLI loopback capability contract and the author adds redacted live Control UI or CLI-backed proof; keep grant-authenticated MCP and direct HTTP callers capless.

Do we have a high-confidence way to reproduce the issue?

Yes from source for the linked feature gap: current main preserves client caps on queued runs and filters tools by caps, but the CLI loopback request/scope/prepare path omits caps.

Is this the best way to solve the issue?

Yes, conditionally: threading caps through the existing loopback env/header/request/cache seam is the clean owner-boundary fix, but maintainer signoff and live proof are still required.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against f6b990124353.

Label changes

Label changes:

  • add P2: This is a bounded gateway/CLI backend parity improvement for capability-gated tools with limited blast radius.
  • add rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🧂 unranked krab and patch quality is 🐚 platinum hermit.
  • add status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body provides tests and static checks only; it needs redacted live output, logs, or a screenshot/recording from a real CLI-backed Control UI or loopback run showing the gated tool path after the fix. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Label justifications:

  • P2: This is a bounded gateway/CLI backend parity improvement for capability-gated tools with limited blast radius.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🧂 unranked krab and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body provides tests and static checks only; it needs redacted live output, logs, or a screenshot/recording from a real CLI-backed Control UI or loopback run showing the gated tool path after the fix. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +24, Tests +89, Docs 0. Total +113 across 16 files.

View PR surface stats
Area Files Added Removed Net
Source 8 24 0 +24
Tests 7 99 10 +89
Docs 1 1 1 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 16 124 11 +113

What I checked:

  • Repository policy read: Read root AGENTS.md plus scoped src/agents/AGENTS.md, src/gateway/AGENTS.md, and docs/AGENTS.md; no matching .agents/maintainer-notes files were present. (AGENTS.md:1, f6b990124353)
  • Live PR state: this PR is open, mergeable but behind main, carries the maintainer label, and has no review comments beyond the ClawSweeper placeholder. (3b993cb91c59)
  • Current capability gate: Current main already treats client capabilities as a hard tool-assembly fact and filters tools through filterToolsByClientCaps. (src/agents/openclaw-tools.ts:91, f6b990124353)
  • Resolver seam already accepts caps: resolveGatewayScopedTools accepts clientCaps and passes them to createOpenClawTools, so the missing path is transport into the loopback scope rather than a new resolver API. (src/gateway/tool-resolution.ts:48, f6b990124353)
  • Current CLI loopback omission: Current main's MCP request context, loopback scope/cache, header template, and CLI prepare env do not carry client capabilities. (src/gateway/mcp-http.request.ts:55, f6b990124353)
  • Current loopback cache omission: The current loopback tool cache key includes session/channel/request facts but not client capabilities, matching the linked issue's cache concern. (src/gateway/mcp-http.runtime.ts:31, f6b990124353)

Likely related people:

  • steipete: Authored the current main capability-gated show_widget implementation in PR feat: render inline web chat widgets via capability-gated show_widget tool #101840 and this PR's linked follow-up targets that feature's documented CLI backend gap. (role: related feature author and likely follow-up owner; confidence: high; commits: 3ccf2a07393e, 5f9e0e20d4e4, 3b993cb91c59; files: src/agents/openclaw-tools.ts, src/gateway/tool-resolution.ts, src/gateway/mcp-http.runtime.ts)
  • Ayaan Zaidi: Recent current-main history owns much of McpLoopbackScopeParams and resolveGatewayScopedTools surrounding the transport seam this PR extends. (role: recent loopback/tool-resolution contributor; confidence: medium; commits: 34d257713ea3; files: src/gateway/mcp-http.runtime.ts, src/gateway/tool-resolution.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. labels Jul 9, 2026
steipete added 2 commits July 9, 2026 06:53
CLI-backed model runs now transport the originating client's declared
capabilities along the existing per-field loopback contract: RunCliAgentParams
gains clientCaps, prepare emits OPENCLAW_MCP_CLIENT_CAPS, the loopback header
template forwards x-openclaw-client-caps, the request context parses and
normalizes it (grant-authenticated callers keep ignoring spoofable headers),
and the loopback tool cache keys on a stable caps serialization so capless and
capped requests never share tool lists. Capability-gated tools such as
show_widget now work on CLI backends; the CLI session binding hash includes
caps, consistent with messageProvider. Cron and command-attempt runs stay
capless (fail closed).

Fixes #102577
@steipete
steipete force-pushed the feat/cli-loopback-client-caps-102577 branch from 3b993cb to 1bdeb15 Compare July 9, 2026 13:55
@steipete
steipete merged commit b5ba077 into main Jul 9, 2026
98 checks passed
@steipete
steipete deleted the feat/cli-loopback-client-caps-102577 branch July 9, 2026 14:09
@steipete

steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 10, 2026
…end (openclaw#102835)

* test: shorten loopback token fixtures below secret-scanner thresholds

* feat: carry gateway client capabilities through the CLI loopback backend

CLI-backed model runs now transport the originating client's declared
capabilities along the existing per-field loopback contract: RunCliAgentParams
gains clientCaps, prepare emits OPENCLAW_MCP_CLIENT_CAPS, the loopback header
template forwards x-openclaw-client-caps, the request context parses and
normalizes it (grant-authenticated callers keep ignoring spoofable headers),
and the loopback tool cache keys on a stable caps serialization so capless and
capped requests never share tool lists. Capability-gated tools such as
show_widget now work on CLI backends; the CLI session binding hash includes
caps, consistent with messageProvider. Cron and command-attempt runs stay
capless (fail closed).

Fixes openclaw#102577
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling docs Improvements or additions to documentation gateway Gateway runtime maintainer Maintainer-authored PR P2 Normal backlog priority with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. size: S status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Carry gateway client capabilities through the CLI/bundle-MCP backend

1 participant