Skip to content

perf(mcp): cache immutable bundled config discovery#79882

Merged
steipete merged 1 commit into
openclaw:mainfrom
shebson:stephen-hebson/mcp-shared-runtime-scope
Jul 17, 2026
Merged

perf(mcp): cache immutable bundled config discovery#79882
steipete merged 1 commit into
openclaw:mainfrom
shebson:stephen-hebson/mcp-shared-runtime-scope

Conversation

@shebson

@shebson shebson commented May 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Problem: bundled MCP config discovery repeatedly rereads plugin metadata and MCP JSON while preparing equivalent session catalogs.
  • Why it matters: each session and requester partition repeats synchronous filesystem/config work before any live MCP transport starts.
  • What changed: cache immutable discovery and prepared catalog variants process-wide, keyed by workspace, canonical config fingerprint, and plugin-manifest snapshot. Both cache levels are bounded LRUs. Plugin metadata lifecycle clears invalidate the cache.
  • Safety boundary: live clients, transports, tools/list catalogs, backoff, and failures remain session-owned. Diagnostic-bearing discovery results are never cached. Cached input graphs are snapshotted, and every caller receives a deep-fresh result.

What Problem This Solves

Equivalent session and requester-partition catalog preparations repeatedly performed synchronous bundle/plugin manifest discovery and MCP JSON loading. The repeated filesystem/config work delayed every fresh session even when the immutable inputs had not changed. This rewrite removes that repeat work without sharing live MCP state between sessions.

Change Type (select all)

  • Bug fix
  • Refactor required for the fix
  • Feature
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

Evidence

  • node scripts/run-vitest.mjs src/agents/agent-bundle-mcp-runtime-config.test.ts src/agents/agent-bundle-mcp-runtime.test.ts
    • 2 files passed; 81 tests passed.
  • node scripts/check-changed.mjs -- src/agents/agent-bundle-mcp-runtime-config.ts src/agents/agent-bundle-mcp-runtime-config.test.ts
  • Repeated-load probe, 25 rounds: lifecycle-invalidated discovery 2743.04 ms; warm discovery 110.08 ms; 24.9x ratio. This measures the synchronous preparation path only, not live MCP startup.

Root Cause

loadSessionMcpConfig rebuilt the same bundle/plugin discovery and filtered catalog preparation for every call. Runtime reuse already had a content fingerprint, but immutable preparation had no process-lifecycle owner.

Regression Test Plan

  • Reuse one discovery load across full and filtered preparations.
  • Invalidate on config, workspace, manifest snapshot, and plugin metadata lifecycle changes.
  • Bound cached entries and variants.
  • Preserve retry after diagnostic-bearing discovery.
  • Snapshot nested input values and isolate returned object graphs from session mutation.

Notes for reviewers

  • No config option or environment variable added.
  • Live runtime pooling remains future work. It needs an explicit server-declared shareability contract before transports or dynamic catalogs can cross session boundaries.
  • Contributor credit retained in the rewritten commit.

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: M triage: mock-only-proof Candidate: PR proof only shows tests, mocks, snapshots, lint, typecheck, or CI. labels May 9, 2026
@clawsweeper

clawsweeper Bot commented May 9, 2026

Copy link
Copy Markdown
Contributor

Codex review: found issues before merge. Reviewed July 3, 2026, 11:44 PM ET / 03:44 UTC.

Summary
The PR adds an opt-in mcp.runtimeScope setting that can share bundled MCP runtimes across sessions with the same workspace/config fingerprint, plus schema, docs, and runtime-manager tests.

PR surface: Source +176, Tests +344, Docs +13, Generated 0. Total +533 across 10 files.

Reproducibility: yes. at source level: current main and v2026.6.11 still key bundled MCP runtimes by session id, and the PR body provides repeated Docker terminal benchmarks showing the second matching session reuses the shared runtime in about 100 ms instead of paying another cold start. I did not run a live benchmark because this review is read-only.

Review metrics: 1 noteworthy metric.

  • Config Surface: 1 added (mcp.runtimeScope). The new openclaw.json option changes runtime reuse and isolation semantics for operators who enable it.

Stored data model
Persistent data-model change detected: persistent cache schema: docs/gateway/configuration-reference.md, persistent cache schema: src/agents/agent-bundle-mcp-runtime.test.ts, persistent cache schema: src/config/schema.help.ts. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #95506
Summary: This PR is a candidate implementation for the canonical identical workspace/config bundled MCP runtime fan-out issue; the sibling open PR is a competing candidate, not a safe superseding target while both branches are conflicting.

Members:

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

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🦞 diamond lobster
Patch quality: 🦐 gold shrimp
Result: needs maintainer review before merge.

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

