Skip to content

refactor(mcp-server): replace SDK with xmcp framework and dual-runtime sandbox#34904

Merged
fmontes merged 64 commits into
mainfrom
mcp-server-2
Jun 8, 2026
Merged

refactor(mcp-server): replace SDK with xmcp framework and dual-runtime sandbox#34904
fmontes merged 64 commits into
mainfrom
mcp-server-2

Conversation

@fmontes

@fmontes fmontes commented Mar 8, 2026

Copy link
Copy Markdown
Member

Summary

Complete rewrite of the MCP server replacing @modelcontextprotocol/sdk + esbuild with the xmcp framework (rspack-based).

Why?

Because Anthropic demostrate that models are better writing code that calling tools and Cloudfare had a similar problem that us... too many endpoints:

New Architecture

  • xmcp framework — Tools auto-discovered from src/tools/, each exports schema, metadata, and a handler. No manual server wiring. See xmcp.config.ts.

  • Sandbox isolation — AI-generated code runs in isolated Workers. API tokens never enter the sandbox; an adapter pattern bridges sandbox↔main thread for authenticated HTTP calls. See src/lib/sandbox/ and src/lib/http-client.ts.

  • Dual-runtime support — Sandbox works on both Node.js (worker_threads) and Bun (Web Workers), detected automatically at startup. See src/lib/sandbox/index.ts.

  • Build-time spec processing — OpenAPI spec is dereferenced, filtered, and compacted at build time. See scripts/generate-spec.ts.

  • Two toolssearch (explore API spec) and execute (make API calls), both via sandboxed JS execution. See src/tools/.

Key Files

File Purpose
src/tools/search.ts API spec exploration tool
src/tools/execute.ts Authenticated API execution tool
src/lib/executor.ts Sandbox orchestration
src/lib/http-client.ts Authenticated HTTP adapter
src/lib/sandbox/bun-worker.ts Bun Web Worker sandbox
src/lib/sandbox/node-worker.ts Node.js worker_threads sandbox
CLAUDE.md Full architecture reference

Test plan

  • yarn nx build mcp-server — produces dist/apps/mcp-server/stdio.js + chunks
  • yarn nx test mcp-server — passes
  • yarn nx lint mcp-server — passes
  • npm pack --dry-run — 5 files, 167KB, correct paths
  • node dist/apps/mcp-server/stdio.js — runs without missing dependency errors
  • Test with MCP Inspector against a live dotCMS instance
  • Test with Claude Desktop / Cursor

🤖 Generated with Claude Code


Note

High Risk
High risk due to a full rewrite of the MCP server runtime/build pipeline and removal of prior tool/service implementations, plus introduction of sandboxed code execution and HTTP adapter behavior that directly affects authenticated API calls.

Overview
Replaces the @modelcontextprotocol/sdk-based MCP server (manual tool registration + service layer) with an xmcp-based build that auto-discovers tools and outputs a new entrypoint dist/apps/mcp-server/stdio.js.

Introduces two sandboxed JS tools: search (runs code against a build-time processed OpenAPI spec) and execute (runs code that calls an injected api.request adapter), including a dual-runtime Worker sandbox (Node worker_threads vs Bun Web Workers), sandbox timeouts (SANDBOX_TIMEOUT), blocked direct network access inside the sandbox, and a new authenticated HTTP adapter with path validation and multipart formData support.

Adds an OpenAPI spec generation step (scripts/generate-spec.ts) wired into Nx targets (generate-spec, new build/serve via xmcp), updates Jest/NPM packaging metadata for the new entrypoint/version, and refreshes docs/examples (README.md, CLAUDE.md, .env.example, .gitignore) accordingly.

Reviewed by Cursor Bugbot for commit a5fb0b0. Bugbot is set up for automated code reviews on this repo. Configure here.

This PR fixes: #35978

fmontes and others added 4 commits March 7, 2026 23:16
…mework

Replace the MCP server implementation with xmcp-based architecture featuring
sandbox-isolated code execution, OpenAPI spec exploration, and build-time
spec processing. Two tools: search (explore API spec) and execute (make
authenticated API calls).

- Switch build from @nx/esbuild to nx:run-commands + xmcp build (rspack)
- Add bundler config to output directly to dist/apps/mcp-server
- Add generate-spec target to process openapi.json at build time
- Add xmcp, @apidevtools/swagger-parser, tsx dependencies
- Update env vars: DOTCMS_BASE_URL, DOTCMS_API_TOKEN, SANDBOX_TIMEOUT

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… support

The sandbox previously only worked with Bun Web Workers. Add a
NodeWorkerSandbox using worker_threads so the server runs on both
Node.js and Bun. Runtime is detected automatically via globalThis.Bun.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Paths now reference ./stdio.js instead of ./dist/stdio.js since the
published package has files at the root. Remove xmcp and zod from
dependencies since they are fully bundled by rspack.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… beta

Update all setup examples to use @dotcms/mcp-server@beta tag.
Fix TypeScript error in sandbox runtime detection.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@fmontes fmontes requested review from a team, AP2300, Copilot, hmoreras and zJaaal and removed request for a team March 8, 2026 19:39
@github-actions github-actions Bot added the Area : Frontend PR changes Angular/TypeScript frontend code label Mar 8, 2026
@claude

claude Bot commented Mar 8, 2026

Copy link
Copy Markdown
Contributor

Claude finished @fmontes's task in 2m 38s —— View job


Rollback Safety Analysis

  • Read rollback-unsafe categories reference
  • Get full PR diff
  • Analyze diff against all unsafe categories
  • Post result and apply label

Result: Pull Request Unsafe to Rollback

Category: M-3 — REST / GraphQL / Headless API Contract Change
Risk Level: 🟡 MEDIUM

