Skip to content

[RUN-4805] Migrate the MCP SDK from v1 to v2 - #83

Merged
fdevans merged 7 commits into
mainfrom
sdk-update
Aug 20, 2026
Merged

fdevans merged 7 commits into
mainfrom
sdk-update

Conversation

@smartinellibenedetti

@smartinellibenedetti smartinellibenedetti commented Aug 19, 2026 •

Copy link
Copy Markdown
Contributor

About this change

Jira Ticket: RUN-4805

Purpose

Upgrades the server from MCP TypeScript SDK v1 to v2. Straight dependency/infra upgrade — no user-facing behavior changes.

This PR by itself does not make the MCP work with the latest protocol revision (2026-07-28). It only moves us onto the v2 SDK library. The changes that actually add support for the latest protocol revision are in a separate PR (#85).

What changed

  • SDK v1 → v2 (@modelcontextprotocol/sdk → server/client)
  • zod v3 → v4 (required by v2) — fixed the resulting breaking changes (z.record() signature, ZodError.issues)
  • Replaced zod-to-json-schema (silently broken under zod v4 — was emitting empty tool schemas) with zod's own z.toJSONSchema, plus a fix so published tool schemas still correctly say additionalProperties: false and don't mark optional params as required
  • @modelcontextprotocol/inspector bumped to v2 too
  • Cleaned up a couple of v1/zod-v3 leftovers that came in from other branches merged in during a rebase

Testing

npm run build && npm test && npm run validate all green (374/374 tests). CircleCI build/test/docker-build all green. Also manually verified the built server and Docker image respond correctly over real MCP stdio.

Development Checklist

  • npm run validate passes locally
  • Tests added/updated where needed
  • Docs download / RUNDECK_DOCS_PATH unaffected

@smartinellibenedetti
smartinellibenedetti marked this pull request as ready for review August 19, 2026 22:38
Copilot AI lite review requested due to automatic review settings August 19, 2026 22:38

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates the Rundeck MCP server from the v1 TypeScript SDK (@modelcontextprotocol/sdk) to the v2 split packages (@modelcontextprotocol/server / @modelcontextprotocol/client), including required Zod v4 upgrades and updated JSON Schema generation to satisfy v2’s stricter spec validation.

Changes:

  • Replace v1 SDK server/client imports with v2 packages and update request handler registration and result typing.
  • Upgrade Zod to v4 and adjust schemas (notably z.record(...)) and Zod error handling (.errors → .issues).
  • Replace zod-to-json-schema with z.toJSONSchema(..., { io: "input" }), add schema post-processing for additionalProperties, and extend integration tests to validate schema fidelity via a real client/server round trip.

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
TECHNICAL-CAPABILITIES.md Updates documentation to reflect v2 SDK + Zod v4 dependency changes.
src/tools/resources.ts Updates z.record usage for Zod v4 compatibility.
src/tools/jobs.ts Updates nested workflow schema z.record usage for Zod v4 compatibility.
src/tools/api.ts Updates request body/query param schemas for Zod v4 z.record signature.
src/index.ts Migrates server entry point to v2 SDK, updates handler wiring, and replaces JSON Schema generation.
src/tests/integration/integration-server-tool-gating.test.ts Migrates test client to v2 SDK and adds integration assertions for schema correctness.
package.json Switches dependencies from v1 SDK to v2 server/client packages and upgrades Zod.
package-lock.json Lockfile updates reflecting the dependency migration.
Suppressed comments (1)

src/index.ts:107

  • If schema conversion fails, the fallback JSON Schema currently omits additionalProperties: false, which can cause clients to accept arbitrary tool arguments (even though execution will still be rejected by Zod). To keep advertised schemas strict and consistent with the restoreAdditionalProperties intent, set additionalProperties: false on the fallback object schema as well.
  } catch (error) {
    logger.error("Error converting schema", error);
    return { type: "object", properties: {} };
  }

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread TECHNICAL-CAPABILITIES.md Outdated
Comment thread src/__tests__/integration/integration-server-tool-gating.test.ts Outdated
smartinellibenedetti and others added 4 commits August 19, 2026 17:32
Runs the official v1-to-v2 codemod (Server/Client packages, string-literal
request handler methods) plus the manual fixes it can't automate: bumps
zod to v4 (required by v2) and fixes the resulting z.record() signature
and ZodError.issues changes, types tools/call and prompts/get handlers
against the new strict CallToolResult/GetPromptResult schemas, fixes
prompts/get error paths that returned a non-spec-compliant isError/content
shape, and replaces zod-to-json-schema (incompatible with zod v4 — it was
silently emitting empty schemas) with zod's built-in z.toJSONSchema.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ation

zod v4's z.toJSONSchema(schema, { io: "input" }) — needed so optional
fields with a .default() (e.g. api_call's method) aren't misreported as
required — silently drops additionalProperties from plain z.object()
schemas, unlike the zod-to-json-schema output it replaced. That's a real
regression: clients validating tool arguments against the schema would no
longer catch unknown/misspelled params before calling.

Restores it in convertSchema() and adds integration coverage that drives
the real compiled server over stdio (the only way this surfaces, since it
depends on the SDK's own tools/list response validation) to check every
tool's inputSchema declares additionalProperties: false and that
optional/defaulted params never appear in required.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Bumps the inspector devDependency from ^1.0.0 to ^2.3.0 per
https://github.com/modelcontextprotocol/inspector/blob/main/docs/v1-to-v2-migration.md.
Our only invocation (npm run inspect -> mcp-inspector node dist/index.js)
has no CLI flags, so it's unaffected by v2's flag-ordering change and
needed no script updates — verified it still launches cleanly on the new
port layout (6274 web + 6275 sandbox, no 6277 proxy) with the new
MCP_INSPECTOR_API_TOKEN env var.

Also removes the now-dead overrides.@modelcontextprotocol/sdk.ajv pin:
the v1 SDK was inspector v1's last transitive dependent, and with it gone
the override was a no-op. Confirmed ajv still resolves safely to 8.20.0
on its own via inspector v2's direct dependency.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
smartinellibenedetti and others added 3 commits August 19, 2026 17:43
sdk-update was rebased onto a newer main that merged #81 (draft-port) and
#82 (RUN-4707-guidance), both developed against the pre-migration v1 SDK
and zod v3 — they broke the build against this branch's v2 SDK/zod v4:

- src/utils/confirmation.ts and its test imported
  @modelcontextprotocol/sdk/server/index.js (v1 path); fixed to
  @modelcontextprotocol/server.
- src/tools/jobs.ts had three new single-arg z.record(z.unknown()) calls
  (NotificationHook/LogFilter/plugin config fields) using the zod v3
  signature; fixed to the v4 two-arg form z.record(z.string(), z.unknown()),
  matching the fix already applied elsewhere in this migration.

Verified with npm ci && npm run build && npm test (CircleCI's exact
build/test steps): clean build, 374/374 tests, npm run validate passes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- TECHNICAL-CAPABILITIES.md: sync marked/yaml versions in the Dependencies
  section with package.json (^18.0.0 / 2.9.0), which had drifted.
- integration-server-tool-gating.test.ts: rename the schema-walk helper's
  `path` parameter to `schemaPath` — it shadowed the imported `path` module.
- index.ts: convertSchema()'s error fallback now also sets
  additionalProperties: false, matching restoreAdditionalProperties'
  intent — previously a conversion failure would advertise a schema that
  silently accepted arbitrary tool arguments (execution would still reject
  them via the underlying Zod parse, but the published schema was
  misleading).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
It duplicated package.json and kept drifting out of sync with it (Copilot
flagged this exact staleness on PR #83) — package.json is already the
authoritative source and doesn't need a second, manually-maintained copy.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@smartinellibenedetti smartinellibenedetti changed the title Migrate MCP TypeScript SDK v1 to v2 [RUN-4805] Migrate MCP TypeScript SDK v1 to v2 Aug 20, 2026
@smartinellibenedetti smartinellibenedetti changed the title [RUN-4805] Migrate MCP TypeScript SDK v1 to v2 [RUN-4805] Migrate the MCP SDK from v1 to v2 Aug 20, 2026
@fdevans
fdevans merged commit f69470b into main Aug 20, 2026
4 checks passed
@fdevans
fdevans deleted the sdk-update branch August 20, 2026 14:16
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.

3 participants