Rank-up moves:

  • Rebase or port the branch onto current main while preserving newer MCP catalog concurrency and lease lifecycle fixes.
  • Use a hashed/redacted shared runtime id instead of embedding raw workspace/config identity.
  • [P2] Add the trusted single-tenant isolation warning to the primary configuration reference.

Risk before merge

  • [P1] The new mcp.runtimeScope config changes bundled MCP lifecycle and isolation semantics for operators who enable shared mode.
  • [P1] Shared mode intentionally lets MCP clients, child processes, catalog state, server-side state, and failure/backoff state cross the current per-session boundary.
  • [P1] A shared MCP child process, catalog load, hang, crash, stale TTL, or failure backoff can affect every attached matching session until detach, config reload, last-session disposal, or idle eviction.
  • [P1] The branch is currently conflicting with current main, which has newer MCP catalog concurrency and lease/idle lifecycle fixes in the same runtime manager.
  • [P1] feat(mcp): add shared bundled runtime scope #95591 is a competing open candidate for the same root cause, so maintainers need to choose one canonical landing path.

Maintainer options:

  1. Choose And Repair One Canonical Branch (recommended)
    Maintainers should choose this PR or feat(mcp): add shared bundled runtime scope #95591, then require the chosen branch to preserve current main MCP lifecycle fixes, hash the shared runtime id, and pass exact-head validation.
  2. Accept The Opt-In Isolation Tradeoff
    Maintainers may intentionally accept shared MCP reuse for trusted single-tenant deployments, but should explicitly own the cross-session client, process, catalog, server-state, and failure-state behavior.
  3. Pause If Per-Session Isolation Must Stay Strict
    If bundled MCP clients must remain per-session only, pause or close the shared-runtime candidates and pursue narrower latency fixes that do not share MCP runtime state.

Next step before merge

  • [P2] The remaining blockers are maintainer branch choice, conflict resolution against current main, and a security/config-boundary decision, so this is not a safe automated repair lane candidate.

Security
Needs attention: The diff introduces an opt-in shared MCP isolation boundary and currently exposes raw workspace/config identity in the shared runtime id.

Review findings

  • [P2] Hash the shared runtime key before surfacing it as a session id — src/agents/agent-bundle-mcp-runtime.ts:493-496
  • [P2] Document the shared-mode isolation tradeoff in config reference — docs/gateway/configuration-reference.md:179-184
Review details

Best possible solution:

Land one maintainer-approved shared-runtime implementation with session as the default, hashed/redacted shared runtime identity, explicit trusted single-tenant isolation docs, conflict-free exact-head validation, and a clear branch choice versus #95591.

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

Yes, at source level: current main and v2026.6.11 still key bundled MCP runtimes by session id, and the PR body provides repeated Docker terminal benchmarks showing the second matching session reuses the shared runtime in about 100 ms instead of paying another cold start. I did not run a live benchmark because this review is read-only.

Is this the best way to solve the issue?

No, not as-is. Workspace/config-keyed sharing is the right implementation layer for the fan-out problem, but this branch still needs a hashed shared runtime id, stronger primary config docs, conflict resolution, and maintainer acceptance of the new config/security boundary.

Full review comments:

  • [P2] Hash the shared runtime key before surfacing it as a session id — src/agents/agent-bundle-mcp-runtime.ts:493-496
    buildSharedRuntimeKey embeds the raw workspace path and full config fingerprint, and shared scope passes that key into the runtime as sessionId. Since session ids appear in errors/logging and diagnostic paths, this can expose local workspace identity and a stable config fingerprint; keep the raw tuple internal and use a hashed/redacted runtime id instead.
    Confidence: 0.87
  • [P2] Document the shared-mode isolation tradeoff in config reference — docs/gateway/configuration-reference.md:179-184
    The primary configuration reference introduces "shared" but only says two sessions reuse one runtime. Add the trusted single-tenant warning here, including that MCP clients, child processes, catalog state, server-side state, and failure/backoff state can cross sessions, so operators see the boundary before enabling the config.
    Confidence: 0.85

Overall correctness: patch is incorrect
Overall confidence: 0.86

AGENTS.md: found and applied where relevant.

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

Label changes

Label justifications:

  • P2: This is a bounded opt-in MCP performance/resource-pressure feature with source-level evidence, but it touches config and runtime lifecycle boundaries.
  • merge-risk: 🚨 compatibility: The PR adds mcp.runtimeScope and changes bundled MCP runtime ownership semantics for users who enable shared mode.
  • merge-risk: 🚨 security-boundary: Shared mode intentionally lets MCP client, child-process, catalog, server-state, and failure-state behavior cross the current per-session runtime boundary.
  • merge-risk: 🚨 availability: A shared MCP process, catalog load, hang, crash, stale TTL, or failure backoff can affect every attached matching session.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (terminal): The PR body includes repeated terminal benchmark output from a Docker-built branch image showing default session-scope cold starts and shared-scope reuse on the changed runtime path, plus a follow-up production ECS/Slack observation.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes repeated terminal benchmark output from a Docker-built branch image showing default session-scope cold starts and shared-scope reuse on the changed runtime path, plus a follow-up production ECS/Slack observation.
