Repository navigation
Index the tool registry by workspace and answer server/discover without tools - #1478
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Cloud incident, 3 Nov 2026 ~09:20 UTC: a burst of Claude directory handshakes (
server/discover+initializeonPOST /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 inattachVisibleTools, 21.3 % self ingetAllTools().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 onregisterTool/unregisterConnectorTools, withgetToolsForOrganization()andgetToolsForConnectors()(same tools, same order as filtering the whole registry).attachVisibleTools(shared/mcp), the tenant/mcp/:idpath, the session refresh and the demo read those indexes instead ofgetAllTools().filter(...).attachVisibleToolsis aSet(hasinstead ofincludes).server/discoveris answered from a server with the name, capabilities and instructions only, without building the tool set: on the shared endpoint beforeattachVisibleTools(instructions from the OAuth client's profile, as before), on/mcp/:idafter 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.initializekeeps 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 withgetAllToolsget the index reads derived from it.Type
Testing
server/discoverwithout 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 eslinton the changed files: no errors.Checklist
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-1476on top ofcloud/v0.51.7-1456.Related Issues
Cloud incident 2026-11-03.