This document describes the Model Context Protocol (MCP) tools exposed by the DeepWork server. AI agents use these tools to discover and execute multi-step workflows.
- Server Name:
deepwork - Transport: stdio (default) or SSE
- Starting the server:
deepwork serve --path /path/to/project
DeepWork exposes eleven MCP tools:
List all available DeepWork workflows. Call this first to discover available workflows.
None.
{
jobs: JobInfo[];
errors: JobLoadErrorInfo[]; // Jobs that failed to parse
issue_detected?: string; // Present when startup issues exist; warns agent to suggest repair
}Where JobInfo is:
interface JobInfo {
name: string; // Job identifier
summary: string; // Short summary of the job
workflows: WorkflowInfo[]; // Named workflows in the job
}
interface JobLoadErrorInfo {
job_name: string; // Name of the job that failed
job_dir: string; // Path to the job directory
error: string; // Error message
}
interface WorkflowInfo {
name: string; // Workflow identifier
summary: string; // Short description
how_to_invoke: string; // Instructions for how to invoke this workflow
}Start a new workflow session. Initializes state tracking and returns the first step's instructions. Supports nested workflows — starting a workflow while one is active pushes onto a stack.
| Parameter | Type | Required | Description |
|---|---|---|---|
goal |
string |
Yes | What the user wants to accomplish |
job_name |
string |
Yes | Name of the job |
workflow_name |
string |
Yes | Name of the workflow within the job. If the name doesn't match but the job has only one workflow, that workflow is selected automatically. If the job has multiple workflows, an error is returned listing the available workflow names. |
session_id |
string | null |
No | Session identifier for persistent state storage. For Claude Code: use CLAUDE_CODE_SESSION_ID from startup context. For other platforms: omit to auto-generate; then use the value returned in begin_step.session_id for all subsequent calls. |
inputs |
Record<string, string | string[]> | null |
No | Optional input values for the first step. Map of step_argument names to values. For file_path type arguments: pass a file path string or list of file path strings. For string type arguments: pass a string value. These values are made available to the first step and flow through the workflow. |
agent_id |
string | null |
No | Agent identifier for sub-agent scoping (CLAUDE_CODE_AGENT_ID from startup context on Claude Code). When set, this workflow is scoped to this agent. |
{
important_note: string; // Instruction reminding agent to clarify ambiguous requests
begin_step: ActiveStepInfo; // Information about the first step to begin
stack: StackEntry[]; // Current workflow stack after starting
issue_detected?: string; // Present when startup issues exist; warns agent to suggest repair
}Report that you've finished a workflow step. Validates outputs and runs quality reviews (from step definitions and .deepreview rules), then returns the next action.
| Parameter | Type | Required | Description |
|---|---|---|---|
outputs |
Record<string, string | string[]> |
Yes | Map of step_argument names to values. For outputs declared with type file_path: pass a single string path or list of paths. For outputs declared with type string: pass a string value. Outputs with required: false can be omitted. Check step_expected_outputs to see each output's type and required status. |
work_summary |
string | null |
No | Summary of the work done in this step. Used by process_requirements reviews to evaluate whether the work process met quality criteria. Include key decisions, approaches taken, and any deviations from the instructions. |
quality_review_override_reason |
string | null |
No | If provided, skips quality review (must explain why) |
session_id |
string |
Yes | Session identifier from the begin_step.session_id returned by start_workflow. |
agent_id |
string | null |
No | Agent identifier for sub-agent scoping (CLAUDE_CODE_AGENT_ID from startup context on Claude Code). When set, operates on this agent's scoped workflow stack. |
{
status: "needs_work" | "next_step" | "workflow_complete";
// For status = "needs_work"
feedback?: string; // Feedback from quality reviews
// For status = "next_step"
begin_step?: ActiveStepInfo; // Information about the next step to begin
// For status = "workflow_complete"
summary?: string; // Summary of completed workflow
all_outputs?: Record<string, string | string[]>; // All outputs from all steps
post_workflow_instructions?: string; // Instructions for after workflow completion
// Always included
stack: StackEntry[]; // Current workflow stack after this operation
issue_detected?: string; // Present when startup issues exist; warns agent to suggest repair
}Abort the current workflow and return to the parent workflow (if nested). Use this when a workflow cannot be completed.
| Parameter | Type | Required | Description |
|---|---|---|---|
explanation |
string |
Yes | Why the workflow is being aborted |
session_id |
string |
Yes | Session identifier from the begin_step.session_id returned by start_workflow. |
agent_id |
string | null |
No | Agent identifier for sub-agent scoping (CLAUDE_CODE_AGENT_ID from startup context on Claude Code). When set, operates on this agent's scoped workflow stack. |
{
aborted_workflow: string; // The workflow that was aborted (job_name/workflow_name)
aborted_step: string; // The step that was active when aborted
explanation: string; // The explanation provided
stack: StackEntry[]; // Current workflow stack after abort
resumed_workflow?: string | null; // The workflow now active (if any)
resumed_step?: string | null; // The step now active (if any)
issue_detected?: string; // Present when startup issues exist; warns agent to suggest repair
}Navigate back to a prior step in the current workflow. Clears all progress from the target step onward, forcing re-execution of subsequent steps to ensure consistency. Use this when earlier outputs need revision or quality issues are discovered in later steps.
| Parameter | Type | Required | Description |
|---|---|---|---|
step_id |
string |
Yes | ID of the step to navigate back to. Must exist in the current workflow. |
session_id |
string |
Yes | Session identifier from the begin_step.session_id returned by start_workflow. |
agent_id |
string | null |
No | Agent identifier for sub-agent scoping (CLAUDE_CODE_AGENT_ID from startup context on Claude Code). When set, operates on this agent's scoped workflow stack. |
{
begin_step: ActiveStepInfo; // Information about the step to begin working on
invalidated_steps: string[]; // Step IDs whose progress was cleared (from target onward)
stack: StackEntry[]; // Current workflow stack after navigation
issue_detected?: string; // Present when startup issues exist; warns agent to suggest repair
}- Backward/current only: The target step's entry index must be <= the current entry index. To go forward, use
finished_step. - Clears subsequent progress: All
step_progressentries from the target step onward are deleted (outputs, timestamps, quality attempts). The agent must re-execute all affected steps. - Files preserved: Only session tracking state is cleared. Files on disk are not deleted — Git handles file versioning.
- Invalidation scope: All steps from the target step through the end of the workflow are invalidated and must be re-executed.
Run a review of changed files based on .deepreview configuration files and DeepSchema-generated synthetic review rules. Returns a list of review tasks to invoke in parallel. Each task has name, description, subagent_type, and prompt fields for the Task tool.
This tool operates outside the workflow lifecycle — it can be called independently at any time.
| Parameter | Type | Required | Description |
|---|---|---|---|
files |
string[] | null |
No | Explicit file paths to review. When omitted, detects changes via git diff against the default branch and includes untracked files. |
A plain string with one of:
- An informational message (no rules found, no changed files, no matches)
- Formatted review task list ready for parallel dispatch
List all configured review rules from .deepreview files and DeepSchema-generated synthetic rules. Returns each rule's name, description, and defining file location. Optionally filters to rules matching specific files.
This tool operates outside the workflow lifecycle — it can be called independently at any time.
| Parameter | Type | Required | Description |
|---|---|---|---|
only_rules_matching_files |
string[] | null |
No | File paths to filter by. When provided, only rules whose include/exclude patterns match at least one file are returned. When omitted, all rules are returned. |
Array<{
name: string; // Rule name from the .deepreview file
description: string; // Rule description
defining_file: string; // Relative path to .deepreview file with line number (e.g., ".deepreview:1")
}>Mark a review as passed so it won't be re-run while reviewed files remain unchanged. Call this when a review has no findings, when all findings have been fixed, or when remaining findings have been explicitly dismissed by the user. The review_id is provided in the instruction file's "After Review" section.
This tool operates outside the workflow lifecycle — it can be called independently at any time.
| Parameter | Type | Required | Description |
|---|---|---|---|
review_id |
string |
Yes | The deterministic review ID from the instruction file. Encodes rule name, file paths, and a content hash. |
A plain string with either:
- A confirmation message (e.g.,
"Review 'rule--file--hash' marked as passed.") - A validation error if
review_idis empty or contains path traversal
List all named DeepSchemas discovered across all schema sources (project-local, standard, and env var). Returns each schema's name, summary, and matcher patterns.
None.
Array<{
name: string; // Schema name (directory name)
summary: string; // Brief description of the schema (empty string if not set)
matchers: string[]; // Glob patterns this schema applies to
}>Register a transient job definition scoped to the current session. The job is validated against the job schema and stored so that start_workflow can discover it. Can be called multiple times to overwrite.
| Parameter | Type | Required | Description |
|---|---|---|---|
job_name |
string |
Yes | Lowercase identifier for the job (must match ^[a-z][a-z0-9_]*$) |
job_definition_yaml |
string |
Yes | Full content of a job.yml definition as a YAML string |
session_id |
string |
Yes | Session identifier (CLAUDE_CODE_SESSION_ID on Claude Code) |
{
status: "registered";
job_name: string;
job_dir: string; // Absolute path to the session job directory
message: string; // Confirmation message
}On validation failure, returns { error: string } with details about what failed.
Retrieve the YAML content of a session-scoped job definition previously registered with register_session_job.
| Parameter | Type | Required | Description |
|---|---|---|---|
job_name |
string |
Yes | Name of the session job to retrieve |
session_id |
string |
Yes | Session identifier used when the job was registered |
{
job_name: string;
job_definition_yaml: string; // Full YAML content of the job definition
}interface ExpectedOutput {
name: string; // Output name (use as key in finished_step outputs)
type: string; // "file_path" or "string"
description: string; // What this output should contain
required: boolean; // If false, this output can be omitted from finished_step
syntax_for_finished_step_tool: string; // Value format hint:
// "filepath or list of filepaths" for type "file_path"
// "string value" for type "string"
}
interface StepInputInfo {
name: string; // Step argument name
type: string; // Argument type: "file_path" or "string"
description: string; // What this input represents
value: string | string[] | null; // The input value (file path or string content), if available
required: boolean; // Whether this input is required
}
interface ActiveStepInfo {
session_id: string; // Session ID — use this for all subsequent finished_step, abort_workflow, go_to_step calls
step_id: string; // ID of the current step
project_root: string; // Absolute path to the MCP server's project root (use for .deepwork/ operations)
job_dir: string; // Absolute path to job directory (templates, scripts, etc.)
step_expected_outputs: ExpectedOutput[]; // Expected outputs with type and format hints
step_inputs: StepInputInfo[]; // Inputs provided to this step with their values
step_instructions: string; // Instructions for the step
common_job_info: string; // Common context shared across all steps in this job
}
interface StackEntry {
workflow: string; // Workflow identifier (job_name/workflow_name)
step: string; // Current step ID in this workflow
}The finished_step tool returns one of three statuses:
| Status | Meaning | Next Action |
|---|---|---|
needs_work |
Quality criteria not met | Fix issues based on feedback, call finished_step again |
next_step |
Step complete, more steps remain | Execute instructions in response, call finished_step when done |
workflow_complete |
All steps complete | Workflow is finished |
1. get_workflows()
|
Discover available jobs and workflows
|
2. start_workflow(goal, job_name, workflow_name[, session_id])
|
Get begin_step.session_id — use this for all subsequent calls
|
3. Execute step instructions, create outputs
|
4. finished_step(outputs, session_id)
|
+-- status = "needs_work" -> Fix issues, goto 4
+-- status = "next_step" -> Execute new instructions, goto 4
+-- status = "workflow_complete" -> Done!
Steps may define quality reviews that outputs must pass. When finished_step is called:
- JSON schema validation runs first (if any outputs have
json_schemadefined) - Dynamic review rules are built from step output
reviewblocks andprocess_requirements .deepreviewrules and DeepSchema-generated synthetic review rules are loaded and matched against output files that are actually changed (via git diff). Dynamic rules from stepreviewblocks run against all output files regardless of git status.- If any reviews are needed,
status = "needs_work"with review instructions - If all reviews pass (or no reviews defined), workflow advances
- There is no maximum attempt limit — the agent can retry
finished_stepindefinitely
The quality gate builds dynamic ReviewRule objects from step output review blocks. Each rule's instructions include a preamble with:
- Job context: The workflow's
common_job_info(if any) - Step inputs: Input values from prior steps, with file_path inputs shown as
@pathreferences
These rules are then processed through the standard DeepWork Reviews pipeline (matched against output files, instruction files written, formatted for the agent platform). The review output directs the agent to launch parallel Task agents for each review.
Reviews are defined on individual output refs or step_arguments in job.yml using ReviewBlock:
step_arguments:
- name: report
type: file_path
review:
strategy: individual # "individual" or "matches_together"
instructions: "Review the report for accuracy and completeness."
agent: # Optional: delegate to a specific agent type
type: "code"
additional_context: # Optional
all_changed_filenames: true
unchanged_matching_files: true
steps:
- name: write_report
outputs:
report:
review: # Override or add review at the output ref level
strategy: matches_together
instructions: "Review all output files together for consistency."
process_requirements: # Process review (evaluates work_summary)
thoroughness: "Research MUST use multiple sources (web search, analyst reports, review sites)."
user_consulted: "The user SHOULD be asked to confirm the approach."- Output-level reviews: Defined on the output ref in a step, or inherited from the step_argument's
reviewblock strategy: individual: Each matched file is reviewed separatelystrategy: matches_together: All matched files are reviewed together in one review taskprocess_requirements: Evaluates thework_summaryagainst requirement statements using RFC 2119 keywords (MUST, SHOULD, MAY, etc.). MUST/SHALL violations cause failure; SHOULD/RECOMMENDED violations fail only if easily achievable. Requireswork_summaryto be provided infinished_step.
To skip quality review (use sparingly):
- Provide
quality_review_override_reasonexplaining why review is unnecessary
Workflows can be nested — starting a new workflow while one is active pushes onto a stack:
- All tool responses include a
stackfield showing the current workflow stack - Each stack entry shows
{workflow: "job/workflow", step: "current_step"} - When a workflow completes, it pops from the stack and resumes the parent
- Use
abort_workflowto cancel the current workflow and return to parent
deepwork serve [OPTIONS]
Options:
--path PATH Project root directory (default: current directory)
--transport TYPE Transport type: stdio or sse (default: stdio)
--port PORT Port for SSE transport (default: 8000)
--platform NAME Platform identifier (e.g., 'claude'). Used by the review tool to format output.Note: --no-quality-gate and --external-runner are deprecated and hidden. Quality reviews now use the DeepWork Reviews infrastructure (dynamic review rules from job.yml + .deepreview file rules). These flags are accepted for backwards compatibility but have no effect.
Add to your .mcp.json:
{
"mcpServers": {
"deepwork": {
"command": "uvx",
"args": ["deepwork", "serve", "--path", ".", "--platform", "claude"]
}
}
}| Version | Changes |
|---|---|
| 2.3.0 | Added project_root field to ActiveStepInfo — the absolute path to the MCP server's project root. Added register_session_job and get_session_job tools for transient session-scoped job definitions. Session jobs are discoverable by start_workflow via session_id lookup — they take priority over standard discovery. Added deepplan standard job with create_deep_plan workflow. |
| 2.2.0 | session_id is now optional (`str |
| 2.1.0 | Added important_note field to StartWorkflowResponse — instructs agents to clarify ambiguous user requests via AskUserQuestion when available. |
| 2.0.0 | Breaking: session_id is now a required string parameter on all mutation tools (start_workflow, finished_step, abort_workflow, go_to_step). Added agent_id optional parameter for sub-agent scoping — sub-agents get their own isolated workflow stacks. State persistence path changed to .deepwork/tmp/sessions/<platform>/session-<id>/state.json (with sub-agent state in agent_<agent_id>.json). |
| 1.9.0 | Added go_to_step tool for navigating back to prior steps. Clears all step progress from the target step onward, forcing re-execution of subsequent steps. Supports session_id for concurrent workflow safety. |
| 1.8.0 | Added how_to_invoke field to WorkflowInfo in get_workflows response. Always populated with invocation instructions: when a workflow's agent field is set, directs callers to delegate via the Task tool; otherwise, directs callers to use the start_workflow MCP tool directly. Also added optional agent field to workflow definitions in job.yml. |
| 1.7.0 | Added mark_review_as_passed tool for review pass caching. Instruction files now include an "After Review" section with the review ID. Reviews with a .passed marker are automatically skipped by get_review_instructions. |
| 1.6.0 | Added get_configured_reviews tool for listing configured review rules without running the full pipeline. Supports optional file-based filtering. |
| 1.5.0 | Added get_review_instructions tool (originally named review) for running .deepreview-based code reviews via MCP. Added --platform CLI option to serve command. |
| 1.4.0 | Added optional session_id parameter to finished_step and abort_workflow for concurrent workflow safety. When multiple workflows are active on the stack, callers can pass the session_id (returned in ActiveStepInfo) to target the correct session. Fully backward compatible — omitting session_id preserves existing top-of-stack behavior. |
| 1.3.0 | step_expected_outputs changed from string[] to ExpectedOutput[] — each entry includes name, type, description, and syntax_for_finished_step_tool so agents know exactly what format to use when calling finished_step. |
| 1.2.0 | Quality gate now includes input files from prior steps in review payload with BEGIN INPUTS/END INPUTS and BEGIN OUTPUTS/END OUTPUTS section headers. Binary files (PDFs, etc.) get a placeholder instead of raw content. |
| 1.1.0 | Added abort_workflow tool, stack field in all responses, ReviewInfo/ReviewResult types, typed outputs as Record<string, string | string[]> |
| 1.0.0 | Initial MCP interface with get_workflows, start_workflow, finished_step |