MCP Tool Reference
All Statewright MCP tools — parameters, return values, examples
MCP Tool Reference
Statewright exposes 10 tools via the MCP gateway, plus statewright_search_docs which runs client-side in the plugin proxy. All statewright tools are always available regardless of allowed_tools restrictions (workflow control tools are never gated).
statewright_get_state
Get the current state machine state, available tools, transitions, and iteration count.
Parameters
None.
Return Value
{
"state": "planning",
"is_final": false,
"allowed_tools": ["Read", "Grep", "Glob"],
"transitions": [
{ "event": "READY", "target": "implementing" },
{ "event": "FAIL", "target": "failed" }
],
"iteration": 3,
"max_iterations": 10,
"instructions": "Read and understand the code. Do not modify files.",
"transition_count": 0,
"blocked_env": null,
"env_overrides": null,
"context": { "test_result": null },
"guards": {
"tests_passed": { "field": "test_result", "op": "eq", "value": "pass" }
}
}| Field | Type | Description |
|---|---|---|
state | string | Current state name |
is_final | boolean | Whether the current state is terminal |
allowed_tools | string[] | Tools available in the current state |
transitions | array | Available transitions with event names and targets |
iteration | integer | Tool calls made in the current state |
max_iterations | integer | null | Iteration limit for the current state |
instructions | string | null | State-specific instructions |
transition_count | integer | Total transitions since workflow was loaded |
blocked_env | string[] | null | Blocked environment variables |
env_overrides | object | null | Environment variable overrides |
context | object | Current state machine context |
guards | object | null | Guard definitions relevant to current transitions |
Example
statewright_get_state()statewright_transition
Transition the state machine to a new state by emitting an event.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
event | string | Yes | The transition event name (e.g., DONE, FAIL, PLAN_READY) |
data | object | No | Context data to merge into the state machine context. Used for guard evaluation on conditional transitions. |
Return Value (Success)
{
"transitioned": true,
"from": "planning",
"to": "implementing",
"requires_approval": false,
"transition_count": 1,
"usage": {
"transitions": 1,
"limit": 50,
"remaining": 49
}
}| Field | Type | Description |
|---|---|---|
transitioned | boolean | Always true on success |
from | string | Previous state |
to | string | New state |
requires_approval | boolean | Whether human approval is needed before proceeding |
transition_count | integer | Total transitions in this session |
usage.transitions | integer | Transitions used |
usage.limit | integer | null | Transition limit (null if unlimited) |
usage.remaining | integer | null | Transitions remaining |
usage.warning | string | Present when approaching the limit |
Error Cases
- Guard blocked:
"Transition 'DEPLOY' from state 'testing' was blocked by a guard condition." - No matching event:
"No transition for event 'UNKNOWN' in state 'planning': ..." - Final state:
"Cannot transition: state machine is in final state 'completed'."
Examples
Simple transition:
statewright_transition(event="READY")Transition with context data for guard evaluation:
statewright_transition(
event="DEPLOY",
data={"test_result": "pass", "coverage": 92}
)statewright_load_workflow
Load a named workflow. By default, resets the state machine to the workflow's initial state. With resume=true, restores the state and context from the last paused run.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Workflow name to load (e.g., bugfix, etl-pipeline) |
session_id | string | No | Client session identifier for per-session state isolation |
project_id | string | No | Project identifier (cwd hash) for per-project run scoping |
resume | boolean | No | Resume from the last paused run instead of starting fresh |
Example
statewright_load_workflow(name="bugfix")Resume a paused workflow:
statewright_load_workflow(name="tdd-feature", resume=true)If no paused run exists for that workflow, resume=true falls back to starting fresh. When a paused run is found, the gateway restores its state and context, sets the run back to running, and returns "resumed": true. The same run_id is reused so the audit trail is continuous.
Note: iteration count resets to 0 on resume, but transition count and context are preserved. Guards on transitions after resume will evaluate against the restored context (see Guard Timing for how guards interact with context).
statewright_list_workflows
List all available named workflows and which one is currently active.
Parameters
None.
Example
statewright_list_workflows()Returns the names of all workflows registered with the gateway and indicates which (if any) is currently loaded.
statewright_get_status
Get gateway status: active workflow, current state, available workflows.
Parameters
None.
Example
statewright_get_status()Returns a summary combining the active workflow name, current state, and the full list of available workflows. Use this for a quick overview without the full detail of statewright_get_state.
statewright_deactivate
Deactivate workflow enforcement. All tools pass through without restriction.
Parameters
None.
Example
statewright_deactivate()After deactivation, tool calls are no longer gated. The agent has unrestricted access to all tools. Use this to exit a workflow early without reaching a final state.
statewright_pause
Pause the current workflow, saving state and context to the run record. The run status changes to paused. Resume later with statewright_load_workflow(name, resume=true).
Parameters
None. This tool takes no arguments.
Return Value
{
"paused": true,
"state": "implementing",
"workflow": "tdd-feature",
"run_id": "abc-123"
}The difference from statewright_deactivate: deactivate discards the run (status stopped) and clears all local enforcement state. Pause saves the run on the gateway (status paused, state and context preserved in the database). Locally, both clear enforcement — the preserved state lives on the server, not the client.
statewright_force_state
Force the state machine to a specific state, bypassing guards and transitions. Only available when the workflow has "debug": true in its meta block. Returns an error otherwise.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
state | string | Yes | Target state name to jump to |
context | object | No | Context values to merge (patches on top of existing context) |
Example
statewright_force_state(
state="refactoring",
context={"test_result": "pass", "build_ok": true}
)When you force to a state, you're bypassing the transitions that would normally set context fields. If downstream transitions have guards (e.g., test_result == "pass"), you need to pass those values via the context parameter — otherwise the guards will check the old context and fail. See Guard Timing.
If you just need to pick up where you left off, statewright_pause + statewright_load_workflow(resume=true) is the better option — it preserves context without bypassing guards. Use force_state when you need to jump to a state you weren't in, or when the context needs manual correction. Not for production workflows. The audit trail records that a force was used.
If meta.debug is not true in the active workflow, this tool returns: "statewright_force_state is only available when meta.debug is true."
statewright_create_workflow
Create a new workflow from a JSON definition.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Workflow name (lowercase, hyphens, e.g., data-pipeline) |
definition | object | Yes | Full workflow definition matching the schema |
Example
statewright_create_workflow(
name="code-review",
definition={
"id": "code-review",
"initial": "reading",
"states": {
"reading": {
"allowed_tools": ["Read", "Grep", "Glob"],
"instructions": "Read the PR diff. Identify issues.",
"max_iterations": 15,
"on": {
"DONE": "reporting"
}
},
"reporting": {
"allowed_tools": ["Read", "Write"],
"instructions": "Write the review summary.",
"on": {
"DONE": "complete"
}
},
"complete": { "type": "final" }
}
}
)The definition must conform to the workflow schema at https://statewright.ai/workflow-schema.json. See the Schema Reference for field documentation.
statewright_run_agent
Run a state-machine-constrained agent to fix bugs or build features. Spawns the local Rust agent executor (sw-agent) with direct-to-Ollama communication and streams progress back.
Use this for per-state direct execution. When a workflow state needs a local commodity model instead of the TUI's frontier model, call statewright_run_agent with the state parameter. The TUI orchestrates the workflow; this tool delegates one state at a time to the Rust agent running on local Ollama.
When to use
Mark workflow states with "model": "ollama:gemma4:31b" (or any ollama:* prefix) to indicate they should be executed by the local agent rather than the TUI's native model. Then call statewright_run_agent with state set to that state name. The agent executes just that state (reads files, makes edits, runs tests) and returns. The gateway state advances automatically.
This is the direct execution pattern — the TUI handles exploration and planning (where conversation context and frontier reasoning help), and delegates precision states (implementing edits, running tests) to the Rust agent which talks directly to Ollama with zero middleware overhead.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
task | string | Yes | What to fix or build — include specific details the agent needs |
state | string | No | Execute only this state then exit (e.g., implementing). Omit for full workflow run. |
model | string | No | Ollama model to use (default: gemma4:31b) |
ollama_url | string | No | Ollama API endpoint (default: http://localhost:11434/v1) |
workdir | string | No | Working directory (default: current directory) |
Examples
Per-state execution (TUI orchestrates, agent handles one state):
statewright_run_agent(
task="Replace max(powers.values()) with sum(powers.values()) on lines 130 and 142 of monomials.py",
state="implementing",
model="gemma4:31b",
workdir="/path/to/project"
)Full workflow run:
statewright_run_agent(
task="Fix the failing tests",
model="gemma4:31b"
)Workflow integration pattern
In your workflow JSON, mark states for direct execution with the model field:
{
"implementing": {
"model": "ollama:gemma4:31b",
"instructions": "Apply the fix using edit_line.",
"allowed_tools": ["Read", "Edit", "Bash"],
"max_iterations": 15,
"on": { "DONE": "testing" }
}
}When the TUI enters this state, it should call statewright_run_agent(state="implementing", ...) instead of processing it with its own model. The ollama: prefix in the model field signals direct execution — the TUI delegates, the Rust agent executes.
After the agent completes, the gateway state advances automatically (the agent's transition is synced back). The TUI can then call statewright_get_state to see the new state and continue orchestrating.
Cost optimization
This enables model ladders — the workflow declares which states are cheap (local GPU, $0) and which need frontier reasoning. The TUI only burns frontier tokens on states that require them:
| State type | Model | Cost |
|---|---|---|
| Exploration/planning | Frontier (opus, sonnet) | Per-token API cost |
| Precision edits | Local (gemma4:31b) | $0 (local GPU) |
| Test running | Cheap (haiku) or programmatic | Minimal |
The state machine makes this observable — each checkpoint is a cost decision.
statewright_search_docs
Search statewright documentation for workflow schema fields, MCP tools, patterns, and troubleshooting. Returns relevant doc snippets.
This tool runs client-side in the plugin proxy (not the gateway). It queries a local search index embedded in the proxy script.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Search query (e.g., guard operators, allowed_tools, approval gate) |
Example
statewright_search_docs(query="guard operators")Tool Call Flow
A typical workflow session follows this sequence:
1. statewright_load_workflow(name="bugfix")
2. statewright_get_state() # check initial state
3. [agent works within allowed tools]
4. statewright_transition(event="READY") # advance to next phase
5. statewright_get_state() # check new state
6. [agent works within new allowed tools]
7. statewright_transition(event="DONE") # advance again
8. [repeat until final state]The agent calls statewright_get_state to understand what tools are available and what transitions exist. It calls statewright_transition to move forward. The gateway enforces allowed_tools on every other tool call in between.