Evidence reviewed

PR surface:

Source +176, Tests +344, Docs +13, Generated 0. Total +533 across 10 files.

View PR surface stats
Area Files Added Removed Net
Source 5 218 42 +176
Tests 1 344 0 +344
Docs 3 20 7 +13
Config 0 0 0 0
Generated 1 3 3 0
Other 0 0 0 0
Total 10 585 52 +533

Security concerns:

  • [medium] Shared runtime id exposes workspace/config identity — src/agents/agent-bundle-mcp-runtime.ts:493
    The shared runtime key includes workspaceDir and configFingerprint and is passed as the runtime sessionId, which can surface through errors, logs, and diagnostics.
    Confidence: 0.87
  • [medium] Shared MCP runtime crosses session isolation — src/agents/agent-bundle-mcp-runtime.ts:1137
    When mcp.runtimeScope is shared, matching sessions can attach to one MCP runtime and child-process set, so MCP client, catalog, server-side, and failure/backoff state can cross sessions for users who enable it.
    Confidence: 0.9

What I checked:

Likely related people:

  • vincentkoc: CONTRIBUTING lists this person for Agents, and live PR history shows they merged recent MCP runtime/fingerprint work that this PR must preserve. (role: listed Agents maintainer and recent merger; confidence: high; commits: a2725b6a24c8, 26f92a4f8d5f; files: src/agents/agent-bundle-mcp-runtime.ts)
  • mmyzwl: Authored the merged catalog-parallelization PR touching the same bundled MCP runtime manager and catalog path. (role: recent runtime contributor; confidence: high; commits: a2725b6a24c8; files: src/agents/agent-bundle-mcp-runtime.ts)
  • openperf: Authored the merged MCP lease-release idle-eviction fix whose active-lease and TTL invariants are directly affected by shared runtime ownership. (role: recent lifecycle contributor; confidence: high; commits: f2530de8320e; files: src/agents/agent-bundle-mcp-runtime.ts, src/agents/agent-bundle-mcp-runtime.test.ts)
  • steipete: Recent MCP operability/config/docs commits shaped the runtime and documentation surface this PR extends. (role: feature-history contributor; confidence: medium; commits: 99ce71ddbbdb, 38d3d11cbc0c; files: src/agents/agent-bundle-mcp-runtime.ts, src/config/types.mcp.ts, docs/gateway/configuration-reference.md)
  • YonganZhang: Authored the merged SHA-256 config fingerprinting change adjacent to the PR's workspace/config-fingerprint shared key behavior. (role: recent adjacent contributor; confidence: medium; commits: 26f92a4f8d5f; files: src/agents/agent-bundle-mcp-runtime.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.

@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: mock-only-proof Candidate: PR proof only shows tests, mocks, snapshots, lint, typecheck, or CI. labels May 9, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 9, 2026
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation gateway Gateway runtime and removed proof: sufficient ClawSweeper judged the real behavior proof convincing. labels May 9, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 9, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 9, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 9, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 9, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 9, 2026
@shebson

shebson commented May 10, 2026

Copy link
Copy Markdown
Contributor Author

I've been running this patch today (with some additional diagnostic log statements) and is working well, not just in the artificial benchmark running in Docker locally but also in production on ECS, serving real Slack sessions. See below:

Screenshot 2026-05-09 at 9 28 47 PM

@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Jun 1, 2026
@clawsweeper clawsweeper Bot added rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. and removed proof: sufficient ClawSweeper judged the real behavior proof convincing. labels Jun 1, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Jun 2, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 2, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 2, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels Jun 2, 2026
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jun 18, 2026
@steipete
steipete force-pushed the stephen-hebson/mcp-shared-runtime-scope branch from 844f4e0 to ac11d58 Compare July 17, 2026 13:12
@openclaw-barnacle openclaw-barnacle Bot added size: M and removed docs Improvements or additions to documentation gateway Gateway runtime size: L labels Jul 17, 2026
@steipete
steipete force-pushed the stephen-hebson/mcp-shared-runtime-scope branch from ac11d58 to af4b309 Compare July 17, 2026 13:12
@steipete steipete changed the title feat(mcp): add shared runtime scope for bundled MCP servers perf(mcp): cache immutable bundled config discovery Jul 17, 2026
@openclaw-barnacle openclaw-barnacle Bot added triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. and removed triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. labels Jul 17, 2026
@steipete
steipete merged commit cc9d80c into openclaw:main Jul 17, 2026
137 of 139 checks passed
@steipete

Copy link
Copy Markdown
Contributor

Merged via squash.

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

Labels

agents Agent runtime and tooling merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. size: M status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants