@mastra/acp 0.2.0 → 0.2.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # @mastra/acp
2
2
 
3
+ ## 0.2.1-alpha.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Fixed ACP tools to keep their default session alive across executions. ([#17516](https://github.com/mastra-ai/mastra/pull/17516))
8
+
9
+ - Updated dependencies [[`f82cc72`](https://github.com/mastra-ai/mastra/commit/f82cc72edca0ce636fe18abaf2598d89a0c6bcca), [`fcf6027`](https://github.com/mastra-ai/mastra/commit/fcf602747f6771731dda268ff3493b836f9f0ee9)]:
10
+ - @mastra/core@1.41.0-alpha.0
11
+
3
12
  ## 0.2.0
4
13
 
5
14
  ### Minor Changes
@@ -3,7 +3,7 @@ name: mastra-acp
3
3
  description: Documentation for @mastra/acp. Use when working with @mastra/acp APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/acp"
6
- version: "0.2.0"
6
+ version: "0.2.1-alpha.0"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -16,7 +16,12 @@ Read the individual reference documents for detailed explanations and code examp
16
16
 
17
17
  ### Docs
18
18
 
19
- - [ACP](references/docs-agents-acp.md) - Wrap ACP-compatible coding agents as Mastra tools or sub-agents.
19
+ - [Agent Client Protocol (ACP)](references/docs-agents-acp.md) - Wrap ACP-compatible coding agents as Mastra tools or sub-agents.
20
+
21
+ ### Reference
22
+
23
+ - [Reference: AcpAgent class](references/reference-acp-acp-agent.md) - API reference for the AcpAgent class, which wraps an ACP-compatible coding agent as a Mastra subagent.
24
+ - [Reference: createACPTool()](references/reference-acp-create-acp-tool.md) - API reference for createACPTool(), which wraps an ACP-compatible coding agent as a Mastra tool.
20
25
 
21
26
 
22
27
  Read [assets/SOURCE_MAP.json](assets/SOURCE_MAP.json) for source code references.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.2.0",
2
+ "version": "0.2.1-alpha.0",
3
3
  "package": "@mastra/acp",
4
4
  "exports": {},
5
5
  "modules": {}
@@ -1,8 +1,8 @@
1
- # ACP (Agent Client Protocol)
1
+ # Agent Client Protocol
2
2
 
3
3
  Mastra supports the [Agent Client Protocol (ACP)](https://agentclientprotocol.com/overview/introduction) for running ACP-compatible coding agents from a Mastra agent. Use `@mastra/acp` to wrap a coding agent process as a Mastra tool or as a subagent.
4
4
 
5
- ACP is useful for coding agents such as Claude Code, Amp, Codex, or any other executable that implements the Agent Client Protocol over standard input and output.
5
+ ACP is useful for coding agents such as Claude Code, Amp, Codex, or any other executable that implements ACP over standard input and output.
6
6
 
7
7
  ## When to use ACP
8
8
 
@@ -23,14 +23,14 @@ The flow is:
23
23
  3. The client sends ACP `initialize` and `session/new` requests.
24
24
  4. Mastra sends the user task to the ACP agent with `session/prompt`.
25
25
  5. The ACP agent streams session updates and message chunks back to Mastra.
26
- 6. Mastra returns the buffered output, emits streaming chunks, or suspends for permission input.
27
- 7. The ACP process stays alive by default, or stops after the prompt when `persistSession` is `false`.
26
+ 6. Mastra returns the buffered output, emits streaming chunks, or handles permission input.
27
+ 7. The ACP connection stops the process after the prompt when `persistSession` is `false`; `AcpAgent` can keep a reusable process alive across calls by default.
28
28
 
29
29
  During execution, the ACP client also handles permission requests and file operations. File reads and writes go through Mastra's `Workspace`, so the ACP agent operates inside the workspace you provide.
30
30
 
31
31
  ## Getting started
32
32
 
33
- Install `@mastra/acp` in a project that already uses `@mastra/core`:
33
+ Install `@mastra/acp` in a project that already uses `@mastra/core`. The package requires `@mastra/core` version `1.34.0` or later.
34
34
 
35
35
  **npm**:
36
36
 
@@ -58,14 +58,12 @@ bun add @mastra/acp
58
58
 
59
59
  `@mastra/acp` exports two APIs:
60
60
 
61
- - `createACPTool`: Create a Mastra tool that sends a `task` string to an ACP agent and returns an `output` string.
62
- - `AcpAgent`: Wrap an ACP agent as a Mastra subagent with `generate()` and `stream()` support.
63
-
64
- The package requires `@mastra/core` version `1.34.0` or later.
61
+ - [`createACPTool()`](https://mastra.ai/reference/acp/create-acp-tool): Create a Mastra tool that sends a `task` string to an ACP agent and returns an `output` string.
62
+ - [`AcpAgent`](https://mastra.ai/reference/acp/acp-agent): Wrap an ACP agent as a Mastra subagent with `generate()` and `stream()` support.
65
63
 
66
64
  ## Use ACP as a subagent
67
65
 
68
- Use `AcpAgent` when a parent Mastra agent should delegate directly to an ACP-compatible coding agent as a subagent. Create the ACP agent, then register it in the parent agent's `agents` map.
66
+ Use `AcpAgent` when a parent Mastra agent should delegate directly to an ACP-compatible coding agent as a subagent.
69
67
 
70
68
  ```typescript
71
69
  import { AcpAgent } from '@mastra/acp'
@@ -84,18 +82,18 @@ export const codeSupervisor = new Agent({
84
82
  id: 'code-supervisor',
85
83
  name: 'Code Supervisor',
86
84
  instructions: 'Delegate code editing tasks to the code-agent subagent.',
87
- model: 'openai/gpt-5.4',
85
+ model: 'openai/gpt-5.5',
88
86
  agents: {
89
87
  codeAgent,
90
88
  },
91
89
  })
92
90
  ```
93
91
 
94
- `AcpAgent.generate()` buffers the ACP response and returns it as text. `AcpAgent.stream()` emits Mastra `text-delta` chunks as ACP `agent_message_chunk` updates arrive.
92
+ See the [AcpAgent reference](https://mastra.ai/reference/acp/acp-agent) for all options, methods, and configuration.
95
93
 
96
94
  ## Use ACP as a tool
97
95
 
98
- Use `createACPTool` when the parent Mastra agent should decide when to call the ACP agent as a tool. The following example creates a code editing tool and registers it on a parent agent:
96
+ Use `createACPTool()` when the parent Mastra agent should decide when to call the ACP agent as a tool.
99
97
 
100
98
  ```typescript
101
99
  import { createACPTool } from '@mastra/acp'
@@ -113,178 +111,43 @@ export const codeSupervisor = new Agent({
113
111
  id: 'code-supervisor',
114
112
  name: 'Code Supervisor',
115
113
  instructions: 'Use the code-agent tool when a task requires repository inspection or code edits.',
116
- model: 'openai/gpt-5.4',
114
+ model: 'openai/gpt-5.5',
117
115
  tools: {
118
116
  codeAgentTool,
119
117
  },
120
118
  })
121
119
  ```
122
120
 
123
- Use the `command` and `args` required by the ACP-compatible agent you run. The tool input schema has a single `task` string, and the output schema returns the final ACP response as `output`.
124
-
125
- If the ACP agent requests permission, the tool can suspend and resume through Mastra's tool suspension flow. Use `onPermissionRequest` when you need custom permission behavior.
126
-
127
- ## Options reference
128
-
129
- `createACPTool` and `AcpAgent` accept the same ACP connection options. `AcpAgent` also accepts `name` to set the display name used during agent delegation.
130
-
131
- | Option | Type | Description |
132
- | --------------------- | -------------------------------- | --------------------------------------------------------------------------------------- |
133
- | `id` | `string` | Unique tool or subagent identifier. |
134
- | `description` | `string` | Description shown to the model when it can call the tool or delegate to the subagent. |
135
- | `command` | `string` | ACP agent executable to spawn. |
136
- | `args` | `string[]` | Arguments passed to the ACP agent executable. |
137
- | `env` | `Record<string, string>` | Environment variables to merge with the current process environment. |
138
- | `cwd` | `string` | Working directory for the ACP process, ACP session, and default workspace. |
139
- | `session` | `Partial<NewSessionRequest>` | ACP session creation options. Defaults to `cwd` or `process.cwd()` and no MCP servers. |
140
- | `initialize` | `Partial<InitializeRequest>` | ACP initialization options. Defaults to Mastra client information and protocol version. |
141
- | `authMethodId` | `string` | ACP authentication method ID to invoke after initialization. |
142
- | `persistSession` | `boolean` | Keep the ACP process alive after execution. Defaults to `true`. |
143
- | `onPermissionRequest` | `(request) => Promise<Response>` | Callback for ACP permission requests. Defaults to selecting the first option. |
144
- | `workspace` | `Workspace` | Workspace used for ACP file reads and writes. |
145
- | `model` | `string` | Model ID to select after session creation via the ACP `session/set_model` method. |
121
+ See the [createACPTool() reference](https://mastra.ai/reference/acp/create-acp-tool) for all options and configuration.
146
122
 
147
123
  ## Model selection
148
124
 
149
- ACP agents may expose selectable models. Instead of setting an environment variable like `ANTHROPIC_MODEL`, you can pass a `model` ID directly in the configuration.
150
-
151
- ### Discover available models
152
-
153
- Call `getAvailableModels()` to see which models the ACP agent supports. This starts the agent process and returns the model list from the session:
154
-
155
- ```typescript
156
- import { AcpAgent } from '@mastra/acp'
157
-
158
- const codeAgent = new AcpAgent({
159
- id: 'code-agent',
160
- description: 'An ACP-compatible coding agent',
161
- command: 'claude',
162
- args: ['--acp'],
163
- })
164
-
165
- const models = await codeAgent.getAvailableModels()
166
- // [{ modelId: 'claude-sonnet-4-20250514', name: 'Claude Sonnet' }, ...]
167
- ```
168
-
169
- ### Set the model
125
+ ACP agents may expose selectable models. Pass `model` in the ACP configuration to select a model after session creation, or use `AcpAgent.getAvailableModels()` and `AcpAgent.setModel()` to manage models at runtime.
170
126
 
171
- Pass the `model` option to select a model at connection time:
172
-
173
- ```typescript
174
- import { AcpAgent } from '@mastra/acp'
175
-
176
- export const codeAgent = new AcpAgent({
177
- id: 'code-agent',
178
- description: 'An ACP-compatible coding agent',
179
- command: 'claude',
180
- args: ['--acp'],
181
- model: '__AI_SDK_ANTHROPIC_MODEL_SONNET__',
182
- })
183
- ```
184
-
185
- You can also change the model at runtime with `setModel()`:
186
-
187
- ```typescript
188
- await codeAgent.setModel('__AI_SDK_ANTHROPIC_MODEL_SONNET__')
189
- ```
190
-
191
- If the ACP agent advertises available models and your model ID doesn't match any of them, Mastra throws an error listing the valid options:
192
-
193
- ```text
194
- Model "bad-model-id" is not available. Available models: claude-sonnet-4-20250514, claude-haiku-4-20250514
195
- ```
196
-
197
- If the agent doesn't advertise a model list, the value is passed through without validation.
127
+ See the [AcpAgent model management methods](https://mastra.ai/reference/acp/acp-agent) for examples.
198
128
 
199
129
  ## Session lifecycle
200
130
 
201
- `createACPTool` and `AcpAgent` start the configured command on first use and create an ACP session. By default, `persistSession` is `true`, so the child process stays alive across calls.
202
-
203
- Use the default persistent session when:
204
-
205
- - The ACP agent benefits from keeping conversation or repository context.
206
- - Startup is expensive and repeated calls should reuse the same process.
207
- - A parent agent may delegate several related tasks to the same coding agent.
131
+ `AcpAgent` starts the configured command on first use and creates an ACP session. By default, `persistSession` is `true`, so the child process stays alive across calls. Set `persistSession: false` when each prompt should run in an isolated process.
208
132
 
209
- Set `persistSession: false` when each prompt should run in an isolated process:
210
-
211
- ```typescript
212
- import { AcpAgent } from '@mastra/acp'
213
-
214
- export const codeAgent = new AcpAgent({
215
- id: 'code-agent',
216
- description: 'Run one isolated ACP coding task',
217
- command: 'acp-agent',
218
- args: ['--stdio'],
219
- cwd: process.cwd(),
220
- persistSession: false,
221
- })
222
- ```
223
-
224
- With `persistSession: false`, `@mastra/acp` stops the ACP process after each prompt completes.
133
+ See the [AcpAgent session lifecycle](https://mastra.ai/reference/acp/acp-agent) section for details.
225
134
 
226
135
  ## Permission handling
227
136
 
228
- ACP agents may ask the client to choose a permission option before they continue. By default, `@mastra/acp` selects the first option returned by the ACP agent.
229
-
230
- Pass `onPermissionRequest` to inspect the request and return the selected option yourself:
231
-
232
- ```typescript
233
- import { createACPTool } from '@mastra/acp'
234
-
235
- export const codeAgentTool = createACPTool({
236
- id: 'code-agent',
237
- description: 'Use an ACP-compatible coding agent',
238
- command: 'acp-agent',
239
- args: ['--stdio'],
240
- async onPermissionRequest(request) {
241
- const allowOption = request.options.find(option => option.name === 'Allow')
242
-
243
- if (!allowOption) {
244
- return { outcome: { outcome: 'cancelled' } }
245
- }
246
-
247
- return {
248
- outcome: {
249
- outcome: 'selected',
250
- optionId: allowOption.optionId,
251
- },
252
- }
253
- },
254
- })
255
- ```
137
+ ACP agents may ask the client to choose a permission option before they continue. By default, `@mastra/acp` selects the first option returned by the ACP agent. Pass `onPermissionRequest` when you need custom permission behavior.
256
138
 
257
- Use this callback to enforce local policy, inspect the permission title, or route the decision to your own approval flow.
139
+ See the [createACPTool() permission handling](https://mastra.ai/reference/acp/create-acp-tool) section for a complete example.
258
140
 
259
141
  ## Workspace integration
260
142
 
261
- ACP file operations go through Mastra's workspace abstraction. If you don't pass `workspace`, `@mastra/acp` creates a `Workspace` backed by `LocalFilesystem` and uses `cwd` as the filesystem root.
262
-
263
- Pass a custom `Workspace` when the ACP agent should read and write through a specific filesystem implementation:
264
-
265
- ```typescript
266
- import { AcpAgent } from '@mastra/acp'
267
- import { LocalFilesystem, Workspace } from '@mastra/core/workspace'
268
-
269
- const workspace = new Workspace({
270
- filesystem: new LocalFilesystem({
271
- root: process.cwd(),
272
- }),
273
- })
274
-
275
- export const codeAgent = new AcpAgent({
276
- id: 'code-agent',
277
- description: 'Run coding tasks in a controlled workspace',
278
- command: 'acp-agent',
279
- args: ['--stdio'],
280
- workspace,
281
- })
282
- ```
143
+ ACP file operations go through Mastra's workspace abstraction. `AcpAgent` can use a `workspace` option, and `createACPTool()` uses the current Mastra workspace from the tool execution context when one is available. Without a workspace, `@mastra/acp` falls back to a `Workspace` backed by `LocalFilesystem` at `cwd` or `process.cwd()`.
283
144
 
284
- Use `cwd` and `workspace` together when the ACP process should start in one directory but file operations should use an explicitly configured workspace root.
145
+ See the [AcpAgent workspace integration](https://mastra.ai/reference/acp/acp-agent) section for custom workspace examples.
285
146
 
286
147
  ## Related
287
148
 
149
+ - [AcpAgent reference](https://mastra.ai/reference/acp/acp-agent)
150
+ - [createACPTool() reference](https://mastra.ai/reference/acp/create-acp-tool)
288
151
  - [Agent reference](https://mastra.ai/reference/agents/agent)
289
152
  - [Subagents](https://mastra.ai/docs/agents/supervisor-agents)
290
153
  - [Agent Client Protocol introduction](https://agentclientprotocol.com/overview/introduction)
@@ -0,0 +1,228 @@
1
+ # AcpAgent class
2
+
3
+ The `AcpAgent` class wraps an Agent Client Protocol (ACP)-compatible coding agent as a Mastra subagent. Use it when a parent Mastra agent should delegate repository inspection, code edits, or other ACP-backed tasks to a named subagent.
4
+
5
+ If you want the parent agent to call the ACP agent as a tool instead, use [`createACPTool()`](https://mastra.ai/reference/acp/create-acp-tool).
6
+
7
+ ## Usage example
8
+
9
+ Register an ACP-compatible coding agent in a parent agent's `agents` map:
10
+
11
+ ```typescript
12
+ import { AcpAgent } from '@mastra/acp'
13
+ import { Agent } from '@mastra/core/agent'
14
+
15
+ const codeAgent = new AcpAgent({
16
+ id: 'code-agent',
17
+ name: 'Code Agent',
18
+ description: 'An ACP-compatible coding agent that can inspect and edit files',
19
+ command: 'acp-agent',
20
+ args: ['--stdio'],
21
+ cwd: process.cwd(),
22
+ })
23
+
24
+ export const codeSupervisor = new Agent({
25
+ id: 'code-supervisor',
26
+ name: 'Code Supervisor',
27
+ instructions: 'Delegate code editing tasks to the code-agent subagent.',
28
+ model: 'openai/gpt-5.5',
29
+ agents: {
30
+ codeAgent,
31
+ },
32
+ })
33
+ ```
34
+
35
+ For Claude Code, ACP support is provided by the `@agentclientprotocol/claude-agent-acp` bridge package. Configure the ACP agent command to run the bridge, then select a Claude model after session creation:
36
+
37
+ ```typescript
38
+ import { AcpAgent } from '@mastra/acp'
39
+
40
+ export const claudeCodeAgent = new AcpAgent({
41
+ id: 'claude-code-agent',
42
+ name: 'Claude Code Agent',
43
+ description: 'Use Claude Code through ACP.',
44
+ command: 'npx',
45
+ args: ['@agentclientprotocol/claude-agent-acp'],
46
+ cwd: process.cwd(),
47
+ model: 'claude-sonnet-4-6',
48
+ })
49
+ ```
50
+
51
+ ## Constructor parameters
52
+
53
+ **id** (`string`): Unique identifier for the subagent.
54
+
55
+ **name** (`string`): Display name used during agent delegation. Defaults to \`id\`.
56
+
57
+ **description** (`string`): Description shown to the model when it can delegate to this subagent.
58
+
59
+ **command** (`string`): ACP agent executable to spawn.
60
+
61
+ **args** (`string[]`): Arguments passed to the ACP agent executable. (Default: `[]`)
62
+
63
+ **env** (`Record<string, string>`): Environment variables to merge with the current process environment when spawning the ACP process.
64
+
65
+ **cwd** (`string`): Working directory for the ACP process and ACP session. Also used as the default local filesystem base path. (Default: `process.cwd()`)
66
+
67
+ **session** (`Partial<NewSessionRequest>`): ACP session creation options. Defaults to \`cwd\` or \`process.cwd()\` and an empty MCP server list.
68
+
69
+ **initialize** (`Partial<InitializeRequest>`): ACP initialization options. Defaults to Mastra client information, the current ACP protocol version, and read/write filesystem capabilities.
70
+
71
+ **authMethodId** (`string`): ACP authentication method ID to invoke after initialization and before session creation.
72
+
73
+ **persistSession** (`boolean`): Whether to keep the ACP process and session alive after each prompt. Set to \`false\` to stop the process after each prompt completes. (Default: `true`)
74
+
75
+ **onPermissionRequest** (`(request: RequestPermissionRequest) => Promise<RequestPermissionResponse>`): Callback invoked when the ACP agent requests permission. Defaults to selecting the first permission option, or cancelling when no option is available.
76
+
77
+ **workspace** (`Workspace`): Workspace used for ACP file read and write requests. Defaults to a \`Workspace\` backed by \`LocalFilesystem\` at \`cwd\` or \`process.cwd()\`.
78
+
79
+ **model** (`ModelId`): Model ID to select after ACP session creation using the ACP \`session/set\_model\` method.
80
+
81
+ ## Properties
82
+
83
+ **id** (`TId`): Readonly subagent identifier from the constructor options.
84
+
85
+ **name** (`string`): Readonly display name for this subagent.
86
+
87
+ **description** (`string`): Readonly description shown when the parent agent can delegate to this subagent.
88
+
89
+ **connection** (`ACPConnection`): Readonly ACP connection used to start the agent process, create sessions, send prompts, stream updates, and manage models.
90
+
91
+ ## Methods
92
+
93
+ ### Generation
94
+
95
+ #### `generate(messages, options?)`
96
+
97
+ Sends the prompt to the ACP agent, buffers text chunks from the ACP response, and returns a Mastra subagent generate result.
98
+
99
+ ```typescript
100
+ const result = await codeAgent.generate('Inspect the repository and summarize the test setup')
101
+
102
+ console.log(result.text)
103
+ ```
104
+
105
+ #### `stream(messages, options?)`
106
+
107
+ Sends the prompt to the ACP agent and returns a Mastra subagent stream result. ACP `agent_message_chunk` updates are emitted as Mastra `text-delta` chunks.
108
+
109
+ ```typescript
110
+ const result = await codeAgent.stream('Refactor the selected module and explain each change')
111
+
112
+ for await (const chunk of result.fullStream) {
113
+ if (chunk.type === 'text-delta') {
114
+ process.stdout.write(chunk.payload.text)
115
+ }
116
+ }
117
+ ```
118
+
119
+ `resumeGenerate()` and `resumeStream()` are not supported and throw an error when called.
120
+
121
+ ### Model management
122
+
123
+ #### `getAvailableModels()`
124
+
125
+ Starts the ACP process if needed and returns the model list advertised by the ACP session.
126
+
127
+ ```typescript
128
+ const models = await codeAgent.getAvailableModels()
129
+ // [{ modelId: 'claude-sonnet-4-6', name: 'Claude Sonnet' }, ...]
130
+ ```
131
+
132
+ #### `setModel(modelId)`
133
+
134
+ Selects a model for the active ACP session. If the ACP agent advertises available models, the model ID must match one of them.
135
+
136
+ ```typescript
137
+ await codeAgent.setModel('claude-sonnet-4-6')
138
+ ```
139
+
140
+ ## Session lifecycle
141
+
142
+ `AcpAgent` starts the configured `command` on first use, initializes the ACP client, and creates an ACP session. By default, `persistSession` is `true`, so the process and session stay alive across `generate()`, `stream()`, `getAvailableModels()`, and `setModel()` calls.
143
+
144
+ Set `persistSession: false` when each prompt should run in a fresh ACP process:
145
+
146
+ ```typescript
147
+ import { AcpAgent } from '@mastra/acp'
148
+
149
+ export const codeAgent = new AcpAgent({
150
+ id: 'code-agent',
151
+ description: 'Run one isolated ACP coding task',
152
+ command: 'acp-agent',
153
+ args: ['--stdio'],
154
+ cwd: process.cwd(),
155
+ persistSession: false,
156
+ })
157
+ ```
158
+
159
+ With `persistSession: false`, `@mastra/acp` stops the ACP process after each prompt completes.
160
+
161
+ ## Workspace integration
162
+
163
+ ACP file operations go through Mastra's `Workspace` abstraction. If you do not pass `workspace`, `@mastra/acp` creates a `Workspace` backed by `LocalFilesystem` and uses `cwd` or `process.cwd()` as the filesystem base path.
164
+
165
+ Pass a custom `Workspace` when the ACP agent should read and write through a specific filesystem implementation:
166
+
167
+ ```typescript
168
+ import { AcpAgent } from '@mastra/acp'
169
+ import { LocalFilesystem, Workspace } from '@mastra/core/workspace'
170
+
171
+ const workspace = new Workspace({
172
+ filesystem: new LocalFilesystem({
173
+ basePath: process.cwd(),
174
+ }),
175
+ })
176
+
177
+ export const codeAgent = new AcpAgent({
178
+ id: 'code-agent',
179
+ description: 'Run coding tasks in a controlled workspace',
180
+ command: 'acp-agent',
181
+ args: ['--stdio'],
182
+ workspace,
183
+ })
184
+ ```
185
+
186
+ Use `cwd` and `workspace` together when the ACP process should start in one directory but file operations should use an explicitly configured workspace root.
187
+
188
+ ## Permission handling
189
+
190
+ ACP agents may ask the client to choose a permission option before they continue. By default, `AcpAgent` selects the first option returned by the ACP agent, or cancels when no option is available.
191
+
192
+ Pass `onPermissionRequest` to inspect the request and return your own permission response:
193
+
194
+ ```typescript
195
+ import { AcpAgent } from '@mastra/acp'
196
+
197
+ export const codeAgent = new AcpAgent({
198
+ id: 'code-agent',
199
+ description: 'Use an ACP-compatible coding agent',
200
+ command: 'acp-agent',
201
+ args: ['--stdio'],
202
+ async onPermissionRequest(request) {
203
+ const allowOption = request.options.find(option => option.name === 'Allow')
204
+
205
+ if (!allowOption) {
206
+ return { outcome: { outcome: 'cancelled' } }
207
+ }
208
+
209
+ return {
210
+ outcome: {
211
+ outcome: 'selected',
212
+ optionId: allowOption.optionId,
213
+ },
214
+ }
215
+ },
216
+ })
217
+ ```
218
+
219
+ Use this callback to enforce local policy, inspect the permission title, or route the decision to your own approval flow.
220
+
221
+ ## Related
222
+
223
+ - [Agent Client Protocol docs](https://mastra.ai/docs/agents/acp)
224
+ - [createACPTool() reference](https://mastra.ai/reference/acp/create-acp-tool)
225
+ - [Agent reference](https://mastra.ai/reference/agents/agent)
226
+ - [Subagents](https://mastra.ai/docs/agents/supervisor-agents)
227
+ - [Agent Client Protocol introduction](https://agentclientprotocol.com/overview/introduction)
228
+ - [Agent Client Protocol schema](https://agentclientprotocol.com/protocol/schema)
@@ -0,0 +1,131 @@
1
+ # createACPTool()
2
+
3
+ The `createACPTool()` function creates a Mastra tool that sends a `task` string to an Agent Client Protocol (ACP)-compatible coding agent and returns the final ACP response as `output`. Use it when a parent agent should decide when to call the ACP agent as a tool.
4
+
5
+ If you want to register the ACP agent as a Mastra subagent instead, use the [`AcpAgent` class](https://mastra.ai/reference/acp/acp-agent).
6
+
7
+ ## Usage example
8
+
9
+ Create a code editing tool and register it on a parent agent:
10
+
11
+ ```typescript
12
+ import { createACPTool } from '@mastra/acp'
13
+ import { Agent } from '@mastra/core/agent'
14
+
15
+ const codeAgentTool = createACPTool({
16
+ id: 'code-agent',
17
+ description: 'Use an ACP-compatible coding agent to inspect and edit code',
18
+ command: 'acp-agent',
19
+ args: ['--stdio'],
20
+ cwd: process.cwd(),
21
+ })
22
+
23
+ export const codeSupervisor = new Agent({
24
+ id: 'code-supervisor',
25
+ name: 'Code Supervisor',
26
+ instructions: 'Use the code-agent tool when a task requires repository inspection or code edits.',
27
+ model: 'openai/gpt-5.5',
28
+ tools: {
29
+ codeAgentTool,
30
+ },
31
+ })
32
+ ```
33
+
34
+ ## Parameters
35
+
36
+ **id** (`string`): Unique identifier for the Mastra tool.
37
+
38
+ **description** (`string`): Description shown to the model when it can call this tool.
39
+
40
+ **command** (`string`): ACP agent executable to spawn.
41
+
42
+ **args** (`string[]`): Arguments passed to the ACP agent executable. (Default: `[]`)
43
+
44
+ **env** (`Record<string, string>`): Environment variables to merge with the current process environment when spawning the ACP process.
45
+
46
+ **cwd** (`string`): Working directory for the ACP process and ACP session. Also used as the default local filesystem base path. (Default: `process.cwd()`)
47
+
48
+ **session** (`Partial<NewSessionRequest>`): ACP session creation options. Defaults to \`cwd\` or \`process.cwd()\` and an empty MCP server list.
49
+
50
+ **initialize** (`Partial<InitializeRequest>`): ACP initialization options. Defaults to Mastra client information, the current ACP protocol version, and read/write filesystem capabilities.
51
+
52
+ **authMethodId** (`string`): ACP authentication method ID to invoke after initialization and before session creation.
53
+
54
+ **persistSession** (`boolean`): Whether the ACP connection created for a tool execution disconnects after the prompt. Set to \`false\` to stop the process after each prompt completes. (Default: `true`)
55
+
56
+ **onPermissionRequest** (`(request: RequestPermissionRequest) => Promise<RequestPermissionResponse>`): Callback invoked when the ACP agent requests permission. Defaults to selecting the first permission option, or cancelling when no option is available.
57
+
58
+ **workspace** (`Workspace`): Workspace option from the shared ACP connection options. During tool execution, \`createACPTool()\` passes the current Mastra workspace from the execution context when one is available; otherwise the ACP connection falls back to a local filesystem workspace. Use \`AcpAgent\` when you need to provide an explicit workspace instance.
59
+
60
+ **model** (`ModelId`): Model ID to select after ACP session creation using the ACP \`session/set\_model\` method.
61
+
62
+ ## Input schema
63
+
64
+ **task** (`string`): The task to send to the ACP agent.
65
+
66
+ ## Output schema
67
+
68
+ **output** (`string`): The final text output returned by the ACP agent.
69
+
70
+ ## Suspend and resume schema
71
+
72
+ `createACPTool()` defines suspend and resume schemas for permission request payloads. Permission decisions are returned through `onPermissionRequest`; by default, `@mastra/acp` selects the first option returned by the ACP agent, or cancels when no option is available.
73
+
74
+ ### Suspend payload
75
+
76
+ **permissionRequest** (`{ title: string; options: { optionId: string; name: string }[] }`): Permission request title and selectable options returned by the ACP agent.
77
+
78
+ ### Resume payload
79
+
80
+ **optionId** (`string`): Permission option ID to select when resuming with \`outcome: "selected"\`.
81
+
82
+ **outcome** (`"selected" | "cancelled"`): Permission decision used to continue or cancel the ACP request.
83
+
84
+ ## Session lifecycle
85
+
86
+ Each tool execution creates an ACP connection, starts the configured `command`, initializes the ACP client, creates an ACP session, and sends the `task` with ACP `session/prompt`.
87
+
88
+ By default, `persistSession` is `true` for the ACP connection created during tool execution. Set `persistSession: false` when the ACP process should stop as soon as that prompt completes.
89
+
90
+ Use [`AcpAgent`](https://mastra.ai/reference/acp/acp-agent) when you need a reusable ACP subagent instance with explicit session lifecycle control across calls.
91
+
92
+ ## Permission handling
93
+
94
+ ACP agents may ask the client to choose a permission option before they continue. By default, `@mastra/acp` selects the first option returned by the ACP agent, or cancels when no option is available.
95
+
96
+ Pass `onPermissionRequest` to inspect the request and return your own permission response:
97
+
98
+ ```typescript
99
+ import { createACPTool } from '@mastra/acp'
100
+
101
+ export const codeAgentTool = createACPTool({
102
+ id: 'code-agent',
103
+ description: 'Use an ACP-compatible coding agent',
104
+ command: 'acp-agent',
105
+ args: ['--stdio'],
106
+ async onPermissionRequest(request) {
107
+ const allowOption = request.options.find(option => option.name === 'Allow')
108
+
109
+ if (!allowOption) {
110
+ return { outcome: { outcome: 'cancelled' } }
111
+ }
112
+
113
+ return {
114
+ outcome: {
115
+ outcome: 'selected',
116
+ optionId: allowOption.optionId,
117
+ },
118
+ }
119
+ },
120
+ })
121
+ ```
122
+
123
+ Use this callback to enforce local policy, inspect the permission title, or route the decision to your own approval flow.
124
+
125
+ ## Related
126
+
127
+ - [Agent Client Protocol docs](https://mastra.ai/docs/agents/acp)
128
+ - [AcpAgent class reference](https://mastra.ai/reference/acp/acp-agent)
129
+ - [Tool reference](https://mastra.ai/reference/tools/create-tool)
130
+ - [Agent Client Protocol introduction](https://agentclientprotocol.com/overview/introduction)
131
+ - [Agent Client Protocol schema](https://agentclientprotocol.com/protocol/schema)