fec266a5ae
The three MCP testing improvements discussed in #23613 (now merged; this branch has been rebased onto main). ## What **1. Name-set assertions in `mcp-protocol.service.spec.ts`.** The two "exactly 6 tools" tests only used `expect.objectContaining` subset matches, so the size claim in the titles was never enforced and a new meta-tool would pass silently. They now assert the exact sorted key set of the ToolSet handed to the executor. This immediately caught real drift: the toolset has seven tools, and `get_tool_catalog` was missing from the expected list. **2. Catalog contract integration test** (`test/integration/ai/suites/mcp-tool-catalog.integration-spec.ts`). Calls `get_tool_catalog` over real HTTP with an API-key bearer, then for every advertised category dispatches one read-only tool (`find_/list_/get_/search_` prefixed, up to 3 candidates) through `execute_tool` and asserts a success envelope. Any newly registered provider is covered the moment it appears in the catalog, with no new test code. Categories with no read-only tool are compared exactly against a deliberate exception list, currently empty since every advertised category ships a read-only tool, so drift in either direction fails loudly. **3. Permission gating integration test** (same suite). Creates two API keys: one bound to Admin, one bound to a freshly created role with `canUpdateAllSettings: false` and no settings flags. Asserts the ROLE category (from #23613) is present in the admin catalog and absent from the restricted one, while the restricted key still sees DATABASE_CRUD read tools, proving it is gating rather than a broken catalog. This locks the provider `isAvailable` contract at the real HTTP boundary, which the unit mocks cannot. ## Testing - `npx jest src/engine/api/mcp` — 43 tests pass - `test/integration/ai/suites` — 4 suites, 24 tests pass locally against a reset DB - `npx nx typecheck twenty-server` clean; oxlint and oxfmt clean on the touched files --- _Generated by [Claude Code](https://claude.ai/code/session_0131sLKVsRuaDoaKCxFM8g4Z)_ <a href="https://cubic.dev/pr/twentyhq/twenty/pull/23630?utm_source=github" rel="nofollow noreferrer noopener" target="_blank">``<img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg">``</a>