The MCP server rewrite itself (frontend/TypeScript) introduces no rollback risk. The Java-side changes in this PR carry three breaking-on-rollback API contract changes:

  1. New HTTP 422 responsePUT /api/v1/workflow/contentlet/actions/bulk/fire now returns 422 when every contentlet is skipped due to a scheme mismatch. N-1 returns 200 for the same input, so clients updated to branch on 422 will silently succeed on rollback.

  2. New HTTP 400 responsesPUT /api/v1/workflow/actions/{actionId}/fire and the fire-merge endpoint now throw 400 for pathToMove without a Move actionlet, or for system fields (host/folder) in the contentlet body. N-1 silently ignores these, masking caller bugs after rollback.

  3. New skipReason field + required schema annotationBulkActionsResultView gains skipReason (clients reading it get null on N-1); FireBulkActionsForm.workflowActionId is now required=true in the OpenAPI spec — code-generated clients will enforce this client-side even after rollback.

The rollback-unsafe comment was posted directly on the PR and the label AI: Not Safe To Rollback was applied.

… file

Remove the 762KB openapi.json from the repo. The generate-spec script
now requires a URL or local file path as an argument and fails with
clear usage instructions if none is provided.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@claude

claude Bot commented Mar 8, 2026

Copy link
Copy Markdown
Contributor

Claude finished @fmontes's task —— View job


Code Review Complete

Reviewed this MCP server rewrite for potential issues, security concerns, and design problems.

Review Checklist

  • Analyze core architecture changes
  • Review sandbox security implementation
  • Check HTTP client authentication patterns
  • Validate worker thread lifecycle management
  • Review dual-runtime compatibility
  • Check build configuration changes
  • Identify missing edge cases or risks

Critical Issues Found

🔴 CRITICAL: Code Injection Vulnerability

  • src/lib/sandbox/node-worker.ts:235 and src/lib/sandbox/bun-worker.ts:234
  • Both sandboxes use AsyncFunction constructor with AI-generated code: new AsyncFunction(data.code)
  • Risk: Malicious MCP clients could inject arbitrary JavaScript beyond intended sandbox constraints
  • Recommendation: Implement proper code validation, AST parsing, or use a more restrictive execution environment

🟡 Security & Design Concerns

  1. Missing Memory Limits: memoryLimit config option exists but isn't enforced in either sandbox implementation

  2. Resource Leak Potential:

    • Workers are created per execution but cleanup validation is minimal
    • No verification that workers actually terminate on timeout
    • Bun worker creates blob URLs that may not always get revoked on early errors
  3. Environment Variable Exposure:

    • http-client.ts:52-59 loads sensitive env vars directly in adapter creation
    • Better pattern: pass credentials through adapter interface vs. direct env access
  4. Error Information Leakage:

    • Full stack traces and error details are returned to MCP clients
    • Could expose internal implementation details or file paths
  5. Missing Input Validation:

    • No code size limits before execution
    • No validation of adapter method parameters
    • File upload paths in formData aren't validated

🟢 Architecture Positives

  • Clean separation between sandbox and main thread for token handling
  • Good dual-runtime detection pattern
  • Proper async/await throughout
  • Reasonable timeout handling

Recommendations

  1. Immediate: Replace AsyncFunction with a safer code execution method (VM2, isolated-vm, or AST-based validation)
  2. High Priority: Implement actual memory limits and resource monitoring
  3. Medium Priority: Add input validation and sanitize error responses
  4. Low Priority: Improve credential injection pattern and cleanup verification

The architectural changes are sound, but the code injection vulnerability makes this unsuitable for production without fixes.


Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Rewrites the core-web/apps/mcp-server application to replace the @modelcontextprotocol/sdk + esbuild-based implementation with the xmcp framework, introducing a worker-based sandbox for tool execution and a build-time OpenAPI spec processing step.

Changes:

  • Migrates MCP server runtime to xmcp with auto-discovered tools (search, execute) and rspack bundling.
  • Adds a dual-runtime sandbox (Node worker_threads + Bun Web Workers) with an adapter bridge for authenticated HTTP calls.
  • Adds build-time OpenAPI processing (scripts/generate-spec.ts) and updates Nx targets/build packaging docs.

Reviewed changes

