feat(studio-mcp): add 25+ MCP tools for full agent coverage#312
feat(studio-mcp): add 25+ MCP tools for full agent coverage#312betterclever merged 10 commits intomainfrom
Conversation
Extract 13 existing MCP tools from monolithic studio-mcp.service.ts (727 lines) into separate files under tools/ directory: - tools/types.ts: shared types, permission checker, result helpers - tools/workflow.tools.ts: 7 workflow tools + task monitor - tools/component.tools.ts: 2 component tools - tools/run.tools.ts: 4 run tools Service is now a thin orchestrator (~55 lines) that creates the MCP server and delegates to tool registration functions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: betterclever <paliwal.pranjal83@gmail.com>
… children) Expand StudioMcpDeps interface with optional services for trace, node-io, log-stream, artifacts, schedules, secrets, and human-inputs. Add 6 new run-scoped tools: get_run_config, get_run_trace, list_run_node_io, get_node_io (with full data fetch), get_run_logs (cursor pagination), and list_child_runs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: betterclever <paliwal.pranjal83@gmail.com>
Add 3 artifact tools: list_artifacts (filter by workflow/search), list_run_artifacts, and view_artifact with byte-level windowing for large files. Includes text/binary detection via MIME type and content heuristics. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: betterclever <paliwal.pranjal83@gmail.com>
Add 16 new MCP tools: - Schedules (8): list, get, create, update, delete, pause, resume, trigger - Secrets (5): list, create, rotate, update_metadata, delete (no value exposure) - Human inputs (3): list, get, resolve (approve/reject) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: betterclever <paliwal.pranjal83@gmail.com>
Import StorageModule, NodeIOModule, SchedulesModule, SecretsModule, and HumanInputsModule into StudioMcpModule. Inject all services into StudioMcpService (@optional for graceful degradation) and register all tool groups. Export SchedulesService from SchedulesModule. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: betterclever <paliwal.pranjal83@gmail.com>
Update tool list assertion with 17 new tools. Export monitorWorkflowRun from workflow.tools.ts and update test to call it directly instead of via service instance. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: betterclever <paliwal.pranjal83@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d06fc4675f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| }, | ||
| }, | ||
| async (args: { workflowId?: string; search?: string; limit?: number }) => { | ||
| const gate = checkPermission(auth, 'artifacts.read'); |
There was a problem hiding this comment.
Extend API-key scopes before gating new MCP tools
This gate checks artifacts.read, but API-key auth currently normalizes permissions to only workflows, runs, and audit (see backend/src/auth/auth.guard.ts), so checkPermission will always reject this scope for API-key callers. The same pattern is used across the newly added artifact/secret/schedule/human-input tools, making those tools effectively unusable for standard /studio-mcp API-key sessions.
Useful? React with 👍 / 👎.
| workflowId: args.workflowId, | ||
| name: args.name, | ||
| cronExpression: args.cronExpression, | ||
| inputs: args.inputs, |
There was a problem hiding this comment.
Map schedule inputs to inputPayload before create
The schedule service consumes dto.inputPayload (runtimeInputs/nodeOverrides), but this DTO is populated with inputs instead, so user-supplied schedule inputs are silently ignored and scheduled runs execute with the default empty payload. This breaks workflows that depend on runtime inputs and can produce incorrect scheduled execution results.
Useful? React with 👍 / 👎.
| try { | ||
| const result = await humanInputsService.resolve( | ||
| args.inputId, | ||
| { action: args.action, data: args.data }, |
There was a problem hiding this comment.
Send ResolveHumanInputDto shape to resolve service
This passes { action, data }, but humanInputsService.resolve expects ResolveHumanInputDto with responseData; in the service, approval is derived from dto.responseData?.status. Because responseData is missing here, a reject action is interpreted as approved, so MCP-driven rejections can incorrectly approve pending human-input gates.
Useful? React with 👍 / 👎.
| if (!gate.allowed) return gate.error; | ||
| try { | ||
| const result = await schedulesService.trigger(auth, args.scheduleId); | ||
| return jsonResult(result); |
There was a problem hiding this comment.
Return explicit success payload for trigger_schedule
schedulesService.trigger returns void, so wrapping its return value with jsonResult(result) serializes undefined instead of a concrete response body. Clients calling trigger_schedule won’t receive a reliable success payload, which makes tool behavior ambiguous despite successful execution.
Useful? React with 👍 / 👎.
- Extend ApiKeyPermissions with artifacts, schedules, secrets, and
human-inputs scopes so API-key callers can access new MCP tools
- Normalize new scopes in auth guard alongside existing ones
- Map schedule inputs to inputPayload.runtimeInputs (not flat inputs)
- Map human-input resolve action to responseData.status DTO shape
- Return explicit { triggered: true } for trigger_schedule (void return)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: betterclever <paliwal.pranjal83@gmail.com>
- Prevent data.status from overriding action in resolve_human_input by spreading args.data before setting status (P1: approval bypass) - Add ensureRunAccess check to get_node_io to prevent cross-org data access via direct runId lookup (P1: org isolation) - Add new permission scopes to ApiKeyPermissionsSchema Zod validator so API keys can actually be granted the new MCP permissions (P2) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: betterclever <paliwal.pranjal83@gmail.com>
68 new tests across 3 test files: - run-detail-tools.spec.ts (23 tests): get_run_config, get_run_trace, list_run_node_io, get_node_io (with ensureRunAccess security check), get_run_logs, list_child_runs, permission gating - artifact-tools.spec.ts (24 tests): list_artifacts, list_run_artifacts, view_artifact (text windowing, binary detection, offset/limit, hasMore), unavailable service fallback, permission gating - domain-tools.spec.ts (21 tests): schedule CRUD (inputPayload mapping), secret CRUD, human-input resolve (DTO shape, status override prevention), permission gating for all domains Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: betterclever <paliwal.pranjal83@gmail.com>
Separate schedule, secret, and human-input tests into individual files for better organization and discoverability. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: betterclever <paliwal.pranjal83@gmail.com>
Summary
studio-mcp.service.tsinto modular tool files undertools/directoryget_run_config,get_run_trace,list_run_node_io,get_node_io(with full data fetch),get_run_logs(cursor pagination),list_child_runslist_artifacts(filter by workflow/search),list_run_artifacts,view_artifact(byte-level windowing for large files, text/binary detection)list_schedules,get_schedule,create_schedule,update_schedule,delete_schedule,pause_schedule,resume_schedule,trigger_schedulelist_secrets,create_secret,rotate_secret,update_secret,delete_secret(values never exposed)list_human_inputs,get_human_input,resolve_human_input(approve/reject)ArtifactsService,NodeIOService,TraceService,LogStreamService,SchedulesService,SecretsService,HumanInputsService) with@Optional()for graceful degradationmonitorWorkflowRunTest plan
🤖 Generated with Claude Code