From dd0985cb11d3a1449d2658efa4e8cb17cbd4abeb Mon Sep 17 00:00:00 2001 From: Edison-A-N Date: Sun, 2 Nov 2025 11:39:35 +0800 Subject: [PATCH 01/10] fix: enhance resolution and enum handling in anyOf schemas --- client/src/utils/schemaUtils.ts | 92 +++++++++++++++++---------------- 1 file changed, 48 insertions(+), 44 deletions(-) diff --git a/client/src/utils/schemaUtils.ts b/client/src/utils/schemaUtils.ts index 36587021..d1ed1e96 100644 --- a/client/src/utils/schemaUtils.ts +++ b/client/src/utils/schemaUtils.ts @@ -149,20 +149,46 @@ export function isPropertyRequired( * Resolves $ref references in JSON schema * @param schema The schema that may contain $ref * @param rootSchema The root schema to resolve references against + * @param visitedRefs Optional set of visited $ref paths to detect circular references * @returns The resolved schema without $ref */ export function resolveRef( schema: JsonSchemaType, rootSchema: JsonSchemaType, + visitedRefs: Set = new Set(), ): JsonSchemaType { + if (!schema) return schema; + if (!("$ref" in schema) || !schema.$ref) { + // Recursively resolve $ref in anyOf (and other nested structures) + if (schema.anyOf && Array.isArray(schema.anyOf)) { + const resolvedAnyOf = schema.anyOf.map((item) => { + if (typeof item === "object" && item !== null) { + return resolveRef(item, rootSchema, visitedRefs); + } + return item; + }); + return { + ...schema, + anyOf: resolvedAnyOf, + }; + } return schema; } const ref = schema.$ref; - // Handle simple #/properties/name references + // Handle all #/ formats (#/properties/, #/$defs/, etc.) if (ref.startsWith("#/")) { + // Check for circular reference + if (visitedRefs.has(ref)) { + console.warn(`Circular reference detected: ${ref}`); + return schema; + } + + // Add current ref to visited set + visitedRefs.add(ref); + const path = ref.substring(2).split("/"); let current: unknown = rootSchema; @@ -176,12 +202,16 @@ export function resolveRef( current = (current as Record)[segment]; } else { // If reference cannot be resolved, return the original schema + visitedRefs.delete(ref); // Clean up on failure console.warn(`Could not resolve $ref: ${ref}`); return schema; } } - return current as JsonSchemaType; + const resolved = current as JsonSchemaType; + + // Recursively resolve nested structures (anyOf, oneOf, items, properties) + return resolveRef(resolved, rootSchema, visitedRefs); } // For other types of references, return the original schema @@ -195,54 +225,28 @@ export function resolveRef( * @returns A normalized schema or the original schema */ export function normalizeUnionType(schema: JsonSchemaType): JsonSchemaType { - // Handle anyOf with exactly string and null (FastMCP pattern) + // Handle anyOf with exactly 2 items (type and null) - unified handling + // Preserves enum and other properties automatically if ( schema.anyOf && schema.anyOf.length === 2 && - schema.anyOf.some((t) => (t as JsonSchemaType).type === "string") && schema.anyOf.some((t) => (t as JsonSchemaType).type === "null") ) { - return { ...schema, type: "string", anyOf: undefined, nullable: true }; - } + const nonNullItem = schema.anyOf.find((t) => { + const item = t as JsonSchemaType; + return item?.type !== "null"; + }) as JsonSchemaType; - // Handle anyOf with exactly boolean and null (FastMCP pattern) - if ( - schema.anyOf && - schema.anyOf.length === 2 && - schema.anyOf.some((t) => (t as JsonSchemaType).type === "boolean") && - schema.anyOf.some((t) => (t as JsonSchemaType).type === "null") - ) { - return { ...schema, type: "boolean", anyOf: undefined, nullable: true }; - } - - // Handle anyOf with exactly number and null (FastMCP pattern) - if ( - schema.anyOf && - schema.anyOf.length === 2 && - schema.anyOf.some((t) => (t as JsonSchemaType).type === "number") && - schema.anyOf.some((t) => (t as JsonSchemaType).type === "null") - ) { - return { ...schema, type: "number", anyOf: undefined, nullable: true }; - } - - // Handle anyOf with exactly integer and null (FastMCP pattern) - if ( - schema.anyOf && - schema.anyOf.length === 2 && - schema.anyOf.some((t) => (t as JsonSchemaType).type === "integer") && - schema.anyOf.some((t) => (t as JsonSchemaType).type === "null") - ) { - return { ...schema, type: "integer", anyOf: undefined, nullable: true }; - } - - // Handle anyOf with exactly array and null (FastMCP pattern) - if ( - schema.anyOf && - schema.anyOf.length === 2 && - schema.anyOf.some((t) => (t as JsonSchemaType).type === "array") && - schema.anyOf.some((t) => (t as JsonSchemaType).type === "null") - ) { - return { ...schema, type: "array", anyOf: undefined, nullable: true }; + // Only process if non-null item has type or enum + if (nonNullItem?.type || nonNullItem?.enum) { + return { + ...schema, + ...nonNullItem, + type: nonNullItem?.type || (nonNullItem?.enum ? "string" : undefined), + nullable: true, + anyOf: undefined, + }; + } } // Handle array type with exactly string and null From d73fb1c30f4fe35873e9d706005a29944853e5dd Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 12:36:30 +0000 Subject: [PATCH 02/10] fix: display tool title field in Inspector UI Display the MCP tool 'title' field when present in the Inspector UI, with fallback to 'name' when not present. This aligns with the MCP specification where 'title' is the human-friendly display name and 'name' is the programmatic identifier. Changes: - Updated tool list rendering to display tool.title || tool.name - Updated tool details header to display selectedTool.title || selectedTool.name Fixes #1053 Co-authored-by: Ola Hungerford --- client/src/components/ToolsTab.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/src/components/ToolsTab.tsx b/client/src/components/ToolsTab.tsx index 9e1b5d56..c581e98a 100644 --- a/client/src/components/ToolsTab.tsx +++ b/client/src/components/ToolsTab.tsx @@ -173,7 +173,7 @@ const ToolsTab = ({
- {tool.name} + {tool.title || tool.name} {tool.description} @@ -196,7 +196,9 @@ const ToolsTab = ({ /> )}

- {selectedTool ? selectedTool.name : "Select a tool"} + {selectedTool + ? selectedTool.title || selectedTool.name + : "Select a tool"}

From 613c650c40b055231300fe99eaf04bc9f869de43 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 13:26:54 +0000 Subject: [PATCH 03/10] Bump actions/setup-node from 4 to 6 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v4...v6) --- updated-dependencies: - dependency-name: actions/setup-node dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/cli_tests.yml | 2 +- .github/workflows/e2e_tests.yml | 2 +- .github/workflows/main.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cli_tests.yml b/.github/workflows/cli_tests.yml index ede7643e..3b46b431 100644 --- a/.github/workflows/cli_tests.yml +++ b/.github/workflows/cli_tests.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version-file: package.json cache: npm diff --git a/.github/workflows/e2e_tests.yml b/.github/workflows/e2e_tests.yml index 378905b4..abf260c3 100644 --- a/.github/workflows/e2e_tests.yml +++ b/.github/workflows/e2e_tests.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v6 id: setup_node with: node-version-file: package.json diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d01f7175..fbc4cf42 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,7 +17,7 @@ jobs: - name: Check formatting run: npx prettier --check . - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v6 with: node-version-file: package.json cache: npm @@ -51,7 +51,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v6 with: node-version-file: package.json cache: npm From bde1d59e8fcf1c7739ba5d25184d35d73bbfa60c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 13:27:00 +0000 Subject: [PATCH 04/10] Bump actions/upload-artifact from 4 to 6 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 6. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v4...v6) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/e2e_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e_tests.yml b/.github/workflows/e2e_tests.yml index 378905b4..fa12b62c 100644 --- a/.github/workflows/e2e_tests.yml +++ b/.github/workflows/e2e_tests.yml @@ -51,7 +51,7 @@ jobs: run: npm run test:e2e - name: Upload Playwright Report and Screenshots - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 if: steps.playwright-tests.conclusion != 'skipped' with: name: playwright-report From 742f27dc7abf31cc85d1658593ecf97c6b183d14 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 13:27:04 +0000 Subject: [PATCH 05/10] Bump actions/attest-build-provenance from 2 to 3 Bumps [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) from 2 to 3. - [Release notes](https://github.com/actions/attest-build-provenance/releases) - [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md) - [Commits](https://github.com/actions/attest-build-provenance/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/attest-build-provenance dependency-version: '3' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d01f7175..7c5bb174 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -109,7 +109,7 @@ jobs: labels: ${{ steps.meta.outputs.labels }} - name: Generate artifact attestation - uses: actions/attest-build-provenance@v2 + uses: actions/attest-build-provenance@v3 with: subject-name: ghcr.io/${{ github.repository }} subject-digest: ${{ steps.push.outputs.digest }} From a68211b3e40520bca80cb8810e7d47bd222669e3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 13:27:09 +0000 Subject: [PATCH 06/10] Bump actions/cache from 4 to 5 Bumps [actions/cache](https://github.com/actions/cache) from 4 to 5. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/cache dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/e2e_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e_tests.yml b/.github/workflows/e2e_tests.yml index 378905b4..c3f27a4a 100644 --- a/.github/workflows/e2e_tests.yml +++ b/.github/workflows/e2e_tests.yml @@ -29,7 +29,7 @@ jobs: # Cache Playwright browsers - name: Cache Playwright browsers id: cache-playwright - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: ~/.cache/ms-playwright # The default Playwright cache path key: ${{ runner.os }}-playwright-${{ hashFiles('package-lock.json') }} # Cache key based on OS and package-lock.json From 0f253927d1cc52d036ca6c1d06913b5a99560723 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 13:27:13 +0000 Subject: [PATCH 07/10] Bump actions/github-script from 7 to 8 Bumps [actions/github-script](https://github.com/actions/github-script) from 7 to 8. - [Release notes](https://github.com/actions/github-script/releases) - [Commits](https://github.com/actions/github-script/compare/v7...v8) --- updated-dependencies: - dependency-name: actions/github-script dependency-version: '8' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/claude.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 23a66f86..52ca5ce4 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -33,7 +33,7 @@ jobs: github.event_name == 'pull_request_review_comment' || github.event_name == 'pull_request_review' id: pr - uses: actions/github-script@v7 + uses: actions/github-script@v8 with: script: | let prNumber; From 39c2c9f8ce41957018e391cace9b794bec05071f Mon Sep 17 00:00:00 2001 From: David Soria Parra Date: Mon, 9 Feb 2026 18:27:16 +0000 Subject: [PATCH 08/10] Remove environment constraint from release workflow jobs Co-Authored-By: Claude Opus 4.6 --- .github/workflows/main.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 96262fda..60262085 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -42,7 +42,6 @@ jobs: publish: runs-on: ubuntu-latest if: github.event_name == 'release' - environment: release needs: build permissions: @@ -69,7 +68,6 @@ jobs: publish-github-container-registry: runs-on: ubuntu-latest if: github.event_name == 'release' - environment: release needs: build permissions: contents: read From 1f424f252546b8611e275a158d1756fd30517d87 Mon Sep 17 00:00:00 2001 From: David Soria Parra Date: Mon, 9 Feb 2026 18:30:00 +0000 Subject: [PATCH 09/10] Revert "Remove environment constraint from release workflow jobs" This reverts commit 39c2c9f8ce41957018e391cace9b794bec05071f. --- .github/workflows/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 60262085..96262fda 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -42,6 +42,7 @@ jobs: publish: runs-on: ubuntu-latest if: github.event_name == 'release' + environment: release needs: build permissions: @@ -68,6 +69,7 @@ jobs: publish-github-container-registry: runs-on: ubuntu-latest if: github.event_name == 'release' + environment: release needs: build permissions: contents: read From 1f9d922475b8cd0598bea0d3306f24935cda9cbf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Feb 2026 23:27:21 +0000 Subject: [PATCH 10/10] Bump actions/checkout from 4 to 6 Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/claude.yml | 4 ++-- .github/workflows/cli_tests.yml | 2 +- .github/workflows/e2e_tests.yml | 2 +- .github/workflows/main.yml | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 52ca5ce4..9fdebc23 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -54,7 +54,7 @@ jobs: - name: Checkout PR branch if: steps.pr.outcome == 'success' - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: ref: ${{ steps.pr.outputs.sha }} repository: ${{ steps.pr.outputs.repo }} @@ -62,7 +62,7 @@ jobs: - name: Checkout repository if: steps.pr.outcome != 'success' - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: 0 diff --git a/.github/workflows/cli_tests.yml b/.github/workflows/cli_tests.yml index 3b46b431..106d98f1 100644 --- a/.github/workflows/cli_tests.yml +++ b/.github/workflows/cli_tests.yml @@ -15,7 +15,7 @@ jobs: run: working-directory: ./cli steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up Node.js uses: actions/setup-node@v6 diff --git a/.github/workflows/e2e_tests.yml b/.github/workflows/e2e_tests.yml index 4d0c4cec..4013a905 100644 --- a/.github/workflows/e2e_tests.yml +++ b/.github/workflows/e2e_tests.yml @@ -18,7 +18,7 @@ jobs: sudo apt-get update sudo apt-get install -y libwoff1 - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: actions/setup-node@v6 id: setup_node diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 96262fda..2cc4537b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Check formatting run: npx prettier --check . @@ -50,7 +50,7 @@ jobs: id-token: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: actions/setup-node@v6 with: node-version-file: package.json @@ -77,7 +77,7 @@ jobs: attestations: write id-token: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Log in to the Container registry uses: docker/login-action@v3