Copilot reviewed 65 out of 67 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
core-web/yarn.lock Adds lock entries for xmcp/rspack and spec tooling dependencies.
core-web/package.json Adds xmcp dependency plus dev deps for spec generation (swagger-parser, tsx).
core-web/apps/mcp-server/xmcp.config.ts New xmcp configuration with custom bundler output path into Nx dist/.
core-web/apps/mcp-server/tsconfig.json Updates TS config to include sources and adjust compiler options for the new build approach.
core-web/apps/mcp-server/tsconfig.app.json Removes esbuild app tsconfig (no longer used with xmcp build).
core-web/apps/mcp-server/src/utils/schema-helpers.ts Removes legacy MCP SDK zod-compat helper.
core-web/apps/mcp-server/src/utils/schema-helpers.spec.ts Removes tests tied to legacy MCP SDK schema compatibility.
core-web/apps/mcp-server/src/utils/response.ts Removes legacy MCP response formatting utilities.
core-web/apps/mcp-server/src/utils/response.spec.ts Removes tests for legacy response utilities.
core-web/apps/mcp-server/src/utils/logger.ts Removes custom logger used by the previous implementation.
core-web/apps/mcp-server/src/utils/logger.spec.ts Removes tests for the legacy logger.
core-web/apps/mcp-server/src/utils/context-store.ts Removes legacy initialization state singleton.
core-web/apps/mcp-server/src/utils/context-store.spec.ts Removes tests for the legacy context store.
core-web/apps/mcp-server/src/utils/context-checking-server.ts Removes legacy MCP SDK middleware/proxy enforcing initialization.
core-web/apps/mcp-server/src/utils/context-checking-server.spec.ts Removes tests for the legacy context-checking proxy.
core-web/apps/mcp-server/src/types/workflow.ts Removes legacy workflow-related Zod schemas/types.
core-web/apps/mcp-server/src/types/site.ts Removes legacy site schemas/types.
core-web/apps/mcp-server/src/types/search.ts Removes legacy search schemas/types.
core-web/apps/mcp-server/src/types/contentype.ts Removes legacy content type schemas/types.
core-web/apps/mcp-server/src/tools/workflow/utils.ts Removes legacy workflow tool utilities.
core-web/apps/mcp-server/src/tools/workflow/index.ts Removes legacy workflow tool registration.
core-web/apps/mcp-server/src/tools/workflow/handlers.ts Removes legacy workflow handlers.
core-web/apps/mcp-server/src/tools/workflow/constants.ts Removes legacy workflow constants.
core-web/apps/mcp-server/src/tools/search/index.ts Removes legacy search tool registration module.
core-web/apps/mcp-server/src/tools/search/handlers.ts Removes legacy content search handler.
core-web/apps/mcp-server/src/tools/search/description.ts Removes long-form legacy Lucene search description text.
core-web/apps/mcp-server/src/tools/search.ts Adds xmcp search tool executing sandboxed JS over generated OpenAPI spec.
core-web/apps/mcp-server/src/tools/execute.ts Adds xmcp execute tool executing sandboxed JS with an authenticated api adapter.
core-web/apps/mcp-server/src/tools/context/index.ts Removes legacy context_initialization tool registration.
core-web/apps/mcp-server/src/tools/context/handlers.ts Removes legacy context init implementation/caching.
core-web/apps/mcp-server/src/tools/context/formatters.ts Removes legacy context formatters.
core-web/apps/mcp-server/src/tools/context/cache.ts Removes legacy context caching module.
core-web/apps/mcp-server/src/tools/content-types/index.ts Removes legacy content type tools registration.
core-web/apps/mcp-server/src/tools/content-types/handlers.ts Removes legacy content type handlers.
core-web/apps/mcp-server/src/tools/content-types/formatters.ts Removes legacy content type text formatting.
core-web/apps/mcp-server/src/tools/_example-tool/index.ts Removes legacy example tool template.
core-web/apps/mcp-server/src/tools/_example-tool/handlers.ts Removes legacy example tool handler template.
core-web/apps/mcp-server/src/tools/_example-tool/formatters.ts Removes legacy example tool formatter template.
core-web/apps/mcp-server/src/test-setup.ts Strips legacy Jest setup/mocks used by removed services/tools.
core-web/apps/mcp-server/src/services/workflow.ts Removes legacy workflow service client.
core-web/apps/mcp-server/src/services/workflow.spec.ts Removes tests for legacy workflow service.
core-web/apps/mcp-server/src/services/site.ts Removes legacy site service client.
core-web/apps/mcp-server/src/services/site.spec.ts Removes tests for legacy site service.
core-web/apps/mcp-server/src/services/search.ts Removes legacy search service client.
core-web/apps/mcp-server/src/services/search.spec.ts Removes tests for legacy search service.
core-web/apps/mcp-server/src/services/contentype.spec.ts Removes tests for legacy content type service.
core-web/apps/mcp-server/src/services/contentType.ts Removes legacy content type service implementation.
core-web/apps/mcp-server/src/services/client.ts Removes legacy base authenticated HTTP client.
core-web/apps/mcp-server/src/main.ts Removes manual MCP SDK server entrypoint (xmcp generates entrypoint at build time).
core-web/apps/mcp-server/src/lib/types.ts Adds core interfaces for adapters, sandbox config, and execution context.
core-web/apps/mcp-server/src/lib/spec.ts Adds loader for generated OpenAPI spec JSON.
core-web/apps/mcp-server/src/lib/sandbox/interface.ts Adds sandbox interface contract.
core-web/apps/mcp-server/src/lib/sandbox/index.ts Adds runtime detection/factory for Bun vs Node sandbox.
core-web/apps/mcp-server/src/lib/sandbox/node-worker.ts Adds Node worker_threads sandbox implementation.
core-web/apps/mcp-server/src/lib/sandbox/bun-worker.ts Adds Bun Web Worker sandbox implementation.
core-web/apps/mcp-server/src/lib/http-client.ts Adds authenticated HTTP adapter (api.request) for sandboxed execution.
core-web/apps/mcp-server/src/lib/executor.ts Adds executor orchestrating sandbox creation and adapter injection.
core-web/apps/mcp-server/scripts/generate-spec.ts Adds build-time OpenAPI dereference/filter/compaction step.
core-web/apps/mcp-server/project.json Replaces esbuild targets with run-commands for xmcp build/dev + spec generation.
core-web/apps/mcp-server/package.json Updates published package metadata to ship stdio.js (xmcp output) and raise Node engine.
core-web/apps/mcp-server/jest.config.ts Updates Jest config for JSON modules and new matching behavior.
core-web/apps/mcp-server/README.md Updates documentation for new tool model, env vars, packaging, and usage examples.
core-web/apps/mcp-server/CLAUDE.md Updates internal architecture notes and developer commands to reflect xmcp/sandbox.
core-web/apps/mcp-server/.gitignore Adds ignores for xmcp artifacts and generated spec/env files.
core-web/apps/mcp-server/.env.example Adds example env file for the new DOTCMS_* variables and sandbox timeout.

Comment thread core-web/libs/agentic-tools/src/lib/http-client.ts
Comment thread core-web/apps/mcp-server/project.json Outdated
Comment thread core-web/apps/mcp-server/README.md Outdated
Comment thread core-web/apps/mcp-server/CLAUDE.md Outdated
Comment thread core-web/apps/mcp-server/xmcp.config.ts
Comment thread core-web/libs/agentic-tools/src/lib/sandbox/node-worker.ts
Comment thread core-web/libs/agentic-tools/src/lib/sandbox/node-worker.ts
Comment thread core-web/libs/agentic-tools/src/lib/sandbox/bun-worker.ts
Comment thread core-web/apps/mcp-server/project.json
- Block direct network access (fetch, XMLHttpRequest, WebSocket, EventSource) in both sandbox runtimes
- Block require() and clean process.env in Node.js worker; pass empty env to Worker constructor
- Protect Authorization header from override by placing it after user header spread
- Add 100KB code size limit via Zod .max(100_000) on both tools
- Remove unenforceable memoryLimit and allowAsync from SandboxConfig
- Fix dev → serve in docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@claude

claude Bot commented Mar 8, 2026

Copy link
Copy Markdown
Contributor

Claude finished @fmontes's task —— View job


Code Review Complete

Reviewed this MCP server rewrite for potential issues, security concerns, and design problems.

Review Checklist

  • Analyze core architecture changes
  • Review sandbox security implementation
  • Check HTTP client authentication patterns
  • Validate worker thread lifecycle management
  • Review dual-runtime compatibility
  • Check build configuration changes
  • Identify missing edge cases or risks

