{"id":"24888104-b03c-4937-bd42-05b2dfbbd242","slug":"toolclash","kind":"mcp","name":"toolclash","summary":"Find naming, contract, and context collisions across MCP tool catalogs","owner":"jovial-liu","repoUrl":"https://github.com/jovial-liu/toolclash","license":"MIT","licenseTier":"permissive","trust":"community","stars":0,"match":null,"fewStars":true,"format":"mcp","createdAt":"2026-08-23T09:48:27.000Z","addedAt":"2026-10-28T21:48:19.765Z","logoUrl":"https://avatars.githubusercontent.com/u/184472154?u=9627239e961d0d6fa8284d5032a810ec668e81b6&v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["memory-knowledge","developer-tools"],"tags":["ai-agents","developer-tools","schema","security","testing"],"runtime":"node","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-28T21:48:45.705Z","sample":false,"url":"https://conduits.dev/tools/toolclash","language":"JavaScript","transports":["stdio"],"install":{"npm":"toolclash"},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"# toolclash\n\n**Find MCP tool collisions before your agent loads them.**\n\n`toolclash` compares multiple MCP tool catalogs for exact names, normalization collisions, incompatible schemas, annotation disagreement, near-duplicate purpose, and combined context cost—then produces a deterministic namespace plan.\n\n![Toolclash report showing two MCP catalogs, collisions, and namespaced aliases](demo.svg)\n\n```bash\nnpx --yes github:jovial-liu/toolclash#v1 scan files.json docs.json --strict\n```\n\nNo server startup, tool execution, model call, account, telemetry, or upload. Node.js 20+; zero runtime dependencies.\n\n## Why this exists\n\nMCP servers are usually tested one at a time, but agents consume a combined tool surface. Two healthy servers can still create an unhealthy catalog:\n\n- both export `search`, with different arguments;\n- one exports `read_file`, another `read-file`;\n- identical-looking tools disagree about whether they are read-only;\n- several tools describe nearly the same action and waste selection context;\n- the combined schemas consume thousands of tokens before any result appears.\n\n`toolclash` checks the composition boundary.\n\n```text\nworkspace-files/search  ↔  team-docs/search\n  TC001 exact name collision\n  TC003 incompatible input schema\n\nworkspace-files/read_file  ↔  team-docs/read-file\n  TC002 normalized name collision\n  TC003 incompatible input schema\n```\n\n## Create catalogs\n\nThe recommended input is a JSON report from [`mcpdoctor`](https://github.com/jovial-liu/mcpdoctor):\n\n```bash\nnpx --yes github:jovial-liu/mcpdoctor#v1 \\\n  --format json --out files.json -- npx -y @modelcontextprotocol/server-filesystem .\n```\n\nAny JSON object with a `tools` array also works. Server identity is read from `serverName`, `server`, or `name`, falling back to the input filename.\n\n## Scan the combined surface\n\n```bash\ntoolclash scan files.json docs.json database.json \\\n  --similarity 0.72 \\\n  --budget 8000 \\\n  --format html \\\n  --out toolclash.html \\\n  --strict\n```\n\nFormats are `json`, `markdown`, and self-contained offline `html`. `--strict` exits 1 when errors or warnings exist.\n\n## Generate a namespace plan\n\n```bash\ntoolclash aliases files.json docs.json --format json\n```\n\nExample:\n\n```json\n{\n  \"server\": \"workspace-files\",\n  \"tool\": \"search\",\n  \"alias\": \"workspace-files__search\",\n  \"reason\": \"collision\"\n}\n```\n\nOnly colliding names are changed. If multiple catalogs claim the same server name, stable catalog ordinals keep aliases unique. The plan is advisory: apply it in your MCP host, gateway, or wrapper according to that product's configuration model.\n\n## Finding codes\n\n| Code | Meaning |\n| --- | --- |\n| `TC001` | Exact tool name appears in multiple servers |\n| `TC002` | Names differ only after punctuation/case normalization |\n| `TC003` | Colliding names expose different input schemas |\n| `TC004` | Colliding tools disagree on `readOnlyHint` |\n| `TC005` | Names/descriptions indicate a near-duplicate purpose |\n| `TC006` | Combined definitions exceed the configured token budget |\n\nNear-duplicate matching is a transparent Jaccard score over normalized words, not an embedding or model judgment. Tune `--similarity`; inspect every result before removing or aliasing a tool.\n\n## Context estimate\n\nEach tool's description, input/output schemas, and annotations are serialized deterministically, measured as UTF-8 bytes, and divided by four. Reports say `~tokens` because real tokenization depends on the host, model, and wire representation.\n\nUse [`prompttax`](https://github.com/jovial-liu/prompttax) when you also need repository instruction costs. `toolclash` stays focused on cross-server composition.\n\n## Safety boundary\n\n- Catalogs are parsed as local data.\n- Server commands in reports are ignored.\n- No MCP lifecycle request or tool call is made.\n- Absolute input paths are reduced to basenames.\n- Tool descriptions can be untrusted text; HTML output escapes them.\n- A clean report is not proof that tools are safe, authorized, or semantically correct.\n\nFor live protocol negotiation and individual-server checks, use `mcpdoctor`. For call authorization policy, use [`toolgate`](https://github.com/jovial-liu/toolgate).\n\n## Development\n\n```bash\nnpm run check\nnode src/cli.mjs scan examples/files.json examples/docs.json\n```\n\nContributions should include minimal catalog fixtures. See [CONTRIBUTING.md](CONTRIBUTING.md) and [SECURITY.md](SECURITY.md).\n\nMIT licensed.\n"}