Skip to content

Index the tool registry by workspace and answer server/discover without tools - #1478

Merged
helpcodeai merged 3 commits into
mainfrom
fix/mcp-discover-without-tools
Nov 3, 2026
Merged

helpcodeai merged 3 commits into
mainfrom
fix/mcp-discover-without-tools

Conversation

@helpcodeai

Copy link
Copy Markdown
Contributor

Summary

Cloud incident, 3 Nov 2026 ~09:20 UTC: a burst of Claude directory handshakes (server/discover + initialize on POST /mcp) made the backend CPU-bound, MCP p50 ~40 s and the dashboard 11-18 s, on both -1456 and -1462. A CPU profile of the live backend (anythingmcp-00) put 29.5 % inclusive in attachVisibleTools, 21.3 % self in getAllTools().filter(t => t.organizationId === …): every request copied the whole registry (~134k tools) into a new array and filtered it, plus ~8 % GC.

Changes

  • ToolRegistry: per-organization and per-connector indexes, kept on registerTool / unregisterConnectorTools, with getToolsForOrganization() and getToolsForConnectors() (same tools, same order as filtering the whole registry).
  • attachVisibleTools (shared /mcp), the tenant /mcp/:id path, the session refresh and the demo read those indexes instead of getAllTools().filter(...).
  • The role allow-list in attachVisibleTools is a Set (has instead of includes).
  • server/discover is answered from a server with the name, capabilities and instructions only, without building the tool set: on the shared endpoint before attachVisibleTools (instructions from the OAuth client's profile, as before), on /mcp/:id after the membership check and the instructions, with the same capabilities as a listen. Guards (auth, licence, verified email) are unchanged: they run before the handlers.
  • initialize keeps the full path (the setup/assistant logic runs on it); the index removes its registry scan.
  • registry-test-double.ts: specs that mock the registry with getAllTools get the index reads derived from it.

Type

  • Bug fix
  • Performance improvement

Testing

  • Added/updated unit tests: registry indexes (same result and order as a full filter, re-registration under another org/connector, unregister), shared server/discover without registry/grant reads and with instructions.
  • cd packages/backend && npx jest src/mcp-server: 40 suites passed, 643 tests passed (2 skipped as before).
  • npx tsc --noEmit -p tsconfig.json: no errors. npx eslint on the changed files: no errors.

Checklist

  • My code follows the existing code style
  • I have tested my changes locally
  • This PR has a descriptive title

Deployment

Same code path in Cloud and self-hosted; self-hosted registries are small, so the change matters on Cloud. Hotfix port: cloud/v0.51.7-1476 on top of cloud/v0.51.7-1456.

Related Issues

Cloud incident 2026-11-03.

@helpcodeai
helpcodeai merged commit 90d6762 into main Nov 3, 2026
14 checks passed
@helpcodeai
helpcodeai deleted the fix/mcp-discover-without-tools branch November 3, 2026 10:04
@github-actions github-actions Bot locked and limited conversation to collaborators Nov 3, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant