> Discover all available pages from the documentation index: https://mastra.ai/llms.txt

# submitPlanTool

A built-in, agent-agnostic tool that submits an implementation plan for user review. The agent writes a plan to a markdown file and passes the file path to this tool. The tool suspends the run until the user approves or rejects the plan.

The tool pauses through the native [tool suspension](https://mastra.ai/docs/agents/agent-approval) primitive: it calls `suspend({ path })`, which makes the agent emit a `tool-call-suspended` event. The host reads the plan file, presents it to the user, and resumes with an approval or rejection.

When executed outside an agent run (no `suspend` available), the tool returns a readable fallback string containing the file path.

## Usage example

Add `submitPlanTool` to an agent's toolset:

```typescript
import { Agent } from '@mastra/core/agent'
import { submitPlanTool } from '@mastra/core/tools'

const agent = new Agent({
  id: 'planner',
  name: 'Planner',
  instructions: 'Write a plan to a file before starting work, then submit it for approval.',
  model,
  tools: { submitPlanTool },
})
```

Handle the suspension and resume:

```typescript
import fs from 'node:fs'

const stream = await agent.stream('Refactor the auth module')

for await (const chunk of stream.fullStream) {
  if (chunk.type === 'tool-call-suspended' && chunk.payload.toolName === 'submit_plan') {
    const { path } = chunk.payload.suspendPayload
    const plan = fs.readFileSync(path, 'utf-8')
    console.log(plan)

    // Approve:
    const resumed = await agent.resumeStream({ action: 'approved' }, { runId: stream.runId })
    for await (const c of resumed.textStream) process.stdout.write(c)
  }
}
```

To reject with feedback:

```typescript
await agent.resumeStream(
  { action: 'rejected', feedback: 'Add error handling steps' },
  { runId: stream.runId },
)
```

## Input schema

The model calls this tool with the following parameters:

**path** (`string`): Path to the plan markdown file on disk (e.g. '.mastracode/plans/add-dark-mode.md').

## Suspend payload

The `tool-call-suspended` event carries a `suspendPayload`:

**path** (`string`): Path to the plan file the agent wrote.

**title** (`string`): Plan title, filled by the host after reading the file.

**plan** (`string`): Plan body, filled by the host after reading the file.

## Resume data

Pass an object to `agent.resumeStream()`:

**action** (`'approved' | 'rejected'`): Whether the user approved or rejected the plan.

**feedback** (`string`): Revision instructions when the plan is rejected. Surfaced to the model so it can revise and resubmit.

**path** (`string`): The plan file path, echoed back for history replay.

**title** (`string`): The plan title, echoed back for history replay.

**plan** (`string`): The plan body, echoed back for history replay.

## Approval behavior

- **Approved:** The tool returns `"Plan approved. Proceed with implementation following the approved plan."` to the model.
- **Rejected with feedback:** The tool returns the feedback and asks the model to revise the plan and submit again.
- **Rejected without feedback:** The tool tells the model to wait for the user's next message before revising.

When used inside an [AgentController](https://mastra.ai/docs/agent-controller/overview), plan approval triggers an automatic mode switch from the planning mode to the default execution mode. See [Modes](https://mastra.ai/docs/agent-controller/modes) for details.