Repository navigation
refactor(mcp): rename packages/mcp-v2 to packages/mcp and de-version all user-visible surfaces - #6079
Conversation
📝 WalkthroughWalkthroughThe MCP implementation moves from ChangesMCP migration
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant MCPClient
participant MCPRoute
participant AuthContext
participant MCPServer
participant HostService
MCPClient->>MCPRoute: Request /mcp
MCPRoute->>AuthContext: Resolve credentials and organization
AuthContext-->>MCPRoute: MCP context and relay URL
MCPRoute->>MCPServer: Create and connect server
MCPServer->>HostService: Execute tool request
HostService-->>MCPClient: MCP response
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Ready to review this PR? Stage has broken it down into 6 individual chapters for you: Chapters generated by Stage for commit 7249a46 on Jul 31, 2026 11:53pm UTC. |
🧹 Preview Cleanup CompleteThe following preview resources have been cleaned up:
Thank you for your contribution! 🎉 |
8e38c7c to
08daae5
Compare
With the v1 server deleted, the -v2 suffix is an artifact. Directory, package name, and import specifiers only — runtime identity strings (server name, telemetry mcp_server, session userAgent) are unchanged to preserve PostHog continuity and the automation-source check. Claude-Session: https://claude.ai/code/session_01Kub4p3Eim9pc1qaRRmGea2
Canonical URL is now /mcp everywhere it is advertised (docs, llms.txt, .well-known, server card, openapi, API hints, 410 hint); the versioned path stays served as a legacy alias. Server info name drops the -v2 suffix. Telemetry mcp_server value and the session userAgent pair stay superset-v2/mcp-v2 for PostHog and automation-source continuity. Claude-Session: https://claude.ai/code/session_01Kub4p3Eim9pc1qaRRmGea2
…s the alias The implementation now lives at the canonical /mcp route; /api/v2/agent/[transport] is a thin re-export kept for already-configured clients. Claude-Session: https://claude.ai/code/session_01Kub4p3Eim9pc1qaRRmGea2
08daae5 to
7249a46
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (5)
apps/api/src/app/mcp/route.ts (1)
14-25: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicate WWW-Authenticate/401 envelope logic.
unauthorizedResponserebuilds the sameBearer realm="superset", resource_metadata="..."header construction and JSON error envelope shape found inunauthorizedinapps/api/src/app/api/route.ts. Extract a shared helper for the header value and envelope so both authentication failure paths stay in sync. Divergence here would produce inconsistent OAuth discovery behavior between/mcpand other endpoints.♻️ Proposed shared helper
// e.g. apps/api/src/lib/oauth-metadata.ts export function buildBearerChallenge(req: Request): string { return `Bearer realm="superset", resource_metadata="${getOAuthProtectedResourceMetadataUrl(req)}"`; }function unauthorizedResponse(req: Request, message: string): Response { return new Response( JSON.stringify({ error: { code: "UNAUTHORIZED", message } }), { status: 401, headers: { - "WWW-Authenticate": `Bearer realm="superset", resource_metadata="${getOAuthProtectedResourceMetadataUrl(req)}"`, + "WWW-Authenticate": buildBearerChallenge(req), "Content-Type": "application/json", }, }, ); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/api/src/app/mcp/route.ts` around lines 14 - 25, Extract the duplicated OAuth authentication failure construction from unauthorizedResponse and the unauthorized handler in the API route into shared helpers, including the Bearer challenge built from getOAuthProtectedResourceMetadataUrl and the UNAUTHORIZED JSON envelope. Update both callers to reuse these helpers while preserving the 401 status and consistent WWW-Authenticate and Content-Type headers.packages/mcp/src/tools/workspaces/update.ts (1)
17-17: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider migrating from deprecated
.uuid()chain toz.uuid().
z.string().uuid()still works in Zod 4 but is deprecated in favor of the top-levelz.uuid(). Also confirm that workspace IDs conform to the stricter RFC 9562/4122 variant-bit validation Zod 4 now enforces, since some non-standard UUID-like values that passed before can now fail.♻️ Proposed refactor
- id: z.string().uuid().describe("Workspace UUID."), + id: z.uuid().describe("Workspace UUID."),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/mcp/src/tools/workspaces/update.ts` at line 17, Update the workspace ID schema in the relevant update tool definition from the deprecated string-based UUID chain to Zod 4’s top-level UUID validator, and verify that accepted workspace IDs meet its stricter RFC 9562/4122 variant-bit requirements without adding a compatibility fallback.packages/mcp/src/tools/automations/get_prompt.ts (1)
13-13: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMultiple tool files use deprecated Zod 4 chained string-format validators. All these sites use
z.string().uuid()orz.string().datetime(). Zod 4.3.6 deprecates these chained forms in favor of top-level functions (z.uuid(),z.iso.datetime()) and plans to remove the chained forms in a future major version.
packages/mcp/src/tools/automations/get_prompt.ts#L13-L13: replacez.string().uuid()withz.uuid()for theidfield.packages/mcp/src/tools/automations/logs.ts#L13-L13: replacez.string().uuid()withz.uuid()for theautomationIdfield.packages/mcp/src/tools/automations/resume.ts#L13-L13: replacez.string().uuid()withz.uuid()for theidfield.packages/mcp/src/tools/automations/set_prompt.ts#L13-L13: replacez.string().uuid()withz.uuid()for theidfield.packages/mcp/src/tools/tasks/create.ts#L15-L36: replacez.string().uuid()withz.uuid()forstatusIdandassigneeId, and replacez.string().datetime()withz.iso.datetime()fordueDate.packages/mcp/src/tools/workspaces/delete.ts#L17-L17: replacez.string().uuid()withz.uuid()for theidfield.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/mcp/src/tools/automations/get_prompt.ts` at line 13, Replace deprecated chained Zod validators: in packages/mcp/src/tools/automations/get_prompt.ts:13-13, logs.ts:13-13, resume.ts:13-13, set_prompt.ts:13-13, and packages/mcp/src/tools/workspaces/delete.ts:17-17, use z.uuid() for the identified UUID fields; in packages/mcp/src/tools/tasks/create.ts:15-36, use z.uuid() for statusId and assigneeId and z.iso.datetime() for dueDate.packages/mcp/src/tools/tasks/update.ts (1)
13-25: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMigrate deprecated chained Zod string-format methods.
id,prUrl, anddueDateuse.string().uuid(),.string().url(), and.string().datetime(). Zod v4 deprecates these chained forms in favor of top-levelz.uuid(),z.url(), andz.iso.datetime(). The chained forms still work today but are scheduled for removal in a future major version.This pattern repeats in
automations/run.ts,tasks/delete.ts,tasks/list.ts,terminals/close.ts,terminals/create.ts,terminals/read.ts,terminals/send.ts, andworkspaces/create.ts. Consider a single follow-up pass across the package.Note:
z.uuid()also validates the UUID variant bits more strictly (RFC 9562/4122) than the old chained check. Verify that existing UUID values in the system satisfy this stricter check before switching.♻️ Proposed migration for this file
inputSchema: { id: z - .string() - .uuid() + .uuid() .describe("Task UUID. Use tasks_get to resolve a slug to UUID first."), title: z.string().min(1).optional(), description: z.string().nullish(), - statusId: z.string().uuid().optional(), + statusId: z.uuid().optional(), priority: z.enum(["urgent", "high", "medium", "low", "none"]).optional(), - assigneeId: z.string().uuid().nullish(), - prUrl: z.string().url().nullish(), + assigneeId: z.uuid().nullish(), + prUrl: z.url().nullish(), estimate: z.number().int().positive().nullish(), - dueDate: z.string().datetime().nullish().describe("ISO 8601 due date."), + dueDate: z.iso.datetime().nullish().describe("ISO 8601 due date."), labels: z.array(z.string()).nullish(), },🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/mcp/src/tools/tasks/update.ts` around lines 13 - 25, Replace the deprecated chained Zod string-format validators in the update task schema: use top-level z.uuid() for id and statusId, z.url() for prUrl, and z.iso.datetime() for dueDate while preserving optional/nullish behavior and descriptions. Apply the same migration pattern to the corresponding schemas in the other listed task, terminal, automation, and workspace tools, after confirming existing UUID values satisfy the stricter validation.packages/mcp/src/tools/automations/create.ts (1)
37-46: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winVerify the "one of" requirement is enforced somewhere.
The description says either
v2ProjectIdorv2WorkspaceIdis required. The schema marks both fields optional. A call that omits both passes MCP input validation and only fails later, insidecaller.automation.create.Confirm that
caller.automation.createrejects the case where both fields are missing with a clear error message. If it does not, add an explicit check in the handler.🛡️ Proposed handler-level guard, if not already enforced downstream
handler: async (input, ctx) => { + if (!input.v2ProjectId && !input.v2WorkspaceId) { + throw new Error( + "Provide either v2ProjectId or v2WorkspaceId.", + ); + } const caller = createMcpCaller(ctx); return caller.automation.create(input); },🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/mcp/src/tools/automations/create.ts` around lines 37 - 46, Verify that the handler or caller used by the automation creation flow rejects requests where both v2ProjectId and v2WorkspaceId are absent, with a clear error message. If caller.automation.create does not enforce this, add an explicit guard in the create handler before invoking it; preserve acceptance when either identifier is provided.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/mcp/src/host-service-client.ts`:
- Around line 40-44: Update hostServiceCall to bound its fetch request with an
abort signal and a finite timeout, ensuring unresponsive hosts fail promptly
with a clear timeout error. Pass the signal into the existing fetch call and
preserve the current method, headers, and body behavior.
In `@packages/mcp/src/tools/workspaces/create.ts`:
- Around line 31-45: Update the handler that dispatches through hostServiceCall
to validate that exactly one of the optional inputs, branch or pr, is provided
before dispatching. Reject requests where both are present or both are absent
with a clear validation error, while preserving dispatch for valid inputs;
implement this in the handler rather than applying refine to the raw inputSchema
shape.
---
Nitpick comments:
In `@apps/api/src/app/mcp/route.ts`:
- Around line 14-25: Extract the duplicated OAuth authentication failure
construction from unauthorizedResponse and the unauthorized handler in the API
route into shared helpers, including the Bearer challenge built from
getOAuthProtectedResourceMetadataUrl and the UNAUTHORIZED JSON envelope. Update
both callers to reuse these helpers while preserving the 401 status and
consistent WWW-Authenticate and Content-Type headers.
In `@packages/mcp/src/tools/automations/create.ts`:
- Around line 37-46: Verify that the handler or caller used by the automation
creation flow rejects requests where both v2ProjectId and v2WorkspaceId are
absent, with a clear error message. If caller.automation.create does not enforce
this, add an explicit guard in the create handler before invoking it; preserve
acceptance when either identifier is provided.
In `@packages/mcp/src/tools/automations/get_prompt.ts`:
- Line 13: Replace deprecated chained Zod validators: in
packages/mcp/src/tools/automations/get_prompt.ts:13-13, logs.ts:13-13,
resume.ts:13-13, set_prompt.ts:13-13, and
packages/mcp/src/tools/workspaces/delete.ts:17-17, use z.uuid() for the
identified UUID fields; in packages/mcp/src/tools/tasks/create.ts:15-36, use
z.uuid() for statusId and assigneeId and z.iso.datetime() for dueDate.
In `@packages/mcp/src/tools/tasks/update.ts`:
- Around line 13-25: Replace the deprecated chained Zod string-format validators
in the update task schema: use top-level z.uuid() for id and statusId, z.url()
for prUrl, and z.iso.datetime() for dueDate while preserving optional/nullish
behavior and descriptions. Apply the same migration pattern to the corresponding
schemas in the other listed task, terminal, automation, and workspace tools,
after confirming existing UUID values satisfy the stricter validation.
In `@packages/mcp/src/tools/workspaces/update.ts`:
- Line 17: Update the workspace ID schema in the relevant update tool definition
from the deprecated string-based UUID chain to Zod 4’s top-level UUID validator,
and verify that accepted workspace IDs meet its stricter RFC 9562/4122
variant-bit requirements without adding a compatibility fallback.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 6b2b0b95-9293-4c56-9e8c-205ca0f039aa
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (55)
apps/api/package.jsonapps/api/src/app/.well-known/mcp/route.tsapps/api/src/app/.well-known/mcp/server-card.json/route.tsapps/api/src/app/api/[...unmatched]/route.tsapps/api/src/app/api/agent/[transport]/route.tsapps/api/src/app/api/integrations/slack/events/utils/run-agent/mcp-clients.tsapps/api/src/app/api/route.tsapps/api/src/app/api/v2/agent/[transport]/route.tsapps/api/src/app/mcp/route.tsapps/api/src/app/openapi.json/route.tsapps/docs/content/docs/mcp-server.mdxapps/marketing/src/lib/llms.tspackages/mcp/package.jsonpackages/mcp/src/auth.tspackages/mcp/src/caller.tspackages/mcp/src/context-utils.tspackages/mcp/src/define-tool.tspackages/mcp/src/host-service-client.tspackages/mcp/src/in-memory.tspackages/mcp/src/index.tspackages/mcp/src/server.tspackages/mcp/src/tools/agents/create.tspackages/mcp/src/tools/agents/list.tspackages/mcp/src/tools/automations/create.tspackages/mcp/src/tools/automations/delete.tspackages/mcp/src/tools/automations/get.tspackages/mcp/src/tools/automations/get_prompt.tspackages/mcp/src/tools/automations/list.tspackages/mcp/src/tools/automations/logs.tspackages/mcp/src/tools/automations/pause.tspackages/mcp/src/tools/automations/resume.tspackages/mcp/src/tools/automations/run.tspackages/mcp/src/tools/automations/set_prompt.tspackages/mcp/src/tools/automations/update.tspackages/mcp/src/tools/hosts/list.tspackages/mcp/src/tools/organization/members/list.tspackages/mcp/src/tools/projects/list.tspackages/mcp/src/tools/register.tspackages/mcp/src/tools/tasks/create.tspackages/mcp/src/tools/tasks/delete.tspackages/mcp/src/tools/tasks/get.tspackages/mcp/src/tools/tasks/list.tspackages/mcp/src/tools/tasks/statuses/list.tspackages/mcp/src/tools/tasks/update.tspackages/mcp/src/tools/terminals/close.tspackages/mcp/src/tools/terminals/create.tspackages/mcp/src/tools/terminals/list.tspackages/mcp/src/tools/terminals/read.tspackages/mcp/src/tools/terminals/send.tspackages/mcp/src/tools/workspaces/create.tspackages/mcp/src/tools/workspaces/delete.tspackages/mcp/src/tools/workspaces/list.tspackages/mcp/src/tools/workspaces/update.tspackages/mcp/tsconfig.jsonpackages/shared/src/constants.ts
💤 Files with no reviewable changes (1)
- packages/shared/src/constants.ts
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 2
🧹 Nitpick comments (5)
apps/api/src/app/mcp/route.ts (1)
14-25: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicate WWW-Authenticate/401 envelope logic.
unauthorizedResponserebuilds the sameBearer realm="superset", resource_metadata="..."header construction and JSON error envelope shape found inunauthorizedinapps/api/src/app/api/route.ts. Extract a shared helper for the header value and envelope so both authentication failure paths stay in sync. Divergence here would produce inconsistent OAuth discovery behavior between/mcpand other endpoints.♻️ Proposed shared helper
// e.g. apps/api/src/lib/oauth-metadata.ts export function buildBearerChallenge(req: Request): string { return `Bearer realm="superset", resource_metadata="${getOAuthProtectedResourceMetadataUrl(req)}"`; }function unauthorizedResponse(req: Request, message: string): Response { return new Response( JSON.stringify({ error: { code: "UNAUTHORIZED", message } }), { status: 401, headers: { - "WWW-Authenticate": `Bearer realm="superset", resource_metadata="${getOAuthProtectedResourceMetadataUrl(req)}"`, + "WWW-Authenticate": buildBearerChallenge(req), "Content-Type": "application/json", }, }, ); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/api/src/app/mcp/route.ts` around lines 14 - 25, Extract the duplicated OAuth authentication failure construction from unauthorizedResponse and the unauthorized handler in the API route into shared helpers, including the Bearer challenge built from getOAuthProtectedResourceMetadataUrl and the UNAUTHORIZED JSON envelope. Update both callers to reuse these helpers while preserving the 401 status and consistent WWW-Authenticate and Content-Type headers.packages/mcp/src/tools/workspaces/update.ts (1)
17-17: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider migrating from deprecated
.uuid()chain toz.uuid().
z.string().uuid()still works in Zod 4 but is deprecated in favor of the top-levelz.uuid(). Also confirm that workspace IDs conform to the stricter RFC 9562/4122 variant-bit validation Zod 4 now enforces, since some non-standard UUID-like values that passed before can now fail.♻️ Proposed refactor
- id: z.string().uuid().describe("Workspace UUID."), + id: z.uuid().describe("Workspace UUID."),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/mcp/src/tools/workspaces/update.ts` at line 17, Update the workspace ID schema in the relevant update tool definition from the deprecated string-based UUID chain to Zod 4’s top-level UUID validator, and verify that accepted workspace IDs meet its stricter RFC 9562/4122 variant-bit requirements without adding a compatibility fallback.packages/mcp/src/tools/automations/get_prompt.ts (1)
13-13: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMultiple tool files use deprecated Zod 4 chained string-format validators. All these sites use
z.string().uuid()orz.string().datetime(). Zod 4.3.6 deprecates these chained forms in favor of top-level functions (z.uuid(),z.iso.datetime()) and plans to remove the chained forms in a future major version.
packages/mcp/src/tools/automations/get_prompt.ts#L13-L13: replacez.string().uuid()withz.uuid()for theidfield.packages/mcp/src/tools/automations/logs.ts#L13-L13: replacez.string().uuid()withz.uuid()for theautomationIdfield.packages/mcp/src/tools/automations/resume.ts#L13-L13: replacez.string().uuid()withz.uuid()for theidfield.packages/mcp/src/tools/automations/set_prompt.ts#L13-L13: replacez.string().uuid()withz.uuid()for theidfield.packages/mcp/src/tools/tasks/create.ts#L15-L36: replacez.string().uuid()withz.uuid()forstatusIdandassigneeId, and replacez.string().datetime()withz.iso.datetime()fordueDate.packages/mcp/src/tools/workspaces/delete.ts#L17-L17: replacez.string().uuid()withz.uuid()for theidfield.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/mcp/src/tools/automations/get_prompt.ts` at line 13, Replace deprecated chained Zod validators: in packages/mcp/src/tools/automations/get_prompt.ts:13-13, logs.ts:13-13, resume.ts:13-13, set_prompt.ts:13-13, and packages/mcp/src/tools/workspaces/delete.ts:17-17, use z.uuid() for the identified UUID fields; in packages/mcp/src/tools/tasks/create.ts:15-36, use z.uuid() for statusId and assigneeId and z.iso.datetime() for dueDate.packages/mcp/src/tools/tasks/update.ts (1)
13-25: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMigrate deprecated chained Zod string-format methods.
id,prUrl, anddueDateuse.string().uuid(),.string().url(), and.string().datetime(). Zod v4 deprecates these chained forms in favor of top-levelz.uuid(),z.url(), andz.iso.datetime(). The chained forms still work today but are scheduled for removal in a future major version.This pattern repeats in
automations/run.ts,tasks/delete.ts,tasks/list.ts,terminals/close.ts,terminals/create.ts,terminals/read.ts,terminals/send.ts, andworkspaces/create.ts. Consider a single follow-up pass across the package.Note:
z.uuid()also validates the UUID variant bits more strictly (RFC 9562/4122) than the old chained check. Verify that existing UUID values in the system satisfy this stricter check before switching.♻️ Proposed migration for this file
inputSchema: { id: z - .string() - .uuid() + .uuid() .describe("Task UUID. Use tasks_get to resolve a slug to UUID first."), title: z.string().min(1).optional(), description: z.string().nullish(), - statusId: z.string().uuid().optional(), + statusId: z.uuid().optional(), priority: z.enum(["urgent", "high", "medium", "low", "none"]).optional(), - assigneeId: z.string().uuid().nullish(), - prUrl: z.string().url().nullish(), + assigneeId: z.uuid().nullish(), + prUrl: z.url().nullish(), estimate: z.number().int().positive().nullish(), - dueDate: z.string().datetime().nullish().describe("ISO 8601 due date."), + dueDate: z.iso.datetime().nullish().describe("ISO 8601 due date."), labels: z.array(z.string()).nullish(), },🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/mcp/src/tools/tasks/update.ts` around lines 13 - 25, Replace the deprecated chained Zod string-format validators in the update task schema: use top-level z.uuid() for id and statusId, z.url() for prUrl, and z.iso.datetime() for dueDate while preserving optional/nullish behavior and descriptions. Apply the same migration pattern to the corresponding schemas in the other listed task, terminal, automation, and workspace tools, after confirming existing UUID values satisfy the stricter validation.packages/mcp/src/tools/automations/create.ts (1)
37-46: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winVerify the "one of" requirement is enforced somewhere.
The description says either
v2ProjectIdorv2WorkspaceIdis required. The schema marks both fields optional. A call that omits both passes MCP input validation and only fails later, insidecaller.automation.create.Confirm that
caller.automation.createrejects the case where both fields are missing with a clear error message. If it does not, add an explicit check in the handler.🛡️ Proposed handler-level guard, if not already enforced downstream
handler: async (input, ctx) => { + if (!input.v2ProjectId && !input.v2WorkspaceId) { + throw new Error( + "Provide either v2ProjectId or v2WorkspaceId.", + ); + } const caller = createMcpCaller(ctx); return caller.automation.create(input); },🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/mcp/src/tools/automations/create.ts` around lines 37 - 46, Verify that the handler or caller used by the automation creation flow rejects requests where both v2ProjectId and v2WorkspaceId are absent, with a clear error message. If caller.automation.create does not enforce this, add an explicit guard in the create handler before invoking it; preserve acceptance when either identifier is provided.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/mcp/src/host-service-client.ts`:
- Around line 40-44: Update hostServiceCall to bound its fetch request with an
abort signal and a finite timeout, ensuring unresponsive hosts fail promptly
with a clear timeout error. Pass the signal into the existing fetch call and
preserve the current method, headers, and body behavior.
In `@packages/mcp/src/tools/workspaces/create.ts`:
- Around line 31-45: Update the handler that dispatches through hostServiceCall
to validate that exactly one of the optional inputs, branch or pr, is provided
before dispatching. Reject requests where both are present or both are absent
with a clear validation error, while preserving dispatch for valid inputs;
implement this in the handler rather than applying refine to the raw inputSchema
shape.
---
Nitpick comments:
In `@apps/api/src/app/mcp/route.ts`:
- Around line 14-25: Extract the duplicated OAuth authentication failure
construction from unauthorizedResponse and the unauthorized handler in the API
route into shared helpers, including the Bearer challenge built from
getOAuthProtectedResourceMetadataUrl and the UNAUTHORIZED JSON envelope. Update
both callers to reuse these helpers while preserving the 401 status and
consistent WWW-Authenticate and Content-Type headers.
In `@packages/mcp/src/tools/automations/create.ts`:
- Around line 37-46: Verify that the handler or caller used by the automation
creation flow rejects requests where both v2ProjectId and v2WorkspaceId are
absent, with a clear error message. If caller.automation.create does not enforce
this, add an explicit guard in the create handler before invoking it; preserve
acceptance when either identifier is provided.
In `@packages/mcp/src/tools/automations/get_prompt.ts`:
- Line 13: Replace deprecated chained Zod validators: in
packages/mcp/src/tools/automations/get_prompt.ts:13-13, logs.ts:13-13,
resume.ts:13-13, set_prompt.ts:13-13, and
packages/mcp/src/tools/workspaces/delete.ts:17-17, use z.uuid() for the
identified UUID fields; in packages/mcp/src/tools/tasks/create.ts:15-36, use
z.uuid() for statusId and assigneeId and z.iso.datetime() for dueDate.
In `@packages/mcp/src/tools/tasks/update.ts`:
- Around line 13-25: Replace the deprecated chained Zod string-format validators
in the update task schema: use top-level z.uuid() for id and statusId, z.url()
for prUrl, and z.iso.datetime() for dueDate while preserving optional/nullish
behavior and descriptions. Apply the same migration pattern to the corresponding
schemas in the other listed task, terminal, automation, and workspace tools,
after confirming existing UUID values satisfy the stricter validation.
In `@packages/mcp/src/tools/workspaces/update.ts`:
- Line 17: Update the workspace ID schema in the relevant update tool definition
from the deprecated string-based UUID chain to Zod 4’s top-level UUID validator,
and verify that accepted workspace IDs meet its stricter RFC 9562/4122
variant-bit requirements without adding a compatibility fallback.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 6b2b0b95-9293-4c56-9e8c-205ca0f039aa
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (55)
apps/api/package.jsonapps/api/src/app/.well-known/mcp/route.tsapps/api/src/app/.well-known/mcp/server-card.json/route.tsapps/api/src/app/api/[...unmatched]/route.tsapps/api/src/app/api/agent/[transport]/route.tsapps/api/src/app/api/integrations/slack/events/utils/run-agent/mcp-clients.tsapps/api/src/app/api/route.tsapps/api/src/app/api/v2/agent/[transport]/route.tsapps/api/src/app/mcp/route.tsapps/api/src/app/openapi.json/route.tsapps/docs/content/docs/mcp-server.mdxapps/marketing/src/lib/llms.tspackages/mcp/package.jsonpackages/mcp/src/auth.tspackages/mcp/src/caller.tspackages/mcp/src/context-utils.tspackages/mcp/src/define-tool.tspackages/mcp/src/host-service-client.tspackages/mcp/src/in-memory.tspackages/mcp/src/index.tspackages/mcp/src/server.tspackages/mcp/src/tools/agents/create.tspackages/mcp/src/tools/agents/list.tspackages/mcp/src/tools/automations/create.tspackages/mcp/src/tools/automations/delete.tspackages/mcp/src/tools/automations/get.tspackages/mcp/src/tools/automations/get_prompt.tspackages/mcp/src/tools/automations/list.tspackages/mcp/src/tools/automations/logs.tspackages/mcp/src/tools/automations/pause.tspackages/mcp/src/tools/automations/resume.tspackages/mcp/src/tools/automations/run.tspackages/mcp/src/tools/automations/set_prompt.tspackages/mcp/src/tools/automations/update.tspackages/mcp/src/tools/hosts/list.tspackages/mcp/src/tools/organization/members/list.tspackages/mcp/src/tools/projects/list.tspackages/mcp/src/tools/register.tspackages/mcp/src/tools/tasks/create.tspackages/mcp/src/tools/tasks/delete.tspackages/mcp/src/tools/tasks/get.tspackages/mcp/src/tools/tasks/list.tspackages/mcp/src/tools/tasks/statuses/list.tspackages/mcp/src/tools/tasks/update.tspackages/mcp/src/tools/terminals/close.tspackages/mcp/src/tools/terminals/create.tspackages/mcp/src/tools/terminals/list.tspackages/mcp/src/tools/terminals/read.tspackages/mcp/src/tools/terminals/send.tspackages/mcp/src/tools/workspaces/create.tspackages/mcp/src/tools/workspaces/delete.tspackages/mcp/src/tools/workspaces/list.tspackages/mcp/src/tools/workspaces/update.tspackages/mcp/tsconfig.jsonpackages/shared/src/constants.ts
💤 Files with no reviewable changes (1)
- packages/shared/src/constants.ts
🛑 Comments failed to post (2)
packages/mcp/src/host-service-client.ts (1)
40-44: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Add a request timeout to
hostServiceCall.The
fetchcall has no timeout or abort signal. If a host is slow or unresponsive, the call can hang for the full routemaxDuration(800 seconds perapps/api/src/app/mcp/route.ts). Every MCP tool that calls a host (agents, workspaces, terminals, projects) shares this risk throughhostServiceCall.Add a bounded timeout so a dead host fails fast with a clear error instead of hanging the request.
🔧 Proposed fix: bound the request with a timeout
const response = await fetch(url, { method: method === "query" ? "GET" : "POST", headers, body, + signal: AbortSignal.timeout(30_000), });📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.const response = await fetch(url, { method: method === "query" ? "GET" : "POST", headers, body, signal: AbortSignal.timeout(30_000), });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/mcp/src/host-service-client.ts` around lines 40 - 44, Update hostServiceCall to bound its fetch request with an abort signal and a finite timeout, ensuring unresponsive hosts fail promptly with a clear timeout error. Pass the signal into the existing fetch call and preserve the current method, headers, and body behavior.packages/mcp/src/tools/workspaces/create.ts (1)
31-45: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Enforce "exactly one of
branchorpr" before dispatching.The description states that the caller must provide exactly one of
branchorpr. The schema does not enforce this, and the handler does not check it either. If a caller passes both or neither, the request goes tohostServiceCallunvalidated, producing a less clear error for the calling agent.Add an explicit check in the handler. Since
defineTool'sinputSchemais a raw shape (not aZodObject), a schema-level.refine()is not directly available here.🐛 Proposed handler-level check
handler: async (input, ctx) => { + if ((input.branch === undefined) === (input.pr === undefined)) { + throw new Error("Provide exactly one of `branch` or `pr`."); + } return hostServiceCall<{Also applies to: 73-77
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/mcp/src/tools/workspaces/create.ts` around lines 31 - 45, Update the handler that dispatches through hostServiceCall to validate that exactly one of the optional inputs, branch or pr, is provided before dispatching. Reject requests where both are present or both are absent with a clear validation error, while preserving dispatch for valid inputs; implement this in the handler rather than applying refine to the raw inputSchema shape.
Stacked on #6077 (needs the v1 package deleted first to free the name); retargets automatically as the stack merges.
Two commits:
1. Mechanical rename (git mv, history preserved):
packages/mcp-v2/→packages/mcp/;@superset/mcp-v2→@superset/mcp; all import specifiers + theapps/apiworkspace dep; removes the orphaned SLACK_MCP_V2 doc comment left by chore(api): retire SLACK_MCP_V2 flag and v1 Slack MCP path #6076.2. De-versioning sweep — after this PR, the MCP is just "the MCP" everywhere a user can see:
https://api.superset.sh/mcpin every advertised surface: docs (all 20 client-setup snippets + callout), marketingllms.txt,.well-known/mcp, server card, openapi (path entry + description), API root/404 hints, and the v1 410 hint./api/v2/agent/mcpkeeps serving forever as a legacy alias (its OAuth audience remains valid; fix(auth): accept /mcp alias as OAuth audience #6078 made/mcpvalid too).superset-v2→superset; internal cosmetic strings ([mcp-v2]log prefix,mcp-v2-internalclient id, caller request id prefix) de-versioned.Deliberately kept (continuity, not user-visible): telemetry
mcp_server: "superset-v2"(PostHog insights key on it) and theuserAgent: "mcp-v2"pair matched bypackages/trpcautomation helpers.Verify post-deploy:
.well-known/mcp+ server card advertise/mcp;claude mcp add --transport http https://api.superset.sh/mcpconnects and lists tools; existing clients on the versioned URL unaffected.https://claude.ai/code/session_01Kub4p3Eim9pc1qaRRmGea2
3. Handler inversion (third commit): the MCP implementation now physically lives at
apps/api/src/app/mcp/route.ts(the canonical URL);apps/api/src/app/api/v2/agent/[transport]/route.tsis reduced to a 4-line re-export kept for already-configured clients. Both URLs serve byte-identical behavior.Summary by CodeRabbit
/mcpas the primary MCP server endpoint with authentication and organization-aware access.