[PR #442] [MERGED] perf(mcp): reduce cold-start work #1989

Closed
opened 2026-10-16 21:13:08 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/442
Author: @morluto
Created: 7/26/2026
Status: ✅ Merged
Merged: 7/26/2026
Merged by: @morluto

Base: main ← Head: fix/mcp-cold-start


📝 Commits (2)

  • fecddc0 perf(mcp): reduce cold-start work
  • 7157ab0 test(mcp): stabilize lazy-loading verification

📊 Changes

30 files changed (+1437 additions, -298 deletions)

View changed files

📝 package.json (+4 -2)
➕ scripts/generate-mcp-tool-catalog.mjs (+153 -0)
➕ scripts/lib/mcp-startup-probe.d.mts (+62 -0)
➕ scripts/lib/mcp-startup-probe.mjs (+217 -0)
📝 scripts/verify-agent-experience.mjs (+2 -1)
📝 scripts/verify-package-mcp.mjs (+2 -1)
📝 scripts/verify-package.mjs (+27 -1)
📝 src/application/AnalysisSnapshotCache.ts (+10 -8)
📝 src/application/BinarySession.ts (+10 -4)
📝 src/application/CapabilityInventory.ts (+3 -3)
📝 src/application/ClientRegistrationStatus.ts (+6 -1)
➕ src/application/LazyAnalysisProvider.ts (+113 -0)
📝 src/application/SetupClientConfiguration.ts (+4 -3)
📝 src/application/runtime.ts (+38 -9)
📝 src/contracts/promptContracts.ts (+1 -1)
📝 src/contracts/toolContractTypes.ts (+1 -1)
➕ src/generatedMcpToolCatalog.ts (+82 -0)
📝 src/ghidra/GhidraProviderCapabilities.ts (+12 -13)
📝 src/hopper/HopperProvider.ts (+21 -13)
📝 src/main.ts (+19 -12)

...and 10 more files

📄 Description

Description

REA currently constructs the production MCP server through the full tool-contract and implementation graph before completing initialization. That makes a target-free Codex connection pay for browser, replay, managed, artifact, and provider machinery it may never use.

This change keeps the complete caller-visible catalog available at tools/list, but generates a lightweight JSON Schema projection for startup and hydrates the existing Zod-backed registrations by tool family on first execution. Optional browser providers and auxiliary analysis providers now use single-flight dynamic loading with explicit close/retry ownership. The original handlers still parse inputs and return the same structured REA errors; no tool names, descriptions, schemas, availability rules, or execution semantics are intentionally changed.

The package verifier now measures the first installed MCP child before doctor or other runtime commands. It records spawn-to-initialize, initialize-to-tools-list, total first-catalog time, Linux peak RSS when available, and ESM module loading. Startup deadlines and regression budgets come from one policy module.

On this Linux x64 workspace with Node 24.18, the original warm-cache baseline was approximately 3.27 s to a usable catalog, 386 MB peak RSS, and 758 loaded modules. Two exact packaged-tree verification runs measured:

Phase Run 1 Run 2
spawn → initialized 1.114 s 2.055 s
initialized → tools/list 0.140 s 0.361 s
spawn → usable catalog 1.254 s 2.416 s
peak RSS 221 MB 221 MB
file-backed ESM modules 246 247

The timing remains informational across hosts; RSS is reported but is not a hard cross-platform gate.

Suggested review order: LazyToolCatalog and hydrateServerTools, then the generated-catalog script/artifact, then provider loading and package measurements.

Type of Change

  • Bug fix
  • New feature
  • Documentation update
  • Performance improvement
  • Refactoring (no functional change)
  • Tool contract change (MCP schema modification)

Testing Performed

  • Unit tests added or updated
  • TypeScript typecheck passes (npm run typecheck)
  • Linting passes (npm run lint)
  • Full test suite passes (npm test)
  • Real Hopper verification performed (npm run verify:hopper)
  • Linux real Hopper verification performed (npm run verify:hopper:linux) or unavailability explained
  • Real browser verification performed (npm run verify:browser) or unavailability explained
  • Package verification performed (npm run verify:package)

Also run successfully:

  • npm run check
  • focused MCP inventory, session, browser, Electron, managed, Ghidra, prompt, identity, and malformed-input tests
  • npm pack --dry-run

npm run check:pr completed its static and generated-document tasks, but its concurrently executed full test task hit five existing wall-clock test limits under local load. Each affected test passes in its focused lane; the isolated package verifier passes against the exact committed tree. Real provider workflows were not run because this change does not alter Hopper/Ghidra process or protocol behavior.

Tool Contract Impact

None. The generated projection is checked against TOOL_CONTRACTS; target-free and fixed-target availability remain unchanged, and the package verifier exercises all 111 tools through the normal target lifecycle.

Closes #441


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/442 **Author:** [@morluto](https://github.com/morluto) **Created:** 7/26/2026 **Status:** ✅ Merged **Merged:** 7/26/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `fix/mcp-cold-start` --- ### 📝 Commits (2) - [`fecddc0`](https://github.com/morluto/rea/commit/fecddc0549a31e99a5ea72cbda84e448b1a961d5) perf(mcp): reduce cold-start work - [`7157ab0`](https://github.com/morluto/rea/commit/7157ab0b70833cc8237271e8625ccb7965c318c3) test(mcp): stabilize lazy-loading verification ### 📊 Changes **30 files changed** (+1437 additions, -298 deletions) <details> <summary>View changed files</summary> 📝 `package.json` (+4 -2) ➕ `scripts/generate-mcp-tool-catalog.mjs` (+153 -0) ➕ `scripts/lib/mcp-startup-probe.d.mts` (+62 -0) ➕ `scripts/lib/mcp-startup-probe.mjs` (+217 -0) 📝 `scripts/verify-agent-experience.mjs` (+2 -1) 📝 `scripts/verify-package-mcp.mjs` (+2 -1) 📝 `scripts/verify-package.mjs` (+27 -1) 📝 `src/application/AnalysisSnapshotCache.ts` (+10 -8) 📝 `src/application/BinarySession.ts` (+10 -4) 📝 `src/application/CapabilityInventory.ts` (+3 -3) 📝 `src/application/ClientRegistrationStatus.ts` (+6 -1) ➕ `src/application/LazyAnalysisProvider.ts` (+113 -0) 📝 `src/application/SetupClientConfiguration.ts` (+4 -3) 📝 `src/application/runtime.ts` (+38 -9) 📝 `src/contracts/promptContracts.ts` (+1 -1) 📝 `src/contracts/toolContractTypes.ts` (+1 -1) ➕ `src/generatedMcpToolCatalog.ts` (+82 -0) 📝 `src/ghidra/GhidraProviderCapabilities.ts` (+12 -13) 📝 `src/hopper/HopperProvider.ts` (+21 -13) 📝 `src/main.ts` (+19 -12) _...and 10 more files_ </details> ### 📄 Description ## Description REA currently constructs the production MCP server through the full tool-contract and implementation graph before completing initialization. That makes a target-free Codex connection pay for browser, replay, managed, artifact, and provider machinery it may never use. This change keeps the complete caller-visible catalog available at `tools/list`, but generates a lightweight JSON Schema projection for startup and hydrates the existing Zod-backed registrations by tool family on first execution. Optional browser providers and auxiliary analysis providers now use single-flight dynamic loading with explicit close/retry ownership. The original handlers still parse inputs and return the same structured REA errors; no tool names, descriptions, schemas, availability rules, or execution semantics are intentionally changed. The package verifier now measures the first installed MCP child before doctor or other runtime commands. It records spawn-to-initialize, initialize-to-tools-list, total first-catalog time, Linux peak RSS when available, and ESM module loading. Startup deadlines and regression budgets come from one policy module. On this Linux x64 workspace with Node 24.18, the original warm-cache baseline was approximately 3.27 s to a usable catalog, 386 MB peak RSS, and 758 loaded modules. Two exact packaged-tree verification runs measured: | Phase | Run 1 | Run 2 | | --- | ---: | ---: | | spawn → initialized | 1.114 s | 2.055 s | | initialized → tools/list | 0.140 s | 0.361 s | | spawn → usable catalog | 1.254 s | 2.416 s | | peak RSS | 221 MB | 221 MB | | file-backed ESM modules | 246 | 247 | The timing remains informational across hosts; RSS is reported but is not a hard cross-platform gate. Suggested review order: `LazyToolCatalog` and `hydrateServerTools`, then the generated-catalog script/artifact, then provider loading and package measurements. ## Type of Change - [x] Bug fix - [ ] New feature - [ ] Documentation update - [x] Performance improvement - [x] Refactoring (no functional change) - [ ] Tool contract change (MCP schema modification) ## Testing Performed - [x] Unit tests added or updated - [x] TypeScript typecheck passes (`npm run typecheck`) - [x] Linting passes (`npm run lint`) - [ ] Full test suite passes (`npm test`) - [ ] Real Hopper verification performed (`npm run verify:hopper`) - [ ] Linux real Hopper verification performed (`npm run verify:hopper:linux`) or unavailability explained - [ ] Real browser verification performed (`npm run verify:browser`) or unavailability explained - [x] Package verification performed (`npm run verify:package`) Also run successfully: - `npm run check` - focused MCP inventory, session, browser, Electron, managed, Ghidra, prompt, identity, and malformed-input tests - `npm pack --dry-run` `npm run check:pr` completed its static and generated-document tasks, but its concurrently executed full test task hit five existing wall-clock test limits under local load. Each affected test passes in its focused lane; the isolated package verifier passes against the exact committed tree. Real provider workflows were not run because this change does not alter Hopper/Ghidra process or protocol behavior. ## Tool Contract Impact None. The generated projection is checked against `TOOL_CONTRACTS`; target-free and fixed-target availability remain unchanged, and the package verifier exercises all 111 tools through the normal target lifecycle. ## Related Issues Closes #441 --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-16 21:13:08 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#1989
No description provided.