From 5665e7cb96a4ee8502106c10152bbd0ffc83ad37 Mon Sep 17 00:00:00 2001 From: CodeMash Date: Tue, 13 Oct 2026 12:34:40 +0300 Subject: [PATCH 1/2] build(deps): @norbix.ai/ts ^4.23.0 (MCP tool catalog, route 24) Co-Authored-By: Claude Opus 5.5 --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 902f927..1df7334 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@commitlint/cli": "^21.2.2", "@commitlint/config-conventional": "^21.2.2", "@eslint/js": "^10.0.1", - "@norbix.ai/ts": "^4.22.0", + "@norbix.ai/ts": "^4.23.0", "@reduxjs/toolkit": "^2.12.0", "@semantic-release/commit-analyzer": "^13.0.1", "@semantic-release/github": "^12.0.9", @@ -1490,9 +1490,9 @@ } }, "node_modules/@norbix.ai/ts": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@norbix.ai/ts/-/ts-4.22.0.tgz", - "integrity": "sha512-l3ktvdYIQ4ffu9RZiJM6WJMfZdwc5vWr9EO2KzXEWeNm1wO92d4mBzOlv1rbeY3cEjFegXTAHH49oo5cUSbHdQ==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/@norbix.ai/ts/-/ts-4.23.0.tgz", + "integrity": "sha512-NWac3JPPoDJ4Y/2wmjgvkfoS2sqghrdr5rv9JwTca5va9/cLX7XThqk6G9a1bxmaeExwMHPh1Qj5VwmSI3v2Gw==", "dev": true, "license": "MIT", "engines": { diff --git a/package.json b/package.json index 3b8cd60..7df230d 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "@commitlint/cli": "^21.2.2", "@commitlint/config-conventional": "^21.2.2", "@eslint/js": "^10.0.1", - "@norbix.ai/ts": "^4.22.0", + "@norbix.ai/ts": "^4.23.0", "@reduxjs/toolkit": "^2.12.0", "@semantic-release/commit-analyzer": "^13.0.1", "@semantic-release/github": "^12.0.9", From 4826fec55b3ed5252720655c6eacec6d981ee9d4 Mon Sep 17 00:00:00 2001 From: CodeMash Date: Tue, 13 Oct 2026 12:34:40 +0300 Subject: [PATCH 2/2] feat(marketplace): useGetMarketplaceIntegrationToolsQuery, the MCP tool catalog Wraps hub.code.getMarketplaceIntegrationTools from @norbix.ai/ts 4.23.0 (GET /{version}/code/marketplace/integrations/{IntegrationViewId}/tools). Provides CodeMarketplace/TOOLS:; validation (test) and delete invalidate it. Route table 23 -> 24, tag tests, README row. Co-Authored-By: Claude Opus 5.5 --- README.md | 2 +- src/hooks/hub/marketplace.ts | 13 ++++++++++++- tests/marketplace.test.ts | 16 ++++++++++++++-- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 27677a6..4dd7334 100644 --- a/README.md +++ b/README.md @@ -555,7 +555,7 @@ added on a connection (`func_…`). Every tag is of type `CodeMarketplace`. | Area | Hooks | Cache tag (`CodeMarketplace/…`) | | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------- | | Catalog | `useGetMarketplaceListingsQuery`, `useGetMarketplaceListingQuery`, `useGetMarketplaceListingFunctionTokensQuery` | provides `LISTINGS` | -| Connections | `useGetMarketplaceIntegrationsQuery`, `useGetMarketplaceIntegrationQuery`, `useSaveMarketplaceIntegrationMutation`, `useDeleteMarketplaceIntegrationMutation`, `useEnableMarketplaceIntegrationMutation`, `useDisableMarketplaceIntegrationMutation`, `useReplaceMarketplaceIntegrationSecretsMutation`, `useRevealMarketplaceIntegrationSecretsMutation`, `useSetMarketplaceIntegrationTokenMappingsMutation`, `useTestMarketplaceIntegrationMutation`, `useGetMarketplaceFunctionCatalogQuery` | `INTEGRATIONS`, ``, `CATALOG:`; reveal touches nothing | +| Connections | `useGetMarketplaceIntegrationsQuery`, `useGetMarketplaceIntegrationQuery`, `useSaveMarketplaceIntegrationMutation`, `useDeleteMarketplaceIntegrationMutation`, `useEnableMarketplaceIntegrationMutation`, `useDisableMarketplaceIntegrationMutation`, `useReplaceMarketplaceIntegrationSecretsMutation`, `useRevealMarketplaceIntegrationSecretsMutation`, `useSetMarketplaceIntegrationTokenMappingsMutation`, `useTestMarketplaceIntegrationMutation`, `useGetMarketplaceFunctionCatalogQuery`, `useGetMarketplaceIntegrationToolsQuery` (the stored MCP tool catalog of an MCP connection, core SDK 4.23.0+) | `INTEGRATIONS`, ``, `CATALOG:`, `TOOLS:` (test and delete invalidate it); reveal touches nothing | | Functions | `useGetMarketplaceFunctionsQuery`, `useGetMarketplaceFunctionQuery`, `useSaveMarketplaceFunctionMutation`, `useDeleteMarketplaceFunctionMutation`, `useEnableMarketplaceFunctionMutation`, `useDisableMarketplaceFunctionMutation`, `useGetMarketplaceFunctionTokensQuery`, `useInvokeMarketplaceFunctionMutation`, `useGetMarketplaceFunctionRunsQuery` | `FUNCTIONS:`, ``, `RUNS`; invoke touches nothing | Revealing secrets is a mutation on purpose: a query would keep the clear values diff --git a/src/hooks/hub/marketplace.ts b/src/hooks/hub/marketplace.ts index 76a1209..2af232e 100644 --- a/src/hooks/hub/marketplace.ts +++ b/src/hooks/hub/marketplace.ts @@ -16,6 +16,8 @@ import type { Arg, Result } from '../types.js'; * - `` — one connection (secrets, token mappings and the * last validation steps live on it) * - `CATALOG:` — the vendor functions a connection offers + * - `TOOLS:` — the stored MCP tool catalog of an MCP connection; + * validation (test) rewrites it (core SDK 4.23.0) * - `FUNCTIONS:`— the functions added on a connection * - `` — one function and its tokens * - `RUNS` — the last runs of a trigger or task (core SDK 4.21.0) @@ -41,6 +43,7 @@ export const hubCodeMarketplace = (b: Builder) => { type SetTokenMappings = Fn<'setMarketplaceIntegrationTokenMappings'>; type TestIntegration = Fn<'testMarketplaceIntegration'>; type GetCatalog = Fn<'getMarketplaceFunctionCatalog'>; + type GetTools = Fn<'getMarketplaceIntegrationTools'>; type GetFunctions = Fn<'getMarketplaceFunctions'>; type GetFunction = Fn<'getMarketplaceFunction'>; type SaveFunction = Fn<'saveMarketplaceFunction'>; @@ -108,6 +111,7 @@ export const hubCodeMarketplace = (b: Builder) => { invalidatesTags: (_res, _err, arg) => [ ...integration(arg), { type: T, id: `FUNCTIONS:${integrationId(arg)}` }, + { type: T, id: `TOOLS:${integrationId(arg)}` }, ], }), enableMarketplaceIntegration: b.mutation, Arg>({ @@ -134,12 +138,19 @@ export const hubCodeMarketplace = (b: Builder) => { }), testMarketplaceIntegration: b.mutation, Arg>({ query: (args) => (norbix) => callHC(norbix).testMarketplaceIntegration(args), - invalidatesTags: (_res, _err, arg) => [{ type: T, id: integrationId(arg) }], + invalidatesTags: (_res, _err, arg) => [ + { type: T, id: integrationId(arg) }, + { type: T, id: `TOOLS:${integrationId(arg)}` }, + ], }), getMarketplaceFunctionCatalog: b.query, Arg>({ query: (args) => (norbix) => callHC(norbix).getMarketplaceFunctionCatalog(args), providesTags: (_res, _err, arg) => [{ type: T, id: `CATALOG:${integrationId(arg)}` }], }), + getMarketplaceIntegrationTools: b.query, Arg>({ + query: (args) => (norbix) => callHC(norbix).getMarketplaceIntegrationTools(args), + providesTags: (_res, _err, arg) => [{ type: T, id: `TOOLS:${integrationId(arg)}` }], + }), // ---- Functions on a connection ---- getMarketplaceFunctions: b.query, Arg>({ diff --git a/tests/marketplace.test.ts b/tests/marketplace.test.ts index e062f4f..dc4a7eb 100644 --- a/tests/marketplace.test.ts +++ b/tests/marketplace.test.ts @@ -98,6 +98,7 @@ const CASES: Array< ], ['testMarketplaceIntegration', 'mutation', 'POST', `${I}/test`, IDS, {}], ['getMarketplaceFunctionCatalog', 'query', 'GET', `${I}/catalog`, IDS, {}], + ['getMarketplaceIntegrationTools', 'query', 'GET', `${I}/tools`, IDS, {}], ['getMarketplaceFunctions', 'query', 'GET', `${I}/functions`, IDS, {}], ['getMarketplaceFunction', 'query', 'GET', `${I}/functions/${FUNCTION}`, FN_IDS, {}], [ @@ -152,7 +153,7 @@ function tagsFor(tags: Tags | undefined, arg: unknown): unknown { const endpoints = hubCodeMarketplace(fakeBuilder()) as unknown as Record; describe('hubCodeMarketplace', () => { - it('wraps the 23 marketplace methods of the published core SDK', () => { + it('wraps the 24 marketplace methods of the published core SDK', () => { expect(Object.keys(endpoints).sort()).toEqual([...NAMES].sort()); }); @@ -202,6 +203,7 @@ describe('hubCodeMarketplace', () => { { type: 'CodeMarketplace', id: 'INTEGRATIONS' }, { type: 'CodeMarketplace', id: INTEGRATION }, { type: 'CodeMarketplace', id: `FUNCTIONS:${INTEGRATION}` }, + { type: 'CodeMarketplace', id: `TOOLS:${INTEGRATION}` }, ]); expect(tagsFor(endpoints['saveMarketplaceIntegration']!.invalidatesTags, {})).toEqual([ { type: 'CodeMarketplace', id: 'INTEGRATIONS' }, @@ -209,12 +211,22 @@ describe('hubCodeMarketplace', () => { for (const key of [ 'replaceMarketplaceIntegrationSecrets', 'setMarketplaceIntegrationTokenMappings', - 'testMarketplaceIntegration', ]) { expect(tagsFor(endpoints[key]!.invalidatesTags, IDS)).toEqual([ { type: 'CodeMarketplace', id: INTEGRATION }, ]); } + // Validation lists the MCP server's tools again and stores the catalog (gateway item mcp-step1). + expect(tagsFor(endpoints['testMarketplaceIntegration']!.invalidatesTags, IDS)).toEqual([ + { type: 'CodeMarketplace', id: INTEGRATION }, + { type: 'CodeMarketplace', id: `TOOLS:${INTEGRATION}` }, + ]); + }); + + it('the MCP tool catalog provides TOOLS: (core SDK 4.23.0)', () => { + expect(tagsFor(endpoints['getMarketplaceIntegrationTools']!.providesTags, IDS)).toEqual([ + { type: 'CodeMarketplace', id: `TOOLS:${INTEGRATION}` }, + ]); }); it('the last runs provide CodeMarketplace/RUNS', () => {