Critical Issues Found

🔴 CRITICAL: Code Injection Vulnerability

  • src/lib/sandbox/node-worker.ts:243 and src/lib/sandbox/bun-worker.ts:238
  • Both sandboxes use AsyncFunction constructor with AI-generated code: new AsyncFunction(data.code)
  • Risk: Malicious MCP clients could inject arbitrary JavaScript beyond intended sandbox constraints
  • Recommendation: Implement proper code validation, AST parsing, or use a more restrictive execution environment

🟡 Security & Design Concerns

  1. Incomplete Network Isolation:

    • Node worker at src/lib/sandbox/node-worker.ts:124-128 attempts to disable fetch, XMLHttpRequest, etc. but this is insufficient
    • The worker still inherits parent process.env (line 132 only clears it, but sandboxed code executes before this)
    • Bun worker has NO network access restrictions - sandboxed code can call fetch directly, bypassing adapter controls
  2. SSRF Vulnerability in HTTP Client:

    • src/lib/http-client.ts:37-42 allows fetching arbitrary URLs from desc.url
    • Sandbox-provided input can trigger server-side requests to attacker-chosen URLs
    • No allowlisting of schemes, hostnames, or blocking of private IP ranges
  3. Resource Leak Potential:

    • Workers are created per execution but cleanup validation is minimal
    • No verification that workers actually terminate on timeout
    • Bun worker creates blob URLs that may not get revoked on early errors
  4. Missing Input Validation:

    • No code size limits before execution (though schema has 100KB max)
    • File upload paths in formData aren't validated
    • No validation of adapter method parameters
  5. Error Information Leakage:

    • Full stack traces returned to MCP clients (lines 251, 246 in both sandboxes)
    • Could expose internal implementation details or file paths
  6. Build Issues:

    • project.json:21-22 uses npx (network calls) and cp (Windows incompatible)
    • Documentation references yarn nx dev mcp-server but target is named serve

🟢 Architecture Positives

  • Clean separation between sandbox and main thread for token handling
  • Good dual-runtime detection pattern
  • Proper async/await throughout
  • Reasonable timeout handling
  • Strong improvement over previous SDK-based approach

Recommendations

  1. Immediate: Replace AsyncFunction with a safer code execution method (VM2, isolated-vm, or AST-based validation)
  2. High Priority: Implement proper network isolation and SSRF protection
  3. Medium Priority: Add comprehensive input validation and sanitize error responses
  4. Low Priority: Fix build configuration and documentation inconsistencies

The architectural changes are sound, but the code injection vulnerability makes this unsuitable for production without fixes.


@fmontes

fmontes commented Mar 8, 2026

Copy link
Copy Markdown
Member Author

Security Remediation — PR Review Findings

Addressed the legitimate security findings from the automated reviews.

Fixed

Finding What changed
Node.js worker leaks process.env/require() Worker now starts with env: {}, and inside the worker code globalThis.require is set to undefined and process.env is wiped
Sandbox allows direct fetch/network access Both runtimes (Node + Bun) now block fetch, XMLHttpRequest, WebSocket, and EventSource at the top of the worker code — all API calls must go through the adapter bridge
memoryLimit/allowAsync not enforced Removed from SandboxConfig interface and all defaults — don't promise what we can't deliver
No code size limits Added .max(100_000) (100KB) Zod validation on the code field in both execute and search tools
Auth header override via options.headers Authorization header is now placed after the ...options.headers spread so user-supplied headers can never override it
yarn nx dev vs serve in docs Fixed in both CLAUDE.md and README.md

Not changed (with reasoning)

Finding Why no action
AsyncFunction code injection False alarm — AsyncFunction inside an isolated Worker is the standard pattern for dynamic code execution in a sandbox
SSRF via formData.url Server-side only, AI-controlled (not user-facing), acceptable risk for beta. Can revisit with URL allowlisting later
npx/cp not cross-platform This is a Unix-only dev environment (macOS/Linux)
xmcp.config.ts path concatenation Can't use path module — xmcp config compiler limitation
passWithNoTests Tests are coming in a follow-up PR

…-reversible

Replace simple `undefined` assignments with Object.defineProperty using
writable: false, configurable: false so sandbox code cannot restore
fetch/WebSocket/etc. Also covers navigator.sendBeacon and freezes
require in the Node worker.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@claude

claude Bot commented Mar 8, 2026

Copy link
Copy Markdown
Contributor

Claude finished @fmontes's task —— View job


Code Review Complete

Reviewed this MCP server rewrite for potential issues, security concerns, and design problems.

Review Checklist

  • Analyze core architecture changes
  • Review sandbox security implementation
  • Check HTTP client authentication patterns
  • Validate worker thread lifecycle management
  • Review dual-runtime compatibility
  • Check build configuration changes
  • Identify missing edge cases or risks

Critical Issues Found

🔴 CRITICAL: Code Injection Vulnerability

  • src/lib/sandbox/node-worker.ts:256 and src/lib/sandbox/bun-worker.ts:249
  • Both sandboxes use AsyncFunction constructor with AI-generated code: new AsyncFunction(data.code)
  • Risk: Malicious MCP clients could inject arbitrary JavaScript beyond intended sandbox constraints
  • Recommendation: Implement proper code validation, AST parsing, or use a more restrictive execution environment

🟡 Security & Design Concerns

  1. SSRF Vulnerability in HTTP Client:

    • src/lib/http-client.ts:38-42 allows fetching arbitrary URLs from desc.url
    • Sandbox-provided input can trigger server-side requests to attacker-chosen URLs
    • No allowlisting of schemes, hostnames, or blocking of private IP ranges
  2. Resource Leak Potential:

    • Workers are created per execution but cleanup validation is minimal
    • No verification that workers actually terminate on timeout
    • Bun worker creates blob URLs that may not always get revoked on early errors (src/lib/sandbox/bun-worker.ts:44)
  3. Error Information Leakage:

    • Full stack traces and error details are returned to MCP clients (node-worker.ts:264, bun-worker.ts:257)
    • Could expose internal implementation details or file paths
  4. Missing Input Validation:

    • File upload paths in formData aren't validated beyond basic type checks
    • No validation of adapter method parameters beyond Zod schema (100KB limit is good)
  5. Build Configuration Issues:

    • project.json:21-22 uses npx (network calls) and cp (Windows incompatible)
    • Documentation references yarn nx dev mcp-server but target is named serve

🟢 Architecture Positives

  • Clean separation between sandbox and main thread for token handling
  • Good dual-runtime detection pattern
  • Proper async/await throughout
  • Network blocking implementation is well-designed (lines 124-138 in both workers)
  • Authorization header placement prevents override (http-client.ts:91)
  • Code size limits are enforced (100KB via Zod validation)

Recommendations

  1. Immediate: Replace AsyncFunction with a safer code execution method (VM2, isolated-vm, or AST-based validation)
  2. High Priority: Add SSRF protection with URL allowlisting and private IP blocking
  3. Medium Priority: Sanitize error responses to prevent information leakage
  4. Low Priority: Fix build configuration and documentation inconsistencies

The architectural changes are sound and show good security awareness, but the code injection vulnerability makes this unsuitable for production without fixes.


…OTCMS_API_TOKEN → AUTH_TOKEN

Shorter, cleaner names that align with existing conventions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@claude

claude Bot commented Mar 8, 2026

Copy link
Copy Markdown
Contributor

Claude finished @fmontes's task —— View job


Code Review Complete

Reviewed this MCP server rewrite for potential issues, security concerns, and design problems.

Review Checklist

  • Analyze core architecture changes
  • Review sandbox security implementation
  • Check HTTP client authentication patterns
  • Validate worker thread lifecycle management
  • Review dual-runtime compatibility
  • Check build configuration changes
  • Identify missing edge cases or risks

Critical Issues Found

🔴 CRITICAL: Code Injection Vulnerability

  • src/lib/sandbox/node-worker.ts:256 and src/lib/sandbox/bun-worker.ts:249
  • Both sandboxes use AsyncFunction constructor with AI-generated code: new AsyncFunction(data.code)
  • Risk: Malicious MCP clients could inject arbitrary JavaScript beyond intended sandbox constraints
  • Recommendation: Implement proper code validation, AST parsing, or use a more restrictive execution environment

🟡 Security & Design Concerns

  1. SSRF Vulnerability in HTTP Client:

    • src/lib/http-client.ts:37-42 allows fetching arbitrary URLs from desc.url
    • Sandbox-provided input can trigger server-side requests to attacker-chosen URLs
    • No allowlisting of schemes, hostnames, or blocking of private IP ranges
  2. Resource Leak Potential:

    • Workers are created per execution but cleanup validation is minimal
    • No verification that workers actually terminate on timeout
    • Bun worker creates blob URLs that may not always get revoked on early errors (src/lib/sandbox/bun-worker.ts:44)
  3. Error Information Leakage:

    • Full stack traces and error details are returned to MCP clients (node-worker.ts:264, bun-worker.ts:257)
    • Could expose internal implementation details or file paths
  4. Missing Input Validation:

    • File upload paths in formData aren't validated beyond basic type checks
    • No validation of adapter method parameters beyond Zod schema (100KB limit is good)
  5. Build Configuration Issues:

    • project.json:21-22 uses npx (network calls) and cp (Windows incompatible)
    • Documentation references yarn nx dev mcp-server but target is named serve

🟢 Architecture Positives

  • Clean separation between sandbox and main thread for token handling
  • Good dual-runtime detection pattern
  • Proper async/await throughout
  • Network blocking implementation is well-designed (lines 124-138 in both workers)
  • Authorization header placement prevents override (http-client.ts:91)
  • Code size limits are enforced (100KB via Zod validation)

Recommendations

  1. Immediate: Replace AsyncFunction with a safer code execution method (VM2, isolated-vm, or AST-based validation)
  2. High Priority: Add SSRF protection with URL allowlisting and private IP blocking
  3. Medium Priority: Sanitize error responses to prevent information leakage
  4. Low Priority: Fix build configuration and documentation inconsistencies

The architectural changes are sound and show good security awareness, but the code injection vulnerability makes this unsuitable for production without fixes.


Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 65 out of 67 changed files in this pull request and generated 3 comments.

Comment thread core-web/apps/mcp-server/project.json Outdated
Comment thread core-web/libs/agentic-tools/scripts/generate-spec.ts Outdated
Comment thread core-web/libs/agentic-tools/src/lib/http-client.ts
fmontes and others added 3 commits March 12, 2026 21:14
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Inline generate-spec as the first build step so the OpenAPI spec URL
can be passed directly via --specUrl instead of requiring a separate
generate-spec run. Update CLAUDE.md and README accordingly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove /api/v1/content, /api/v1/es, and /api/es from allowed prefixes.
Add /api/es/search as the sole Elasticsearch endpoint.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@claude

claude Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Pull Request Unsafe to Rollback!!!

  • Category: M-3 — REST / GraphQL / Headless API Contract Change
  • Risk Level: 🟡 MEDIUM
  • Why it's unsafe: Three breaking-on-rollback contract changes in the Workflow REST surface:
    1. PUT /api/v1/workflow/contentlet/actions/bulk/fire now returns HTTP 422 (instead of 200 OK with successCount: 0) when every input contentlet is skipped due to a workflow-scheme mismatch. Clients updated on N to branch on 422 will fall through to a success path on N-1 because N-1 still returns 200 for the same input.
    2. PUT /api/v1/workflow/actions/{actionId}/fire and the fire-merge endpoint now return HTTP 400 when the body contains pathToMove pointing at an action that has no Move actionlet, or when host/hostId/hostname/folder system fields appear in the contentlet body. N-1 silently ignores these — so clients that started sending these fields after the validation was added will see them quietly accepted (and discarded) again on N-1, masking caller bugs.
    3. BulkActionsResultView adds a new skipReason field on the JSON response. Clients on N that read skipReason will find it null/missing after rollback to N-1. Additionally, FireBulkActionsForm now declares workflowActionId as required in the OpenAPI spec (required: [workflowActionId]) — code-generated clients regenerated against N's spec will enforce this client-side regardless of which server version is live.
  • Code that makes it unsafe:
    • dotCMS/src/main/java/com/dotcms/rest/api/v1/workflow/WorkflowResource.java
      • isWholeBatchSkipped(...) guard returns 422 on whole-batch skip.
      • validateFireActionForm(...) (invoked from fireAction and fireMergeAction) throws 400 on disallowed fields/actions.
    • dotCMS/src/main/java/com/dotcms/rest/api/v1/workflow/BulkActionsResultView.java — new skipReason field and getter.
    • dotCMS/src/main/java/com/dotcms/workflow/form/FireBulkActionsForm.java — adds @Schema(required = true) on workflowActionId, propagated into openapi.yaml (required: [workflowActionId]).
  • Alternative (if possible):
    • For (1): keep returning 200 OK for the whole-batch-skip case and rely purely on the additive skipReason field to signal the cause. This stays additive/non-breaking and lets clients migrate at their own pace.
    • For (2): log a structured warning and return 200 instead of 400 until a coordinated client migration is in place. Alternatively, gate the strict validation behind a feature flag so it can be disabled at deploy time if rollback is needed.
    • For (3): leave the OpenAPI required list unchanged and document the requirement in the field description only; the server already rejects missing workflowActionId at runtime, so the schema change buys nothing but a rollback hazard for generated clients.

resolveFileDescriptor fetched an arbitrary, sandbox-supplied desc.url on
the host. Validate the URL first: require http(s), block loopback/private/
link-local IPv4 and IPv6 (incl. cloud metadata 169.254.169.254), refuse
redirects, and cap size + add a fetch timeout.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Pull Request Unsafe to Rollback!!!

  • Category: M-3 — REST / GraphQL / Headless API Contract Change
  • Risk Level: 🟡 MEDIUM
  • Why it's unsafe: Three breaking-on-rollback contract changes in the Workflow REST surface:
    1. PUT /api/v1/workflow/contentlet/actions/bulk/fire now returns HTTP 422 (instead of 200 OK with successCount: 0) when every input contentlet is skipped due to a workflow-scheme mismatch. Clients updated on N to branch on 422 will fall through to a success path on N-1 because N-1 still returns 200 for the same input.
    2. PUT /api/v1/workflow/actions/{actionId}/fire and the fire-merge endpoint now return HTTP 400 when the body contains pathToMove pointing at an action that has no Move actionlet, or when host/folder system fields appear in the contentlet body. N-1 silently ignores these — so clients that started sending these fields after the validation was added will see them quietly accepted (and discarded) again on N-1, masking caller bugs.
    3. BulkActionsResultView adds a new skipReason field on the JSON response. Clients on N that read skipReason will find it null/missing after rollback to N-1. Additionally, FireBulkActionsForm now declares workflowActionId as required in the OpenAPI spec — code-generated clients regenerated against N's spec will enforce this client-side regardless of which server version is live.
  • Code that makes it unsafe:
    • dotCMS/src/main/java/com/dotcms/rest/api/v1/workflow/WorkflowResource.java
      • isWholeBatchSkipped(...) guard returns 422 on whole-batch skip.
      • validateFireActionForm(...) (invoked from fireAction and fireMergeAction) throws 400 on disallowed fields/actions.
    • dotCMS/src/main/java/com/dotcms/rest/api/v1/workflow/BulkActionsResultView.java — new skipReason field and getter.
    • dotCMS/src/main/java/com/dotcms/workflow/form/FireBulkActionsForm.java — adds required: [workflowActionId] in openapi.yaml.
  • Alternative (if possible):
    • For (1): keep returning 200 OK for the whole-batch-skip case and rely purely on the additive skipReason field to signal the cause. This stays additive/non-breaking and lets clients migrate at their own pace.
    • For (2): log a structured warning and return 200 instead of 400 until a coordinated client migration is in place. Alternatively, gate the strict validation behind a feature flag so it can be disabled at deploy time if rollback is needed.
    • For (3): leave the OpenAPI required list unchanged and document the requirement in the field description only; the server already rejects missing workflowActionId at runtime, so the schema change buys nothing but a rollback hazard for generated clients.

1 similar comment
@claude

claude Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Pull Request Unsafe to Rollback!!!

  • Category: M-3 — REST / GraphQL / Headless API Contract Change
  • Risk Level: 🟡 MEDIUM
  • Why it's unsafe: Three breaking-on-rollback contract changes in the Workflow REST surface:
    1. PUT /api/v1/workflow/contentlet/actions/bulk/fire now returns HTTP 422 (instead of 200 OK with successCount: 0) when every input contentlet is skipped due to a workflow-scheme mismatch. Clients updated on N to branch on 422 will fall through to a success path on N-1 because N-1 still returns 200 for the same input.
    2. PUT /api/v1/workflow/actions/{actionId}/fire and the fire-merge endpoint now return HTTP 400 when the body contains pathToMove pointing at an action that has no Move actionlet, or when host/folder system fields appear in the contentlet body. N-1 silently ignores these — so clients that started sending these fields after the validation was added will see them quietly accepted (and discarded) again on N-1, masking caller bugs.
    3. BulkActionsResultView adds a new skipReason field on the JSON response. Clients on N that read skipReason will find it null/missing after rollback to N-1. Additionally, FireBulkActionsForm now declares workflowActionId as required in the OpenAPI spec — code-generated clients regenerated against N's spec will enforce this client-side regardless of which server version is live.
  • Code that makes it unsafe:
    • dotCMS/src/main/java/com/dotcms/rest/api/v1/workflow/WorkflowResource.java
      • isWholeBatchSkipped(...) guard returns 422 on whole-batch skip.
      • validateFireActionForm(...) (invoked from fireAction and fireMergeAction) throws 400 on disallowed fields/actions.
    • dotCMS/src/main/java/com/dotcms/rest/api/v1/workflow/BulkActionsResultView.java — new skipReason field and getter.
    • dotCMS/src/main/java/com/dotcms/workflow/form/FireBulkActionsForm.java — adds required: [workflowActionId] in openapi.yaml.
  • Alternative (if possible):
    • For (1): keep returning 200 OK for the whole-batch-skip case and rely purely on the additive skipReason field to signal the cause. This stays additive/non-breaking and lets clients migrate at their own pace.
    • For (2): log a structured warning and return 200 instead of 400 until a coordinated client migration is in place. Alternatively, gate the strict validation behind a feature flag so it can be disabled at deploy time if rollback is needed.
    • For (3): leave the OpenAPI required list unchanged and document the requirement in the field description only; the server already rejects missing workflowActionId at runtime, so the schema change buys nothing but a rollback hazard for generated clients.

fmontes and others added 3 commits June 5, 2026 07:00
Story Block field values can be sent as an HTML or Markdown string to the
workflow fire endpoints; dotCMS stores the string as-is and converts it to
the Block Editor structure when opened in the editor. Add this to the shared
fire-endpoint @operation notes and regenerate openapi.yaml.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ields

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Pull Request Unsafe to Rollback!!!

  • Category: M-3 — REST / GraphQL / Headless API Contract Change
  • Risk Level: 🟡 MEDIUM
  • Why it's unsafe: Three breaking-on-rollback contract changes in the Workflow REST surface:
    1. PUT /api/v1/workflow/contentlet/actions/bulk/fire now returns HTTP 422 (instead of 200 OK with successCount: 0) when every input contentlet is skipped due to a workflow-scheme mismatch. Clients updated on N to branch on 422 will fall through to a success path on N-1 because N-1 still returns 200 for the same input.
    2. PUT /api/v1/workflow/actions/{actionId}/fire and the fire-merge endpoint now return HTTP 400 when the body contains pathToMove pointing at an action that has no Move actionlet, or when host/folder system fields appear in the contentlet body. N-1 silently ignores these — so clients that started sending these fields after the validation was added will see them quietly accepted (and discarded) again on N-1, masking caller bugs.
    3. BulkActionsResultView adds a new skipReason field on the JSON response. Clients on N that read skipReason will find it null/missing after rollback to N-1. Additionally, FireBulkActionsForm now declares workflowActionId as required in the OpenAPI spec — code-generated clients regenerated against N's spec will enforce this client-side regardless of which server version is live.
  • Code that makes it unsafe:
    • dotCMS/src/main/java/com/dotcms/rest/api/v1/workflow/WorkflowResource.java
      • isWholeBatchSkipped(...) guard returns 422 on whole-batch skip.
      • validateFireActionForm(...) (invoked from fireAction and fireMergeAction) throws 400 on disallowed fields/actions.
    • dotCMS/src/main/java/com/dotcms/rest/api/v1/workflow/BulkActionsResultView.java — new skipReason field and getter.
    • dotCMS/src/main/java/com/dotcms/workflow/form/FireBulkActionsForm.java — adds @Schema(required = true) on workflowActionId, propagated into openapi.yaml (required: [workflowActionId]).
  • Alternative (if possible):
    • For (1): keep returning 200 OK for the whole-batch-skip case and rely purely on the additive skipReason field to signal the cause. This stays additive/non-breaking and lets clients migrate at their own pace.
    • For (2): log a structured warning and return 200 instead of 400 until a coordinated client migration is in place. Alternatively, gate the strict validation behind a feature flag so it can be disabled at deploy time if rollback is needed.
    • For (3): leave the OpenAPI required list unchanged and document the requirement in the field description only; the server already rejects missing workflowActionId at runtime, so the schema change buys nothing but a rollback hazard for generated clients.

@claude

claude Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Pull Request Unsafe to Rollback!!!

  • Category: M-3 — REST / GraphQL / Headless API Contract Change
  • Risk Level: 🟡 MEDIUM
  • Why it's unsafe: Three breaking-on-rollback contract changes in the Workflow REST surface:
    1. PUT /api/v1/workflow/contentlet/actions/bulk/fire now returns HTTP 422 (instead of 200 OK with successCount: 0) when every input contentlet is skipped due to a workflow-scheme mismatch. Clients updated on N to branch on 422 will fall through to a success path on N-1 because N-1 still returns 200 for the same input.
    2. PUT /api/v1/workflow/actions/{actionId}/fire and the fire-merge endpoint now return HTTP 400 when the body contains pathToMove pointing at an action that has no Move actionlet, or when host/folder system fields appear in the contentlet body. N-1 silently ignores these — so clients that started sending these fields after the validation was added will see them quietly accepted (and discarded) again on N-1, masking caller bugs.
    3. BulkActionsResultView adds a new skipReason field on the JSON response. Clients on N that read skipReason will find it null/missing after rollback to N-1. Additionally, FireBulkActionsForm now declares workflowActionId as required in the OpenAPI spec — code-generated clients regenerated against N's spec will enforce this client-side regardless of which server version is live.
  • Code that makes it unsafe:
    • dotCMS/src/main/java/com/dotcms/rest/api/v1/workflow/WorkflowResource.java
      • isWholeBatchSkipped(...) guard returns 422 on whole-batch skip.
      • validateFireActionForm(...) (invoked from fireAction and fireMergeAction) throws 400 on disallowed fields/actions.
    • dotCMS/src/main/java/com/dotcms/rest/api/v1/workflow/BulkActionsResultView.java — new skipReason field and getter.
    • dotCMS/src/main/java/com/dotcms/workflow/form/FireBulkActionsForm.java — adds @Schema(required = true) on workflowActionId, propagated into openapi.yaml (required: [workflowActionId]).
  • Alternative (if possible):
    • For (1): keep returning 200 OK for the whole-batch-skip case and rely purely on the additive skipReason field to signal the cause. This stays additive/non-breaking and lets clients migrate at their own pace.
    • For (2): log a structured warning and return 200 instead of 400 until a coordinated client migration is in place. Alternatively, gate the strict validation behind a feature flag so it can be disabled at deploy time if rollback is needed.
    • For (3): leave the OpenAPI required list unchanged and document the requirement in the field description only; the server already rejects missing workflowActionId at runtime, so the schema change buys nothing but a rollback hazard for generated clients.

Address unresolved PR review findings on the sandbox runtime:

- Bun worker: clear inherited process.env and block require before
  running user code, mirroring the Node worker. Closes a token-leak
  path where sandboxed code could read AUTH_TOKEN/DOTCMS_URL.
- Both workers: guard adapter_call postMessage with the resolved flag
  and try/catch so a timeout-terminated worker cannot raise an
  unhandled rejection that crashes the host process.
- search tool: guard against a missing/empty OpenAPI spec and return a
  clear handler-level error instead of failing inside the sandbox.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Pull Request Unsafe to Rollback!!!

  • Category: M-3 — REST / GraphQL / Headless API Contract Change
  • Risk Level: 🟡 MEDIUM
  • Why it's unsafe: Three breaking-on-rollback contract changes in the Workflow REST surface:
    1. PUT /api/v1/workflow/contentlet/actions/bulk/fire now returns HTTP 422 (instead of 200 OK with successCount: 0) when every input contentlet is skipped due to a workflow-scheme mismatch. Clients updated on N to branch on 422 will fall through to a success path on N-1 because N-1 still returns 200 for the same input.
    2. PUT /api/v1/workflow/actions/{actionId}/fire and the fire-merge endpoint (PUT /api/v1/workflow/actions/fire/{systemAction}) now return HTTP 400 when the body contains pathToMove pointing at an action that has no Move actionlet, or when host/hostId/hostname/folder system fields appear in the contentlet body. N-1 silently ignores these — so clients that started sending these fields after the validation was added will see them quietly accepted (and discarded) again on N-1, masking caller bugs.
    3. BulkActionsResultView adds a new skipReason field on the JSON response. Clients on N that read skipReason will find it null/missing after rollback to N-1. Additionally, FireBulkActionsForm now declares workflowActionId as required = true in the @Schema annotation, propagated into openapi.yaml — code-generated clients regenerated against N's spec will enforce this client-side regardless of which server version is live.
  • Code that makes it unsafe:
    • dotCMS/src/main/java/com/dotcms/rest/api/v1/workflow/WorkflowResource.java
      • isWholeBatchSkipped(...) guard returns 422 on whole-batch skip.
      • validateFireActionForm(...) (invoked from fireAction and fireMergeAction) throws 400 on disallowed fields/actions.
    • dotCMS/src/main/java/com/dotcms/rest/api/v1/workflow/BulkActionsResultView.java — new skipReason field and getter.
    • dotCMS/src/main/java/com/dotcms/workflow/form/FireBulkActionsForm.java — adds @Schema(required = true) on workflowActionId, propagated into openapi.yaml.
  • Alternative (if possible):
    • For (1): keep returning 200 OK for the whole-batch-skip case and rely purely on the additive skipReason field to signal the cause. This stays additive/non-breaking and lets clients migrate at their own pace.
    • For (2): log a structured warning and return 200 instead of 400 until a coordinated client migration is in place. Alternatively, gate the strict validation behind a feature flag so it can be disabled at deploy time if rollback is needed.
    • For (3): leave the OpenAPI required list unchanged and document the requirement in the field description only; the server already rejects missing workflowActionId at runtime, so the schema change buys nothing but a rollback hazard for generated clients.

The ai-evals harness intentionally uses the Vercel AI SDK (tool/
generateText) to drive LLM evaluation runs. It is internal tooling,
not shipped runtime code, so the four blocking detect-vercelai
findings are false positives in this context. Add inline nosemgrep
comments with justification, matching the repo's existing
nosemgrep convention.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Pull Request Unsafe to Rollback!!!

  • Category: M-3 — REST / GraphQL / Headless API Contract Change
  • Risk Level: 🟡 MEDIUM
  • Why it's unsafe: Three breaking-on-rollback contract changes in the Workflow REST surface:
    1. PUT /api/v1/workflow/contentlet/actions/bulk/fire now returns HTTP 422 (instead of 200 OK with successCount: 0) when every input contentlet is skipped due to a workflow-scheme mismatch. Clients updated on N to branch on 422 will fall through to a success path on N-1 because N-1 still returns 200 for the same input.
    2. PUT /api/v1/workflow/actions/{actionId}/fire and the fire-merge endpoint (PUT /api/v1/workflow/actions/fire/{systemAction}) now return HTTP 400 when the body contains pathToMove pointing at an action that has no Move actionlet, or when host/hostId/hostname/folder system fields appear in the contentlet body. N-1 silently ignores these — so clients that started sending these fields after the validation was added will see them quietly accepted (and discarded) again on N-1, masking caller bugs.
    3. BulkActionsResultView adds a new skipReason field on the JSON response. Clients on N that read skipReason will find it null/missing after rollback to N-1. Additionally, FireBulkActionsForm now declares workflowActionId as required = true in the @Schema annotation, propagated into openapi.yaml — code-generated clients regenerated against N's spec will enforce this client-side regardless of which server version is live.
  • Code that makes it unsafe:
    • dotCMS/src/main/java/com/dotcms/rest/api/v1/workflow/WorkflowResource.java
      • isWholeBatchSkipped(...) guard returns 422 on whole-batch skip.
      • validateFireActionForm(...) (invoked from fireAction and fireMergeAction) throws 400 on disallowed fields/actions.
    • dotCMS/src/main/java/com/dotcms/rest/api/v1/workflow/BulkActionsResultView.java — new skipReason field and getter.
    • dotCMS/src/main/java/com/dotcms/workflow/form/FireBulkActionsForm.java — adds @Schema(required = true) on workflowActionId, propagated into openapi.yaml.
  • Alternative (if possible):
    • For (1): keep returning 200 OK for the whole-batch-skip case and rely purely on the additive skipReason field to signal the cause. This stays additive/non-breaking and lets clients migrate at their own pace.
    • For (2): log a structured warning and return 200 instead of 400 until a coordinated client migration is in place. Alternatively, gate the strict validation behind a feature flag so it can be disabled at deploy time if rollback is needed.
    • For (3): leave the OpenAPI required list unchanged and document the requirement in the field description only; the server already rejects missing workflowActionId at runtime, so the schema change buys nothing but a rollback hazard for generated clients.

@fmontes fmontes added this pull request to the merge queue Jun 8, 2026
Merged via the queue into main with commit c97e75a Jun 8, 2026
57 of 58 checks passed
@fmontes fmontes deleted the mcp-server-2 branch June 8, 2026 20:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI: Not Safe To Rollback Area : Backend PR changes Java/Maven backend code Area : Frontend PR changes Angular/TypeScript frontend code

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Expand dotCMS MCP server API coverage

6 participants