Skip to content

Dedupe MCP-registry tool names across orgs/connectors#152

Merged
keysersoft merged 1 commit into
mainfrom
keysersoft/dedupe-mcp-registration
May 10, 2026
Merged

Dedupe MCP-registry tool names across orgs/connectors#152
keysersoft merged 1 commit into
mainfrom
keysersoft/dedupe-mcp-registration

Conversation

@keysersoft
Copy link
Copy Markdown
Contributor

Summary

Silences the `Dynamic tool 'X' already registered in module — Overwriting.` warnings emitted at boot by aligning our registration logic with the upstream library's single-tenant assumption.

Why

Production logs on `cloud.anythingmcp.com` showed 12 such warnings at startup, covering 8 unique tool names. Triage:

  • 3 organizations each imported the Weclapp adapter → 6 cross-tenant duplicates (`weclapp_*`).
  • 1 organization has two distinct, legitimate connectors ("Udyogi - PROD" and "Param - Prod") that share two tool names (`sales_register_prod`, `purchase_register_prod`) — neither is an accidental import.

Our `ToolRegistry` already handles cross-tenant collisions correctly (`getToolForOrg`, `getTool(name, connectorIds)`). Only the upstream `@rekog/mcp-nest` `McpRegistryService` (single-tenant) was generating noise.

Change

  • `ToolRegistry.countByName(name)` — new O(1) helper.
  • `McpServerService.loadAllTools` / `reloadConnectorTools` — register a name on the upstream MCP registry only when it first appears in our `ToolRegistry`, and remove it only when the last entry leaves.

Test plan

  • `npx jest src/mcp-server/tool-registry.spec.ts` → 15/15 passed (added 3 new for `countByName`).
  • `npm test` → 601 passed across 24 suites.
  • `tsc --noEmit` → exit 0.
  • After deploy: re-check `docker logs amcp-cloud-app | grep 'already registered'` → expect 0 lines.

The upstream @rekog/mcp-nest McpRegistryService is single-tenant: it
keys tools by name and warns 'already registered ... Overwriting' if
the same name is registered twice. Our internal ToolRegistry is
multi-tenant — same tool name can legitimately exist for multiple
orgs (e.g. 3 customers each importing the Weclapp adapter) or for
multiple connectors in the same org (e.g. 'Udyogi - PROD' and
'Param - Prod' exposing identical schemas).

On boot we were emitting one warning per duplicate (12 lines on the
production server). Functionally correct — the handler dispatches
via getToolForOrg / getTool + connectorIds — but noisy.

Now mcpRegistry.registerTool is called only when the name first
appears in our ToolRegistry; subsequent registrations under the same
name are skipped because the upstream registry already exposes one.
On unload, mcpRegistry.removeTool is called only when the last tool
with that name leaves our registry — otherwise we'd tear down a name
another tenant still needs.

Adds ToolRegistry.countByName(name) for O(1) lookups and a small test
suite covering it.
@keysersoft keysersoft force-pushed the keysersoft/dedupe-mcp-registration branch from 6d3a3e6 to ceee721 Compare May 10, 2026 13:08
@keysersoft keysersoft merged commit 3e034be into main May 10, 2026
10 checks passed
@keysersoft keysersoft deleted the keysersoft/dedupe-mcp-registration branch May 10, 2026 13:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant