@mastra/mcp-docs-server 1.2.2-alpha.9 → 1.2.3-alpha.1
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/.docs/docs/{harness → agent-controller}/modes.md +19 -19
- package/.docs/docs/agent-controller/overview.md +128 -0
- package/.docs/docs/agent-controller/session.md +143 -0
- package/.docs/docs/{harness → agent-controller}/subagents.md +12 -12
- package/.docs/docs/agent-controller/threads-and-state.md +141 -0
- package/.docs/docs/{harness → agent-controller}/tool-approvals.md +23 -23
- package/.docs/docs/agents/channels.md +47 -0
- package/.docs/docs/server/auth/google.md +281 -0
- package/.docs/docs/server/auth.md +2 -1
- package/.docs/models/gateways/vercel.md +3 -1
- package/.docs/models/index.md +1 -1
- package/.docs/models/providers/baseten.md +1 -1
- package/.docs/models/providers/fireworks-ai.md +2 -1
- package/.docs/models/providers/friendli.md +3 -1
- package/.docs/models/providers/llmgateway.md +1 -2
- package/.docs/models/providers/nebius.md +3 -2
- package/.docs/models/providers/opencode-go.md +1 -1
- package/.docs/models/providers/ovhcloud.md +1 -2
- package/.docs/models/providers/scaleway.md +2 -1
- package/.docs/models/providers/tinfoil.md +77 -0
- package/.docs/models/providers/togetherai.md +3 -2
- package/.docs/models/providers/xiaomi-token-plan-ams.md +4 -6
- package/.docs/models/providers/xiaomi-token-plan-cn.md +4 -6
- package/.docs/models/providers/xiaomi-token-plan-sgp.md +4 -6
- package/.docs/models/providers/xiaomi.md +4 -7
- package/.docs/models/providers.md +1 -0
- package/.docs/reference/{harness/harness-class.md → agent-controller/agent-controller-class.md} +106 -106
- package/.docs/reference/{harness → agent-controller}/session.md +97 -91
- package/.docs/reference/agents/channels.md +3 -1
- package/.docs/reference/agents/durable-agent.md +30 -3
- package/.docs/reference/auth/google.md +355 -0
- package/.docs/reference/channels/channel-provider.md +65 -0
- package/.docs/reference/channels/slack-provider.md +226 -0
- package/.docs/reference/index.md +5 -2
- package/CHANGELOG.md +28 -0
- package/package.json +6 -6
- package/.docs/docs/harness/overview.md +0 -128
- package/.docs/docs/harness/session.md +0 -143
- package/.docs/docs/harness/threads-and-state.md +0 -141
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# SlackProvider
|
|
2
|
+
|
|
3
|
+
`SlackProvider` is the managed path for connecting agents to Slack. Register it on `Mastra.channels` and it provisions Slack apps via the Manifest API, runs the OAuth install flow, rotates configuration tokens, and routes Slack events to your agents. Use it when you want Mastra to own app creation and installation. For the lower-level path where you create the Slack app and configure scopes and webhooks yourself, use [`createSlackAdapter`](https://mastra.ai/docs/agents/channels) on the agent's `channels.adapters` instead.
|
|
4
|
+
|
|
5
|
+
## Usage example
|
|
6
|
+
|
|
7
|
+
Register the provider on the `Mastra` constructor. The refresh token is single-use and rotates on startup; the resulting access tokens are persisted to `Mastra.storage`.
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { Mastra } from '@mastra/core/mastra'
|
|
11
|
+
import { SlackProvider } from '@mastra/slack'
|
|
12
|
+
|
|
13
|
+
export const mastra = new Mastra({
|
|
14
|
+
storage,
|
|
15
|
+
channels: {
|
|
16
|
+
slack: new SlackProvider({
|
|
17
|
+
refreshToken: process.env.SLACK_APP_CONFIG_REFRESH_TOKEN,
|
|
18
|
+
baseUrl: process.env.MASTRA_BASE_URL,
|
|
19
|
+
}),
|
|
20
|
+
},
|
|
21
|
+
})
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
When credentials aren't available at construction time (for example, entered through the Editor UI or loaded from a vault), construct the provider without them and call [`configure()`](#configurecredentials) later:
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
const slack = new SlackProvider()
|
|
28
|
+
|
|
29
|
+
await slack.configure({
|
|
30
|
+
refreshToken: process.env.SLACK_APP_CONFIG_REFRESH_TOKEN,
|
|
31
|
+
})
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Constructor parameters
|
|
35
|
+
|
|
36
|
+
`SlackProviderConfig` combines Slack-specific fields, Slack-adapter overrides (`toolDisplay`, `streaming`, `typingStatus`), and a curated subset of [`ChannelConfig`](https://mastra.ai/reference/agents/channels) options (such as `handlers`, `inlineMedia`, and `state`) forwarded to every connected agent. All fields are optional.
|
|
37
|
+
|
|
38
|
+
**refreshToken** (`string`): Slack App Configuration refresh token, used for automatic token rotation. Single-use; each rotation returns a new pair. Can also be provided later via \`configure()\`. If omitted, the provider starts unconfigured and cannot create apps until \`configure()\` is called or tokens are loaded from storage. Generate it under "Your App Configuration Tokens" at api.slack.com/apps.
|
|
39
|
+
|
|
40
|
+
**token** (`string`): Slack App Configuration access token for programmatic app creation. Optional, because the provider rotates to a fresh token on startup using \`refreshToken\`.
|
|
41
|
+
|
|
42
|
+
**baseUrl** (`string`): Public base URL for webhook and OAuth callbacks. Required when calling \`connect()\` to create apps. Can also be set via \`setBaseUrl()\` or auto-detected from the Mastra server config. For local development, use a tunnel such as \`cloudflared\`.
|
|
43
|
+
|
|
44
|
+
**encryptionKey** (`string`): Encryption key for sensitive stored data (client secret, signing secret, bot token). Use a 32+ character random string. Can be set via the \`MASTRA\_ENCRYPTION\_KEY\` env var. If omitted, secrets are stored in plaintext (not recommended for production).
|
|
45
|
+
|
|
46
|
+
**storage** (`ChannelsStorage`): Custom storage for installations. Defaults to Mastra's \`ChannelsStorage\` from the global storage. Throws if no persistent storage is available.
|
|
47
|
+
|
|
48
|
+
**redirectPath** (`string`): Path to redirect to after OAuth completion. (Default: `"/"`)
|
|
49
|
+
|
|
50
|
+
**onInstall** (`(installation: SlackInstallation) => Promise<void>`): Called when a workspace successfully installs the app.
|
|
51
|
+
|
|
52
|
+
**streaming** (`StreamingConfig | false`): Stream agent text deltas to Slack as they're generated. Pass \`{ updateIntervalMs }\` to customize the post-and-edit interval, or \`false\` to buffer text until step-finish. Disabling streaming restricts \`toolDisplay\` to static modes. (Default: `true`)
|
|
53
|
+
|
|
54
|
+
**toolDisplay** (`ToolDisplay`): How tool calls are rendered in Slack: \`'cards'\`, \`'text'\`, \`'timeline'\`, \`'grouped'\`, \`'hidden'\`, or a function. \`'hidden'\` suppresses tool call/result rendering entirely. \`'timeline'\` and \`'grouped'\` require streaming. With \`streaming: false\`, only static modes are available and the default is \`'cards'\`. (Default: `'grouped'`)
|
|
55
|
+
|
|
56
|
+
**typingStatus** (`boolean | TypingStatusFn`): Show a typing indicator while the agent works. Set \`false\` to disable, or pass a function to return custom status text per stream chunk (return \`undefined\` to fall back to the default for that chunk). (Default: `true`)
|
|
57
|
+
|
|
58
|
+
**waitUntil** (`WaitUntilFn`): Returns a \`waitUntil\` for the current Slack webhook request. Required on serverless runtimes where Hono can't bridge the platform's \`ExecutionContext\` (Vercel, AWS Lambda). Without it, the invocation freezes after the 200 ack and kills the run mid-flight. Pass the bare \`waitUntil(promise)\` from your platform SDK (for example, \`@vercel/functions\`). Cloudflare Workers and Netlify users typically don't need this.
|
|
59
|
+
|
|
60
|
+
**resolveWaitUntil** (`WaitUntilResolver`): Resolve \`waitUntil\` from the request's Hono \`Context\` when the runtime exposes it through the request and core's default doesn't cover it. Resolution order: \`waitUntil\` → \`resolveWaitUntil\` → core default.
|
|
61
|
+
|
|
62
|
+
**handlers** (`ChannelHandlers`): Override built-in event handlers (\`onDirectMessage\`, \`onMention\`). Forwarded to \`AgentChannels\` for every agent connected via this provider.
|
|
63
|
+
|
|
64
|
+
**inlineMedia** (`ChannelConfig['inlineMedia']`): Which media types to send inline to the model.
|
|
65
|
+
|
|
66
|
+
**inlineLinks** (`ChannelConfig['inlineLinks']`): Promote URLs in message text to file parts.
|
|
67
|
+
|
|
68
|
+
**threadContext** (`ChannelConfig['threadContext']`): Fetch recent thread messages from Slack when the agent joins mid-conversation.
|
|
69
|
+
|
|
70
|
+
**tools** (`ChannelConfig['tools']`): Whether to include channel tools (\`add\_reaction\`, \`remove\_reaction\`).
|
|
71
|
+
|
|
72
|
+
**state** (`ChannelConfig['state']`): State adapter for message deduplication, locking, and subscriptions. Defaults to the \`MastraStateAdapter\` backed by the Mastra instance's configured storage, so subscriptions persist across restarts.
|
|
73
|
+
|
|
74
|
+
**chatOptions** (`ChannelConfig['chatOptions']`): Additional options passed directly to the Chat SDK.
|
|
75
|
+
|
|
76
|
+
**logger** (`SlackAdapterConfig['logger']`): Logger forwarded to the underlying \`SlackAdapter\`. Defaults to the adapter's \`ConsoleLogger\`.
|
|
77
|
+
|
|
78
|
+
## Methods
|
|
79
|
+
|
|
80
|
+
### Agent connections
|
|
81
|
+
|
|
82
|
+
#### `connect(agentId, options?)`
|
|
83
|
+
|
|
84
|
+
Creates a new Slack app for the agent via the Manifest API and returns an OAuth result with the authorization URL to redirect the user to. Requires `baseUrl` to be set. If a pending installation already exists for the agent, returns its existing authorization URL instead of creating a duplicate app.
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
const result = await slack.connect('support-agent', {
|
|
88
|
+
name: 'Support Bot',
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
// Redirect the user to result.authorizationUrl to install the app
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Returns: `Promise<ChannelConnectResult>`
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
interface ChannelConnectResult {
|
|
98
|
+
type: 'oauth'
|
|
99
|
+
installationId: string
|
|
100
|
+
authorizationUrl: string
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`SlackConnectOptions` is serializable and can be stored for stored agents:
|
|
105
|
+
|
|
106
|
+
**name** (`string`): Display name for the Slack bot. Defaults to the agent name, then the agent ID.
|
|
107
|
+
|
|
108
|
+
**description** (`string`): Bot description shown in Slack. Defaults to "{name} - Powered by Mastra".
|
|
109
|
+
|
|
110
|
+
**iconUrl** (`string`): URL to a square image (min 512x512) for the app icon. Downloaded and uploaded to Slack automatically.
|
|
111
|
+
|
|
112
|
+
**manifest** (`(defaults: SlackAppManifest) => SlackAppManifest`): Customize the Slack app manifest before it is sent to the Manifest API. Receives the default manifest and returns the final one. Use it for custom scopes, additional events, or interactivity settings.
|
|
113
|
+
|
|
114
|
+
**redirectUrl** (`string`): URL to redirect to after successful OAuth completion. Defaults to the provider's \`redirectPath\` or \`/\`.
|
|
115
|
+
|
|
116
|
+
#### `disconnect(agentId)`
|
|
117
|
+
|
|
118
|
+
Disconnects an agent from Slack by deleting its app and removing the installation from storage.
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
await slack.disconnect('support-agent')
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Returns: `Promise<void>`
|
|
125
|
+
|
|
126
|
+
#### `getInstallation(agentId)`
|
|
127
|
+
|
|
128
|
+
Returns the Slack installation for an agent, or `null` if none exists.
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
const installation = await slack.getInstallation('support-agent')
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Returns: `Promise<SlackInstallation | null>`
|
|
135
|
+
|
|
136
|
+
#### `listInstallations()`
|
|
137
|
+
|
|
138
|
+
Lists all Slack installations (public info only), including active and pending.
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
const installations = await slack.listInstallations()
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Returns: `Promise<ChannelInstallationInfo[]>`
|
|
145
|
+
|
|
146
|
+
### Configuration
|
|
147
|
+
|
|
148
|
+
#### `configure(credentials)`
|
|
149
|
+
|
|
150
|
+
Provides or clears Slack App Configuration credentials at runtime. Use this when credentials aren't available at construction time. Pass `null` to clear credentials and delete stored tokens.
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
// Provide credentials (persists to storage immediately)
|
|
154
|
+
await slack.configure({ refreshToken: 'xoxe-1-...' })
|
|
155
|
+
|
|
156
|
+
// Clear credentials and stored tokens
|
|
157
|
+
await slack.configure(null)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Returns: `Promise<void>`
|
|
161
|
+
|
|
162
|
+
#### `setBaseUrl(baseUrl)`
|
|
163
|
+
|
|
164
|
+
Sets the public base URL used for webhook and OAuth callbacks. Use this when the URL isn't known at construction time and can't be auto-detected from the server config.
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
slack.setBaseUrl('https://abc123.trycloudflare.com')
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
#### `initialize()`
|
|
171
|
+
|
|
172
|
+
Recreates a `SlackAdapter` for each active installation in storage and injects `AgentChannels` into the corresponding agent so it receives Slack events on startup. Does not auto-provision new apps; use `connect()` to create one. Mastra calls this automatically, so you rarely call it directly.
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
await slack.initialize()
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Returns: `Promise<void>`
|
|
179
|
+
|
|
180
|
+
## Default manifest
|
|
181
|
+
|
|
182
|
+
When `connect()` builds a Slack app, the generated manifest requests a default set of bot scopes and event subscriptions. Override them with the `manifest` option on `connect()`.
|
|
183
|
+
|
|
184
|
+
| Default bot scopes | Default bot events |
|
|
185
|
+
| ------------------- | ------------------ |
|
|
186
|
+
| `chat:write` | `app_mention` |
|
|
187
|
+
| `chat:write.public` | `message.channels` |
|
|
188
|
+
| `im:write` | `message.groups` |
|
|
189
|
+
| `channels:history` | `message.im` |
|
|
190
|
+
| `channels:read` | `message.mpim` |
|
|
191
|
+
| `groups:history` | |
|
|
192
|
+
| `groups:read` | |
|
|
193
|
+
| `im:history` | |
|
|
194
|
+
| `im:read` | |
|
|
195
|
+
| `mpim:history` | |
|
|
196
|
+
| `mpim:read` | |
|
|
197
|
+
| `app_mentions:read` | |
|
|
198
|
+
| `users:read` | |
|
|
199
|
+
| `reactions:write` | |
|
|
200
|
+
| `files:read` | |
|
|
201
|
+
| `assistant:write` | |
|
|
202
|
+
|
|
203
|
+
## Accessing the provider
|
|
204
|
+
|
|
205
|
+
Access the registered provider through the typed `channels` getter, keyed by the id you registered it under:
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
const result = await mastra.channels.slack.connect('support-agent')
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
When the key is only known at runtime, look it up by string id and pass the concrete type:
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
const slack = mastra.getChannelProvider<SlackProvider>('slack')
|
|
215
|
+
const result = await slack.connect('support-agent')
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Storage requirement
|
|
219
|
+
|
|
220
|
+
`SlackProvider` requires persistent storage on `Mastra` to encrypt and persist installations and rotating configuration tokens. The constructor throws if no persistent storage is available and no custom `storage` is passed.
|
|
221
|
+
|
|
222
|
+
## Related
|
|
223
|
+
|
|
224
|
+
- [ChannelProvider](https://mastra.ai/reference/channels/channel-provider): the interface `SlackProvider` implements
|
|
225
|
+
- [Channels](https://mastra.ai/docs/agents/channels): concepts, platform setup, and the `createSlackAdapter` path
|
|
226
|
+
- [Channels reference](https://mastra.ai/reference/agents/channels): the `channels` config on the `Agent` constructor
|
package/.docs/reference/index.md
CHANGED
|
@@ -4,6 +4,8 @@ The Reference section provides documentation of Mastra's API, including paramete
|
|
|
4
4
|
|
|
5
5
|
- [AcpAgent](https://mastra.ai/reference/acp/acp-agent)
|
|
6
6
|
- [createACPTool()](https://mastra.ai/reference/acp/create-acp-tool)
|
|
7
|
+
- [AgentController Class](https://mastra.ai/reference/agent-controller/agent-controller-class)
|
|
8
|
+
- [Session Class](https://mastra.ai/reference/agent-controller/session)
|
|
7
9
|
- [Agent Class](https://mastra.ai/reference/agents/agent)
|
|
8
10
|
- [Channels](https://mastra.ai/reference/agents/channels)
|
|
9
11
|
- [createInngestAgent()](https://mastra.ai/reference/agents/inngest-agent)
|
|
@@ -45,6 +47,7 @@ The Reference section provides documentation of Mastra's API, including paramete
|
|
|
45
47
|
- [Better Auth](https://mastra.ai/reference/auth/better-auth)
|
|
46
48
|
- [Clerk](https://mastra.ai/reference/auth/clerk)
|
|
47
49
|
- [Firebase](https://mastra.ai/reference/auth/firebase)
|
|
50
|
+
- [Google](https://mastra.ai/reference/auth/google)
|
|
48
51
|
- [JSON Web Token](https://mastra.ai/reference/auth/jwt)
|
|
49
52
|
- [Okta](https://mastra.ai/reference/auth/okta)
|
|
50
53
|
- [Supabase](https://mastra.ai/reference/auth/supabase)
|
|
@@ -53,6 +56,8 @@ The Reference section provides documentation of Mastra's API, including paramete
|
|
|
53
56
|
- [BrowserViewer](https://mastra.ai/reference/browser/browser-viewer)
|
|
54
57
|
- [MastraBrowser Class](https://mastra.ai/reference/browser/mastra-browser)
|
|
55
58
|
- [StagehandBrowser](https://mastra.ai/reference/browser/stagehand-browser)
|
|
59
|
+
- [ChannelProvider](https://mastra.ai/reference/channels/channel-provider)
|
|
60
|
+
- [SlackProvider](https://mastra.ai/reference/channels/slack-provider)
|
|
56
61
|
- [create-mastra](https://mastra.ai/reference/cli/create-mastra)
|
|
57
62
|
- [mastra](https://mastra.ai/reference/cli/mastra)
|
|
58
63
|
- [Agent Builder API](https://mastra.ai/reference/client-js/agent-builder)
|
|
@@ -164,8 +169,6 @@ The Reference section provides documentation of Mastra's API, including paramete
|
|
|
164
169
|
- [.startExperimentAsync()](https://mastra.ai/reference/datasets/startExperimentAsync)
|
|
165
170
|
- [.update()](https://mastra.ai/reference/datasets/update)
|
|
166
171
|
- [.updateItem()](https://mastra.ai/reference/datasets/updateItem)
|
|
167
|
-
- [Harness Class](https://mastra.ai/reference/harness/harness-class)
|
|
168
|
-
- [Session Class](https://mastra.ai/reference/harness/session)
|
|
169
172
|
- [API Reference](https://mastra.ai/reference/mastra-platform/api)
|
|
170
173
|
- [Cloned Thread Utilities](https://mastra.ai/reference/memory/clone-utilities)
|
|
171
174
|
- [Memory Class](https://mastra.ai/reference/memory/memory-class)
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @mastra/mcp-docs-server
|
|
2
2
|
|
|
3
|
+
## 1.2.3-alpha.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`b9a2961`](https://github.com/mastra-ai/mastra/commit/b9a2961c1be81e3639c0879e58588c26dd0ae866), [`1274eb3`](https://github.com/mastra-ai/mastra/commit/1274eb3a9508f579ceb3187fbce34408222d4b71), [`1274eb3`](https://github.com/mastra-ai/mastra/commit/1274eb3a9508f579ceb3187fbce34408222d4b71), [`9566d27`](https://github.com/mastra-ai/mastra/commit/9566d27ead3d95bdbe5a69e5a082a68222829cf2)]:
|
|
8
|
+
- @mastra/core@1.48.0-alpha.0
|
|
9
|
+
|
|
10
|
+
## 1.2.2
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- Updated dependencies [[`86623c1`](https://github.com/mastra-ai/mastra/commit/86623c1adf7d22de32cc916dda17f4155184db36), [`023766f`](https://github.com/mastra-ai/mastra/commit/023766f44d59b30a50f3a381e33eddde8ab56c00), [`0200e75`](https://github.com/mastra-ai/mastra/commit/0200e7552d02d4221cd6040bf4eddf189a97a156), [`7c9dd77`](https://github.com/mastra-ai/mastra/commit/7c9dd77bd18cb8dc72797e25f1a0fbdc71a11347), [`7f9ae70`](https://github.com/mastra-ai/mastra/commit/7f9ae70826b047e5a66218f9e92f20e54a2d791f), [`a0509c7`](https://github.com/mastra-ai/mastra/commit/a0509c731a08aa3ed626557c5338126362856f57), [`06e0d63`](https://github.com/mastra-ai/mastra/commit/06e0d63d42bc2a202e18bc091f3781f409f5e6fb), [`bf3fe49`](https://github.com/mastra-ai/mastra/commit/bf3fe49f9467dbbdb8f9eaf74e0f7971ffb19559), [`01caf93`](https://github.com/mastra-ai/mastra/commit/01caf93d71ae2c1e65f49735cafb531975187426), [`438a971`](https://github.com/mastra-ai/mastra/commit/438a9715c8b4398e5eaf8914a1f19dc8a85dc1de), [`9990965`](https://github.com/mastra-ai/mastra/commit/999096571635a83b42ef40841fd7028cfa630779), [`77518cc`](https://github.com/mastra-ai/mastra/commit/77518ccb5bb8cc684875081e64213dc85cffdbee), [`fbeda0c`](https://github.com/mastra-ai/mastra/commit/fbeda0c0f35def07e6837936dd3a003b2b7c5172), [`8a68844`](https://github.com/mastra-ai/mastra/commit/8a688443013816105a09f89c6afa34b5ff13e26d), [`bb2a13b`](https://github.com/mastra-ai/mastra/commit/bb2a13bb4b32e6bb807200fe7b18ae8fa4322118), [`24ceaea`](https://github.com/mastra-ai/mastra/commit/24ceaea0bdd8609cabbab764380608ca6621a194), [`a73cd1a`](https://github.com/mastra-ai/mastra/commit/a73cd1a62a5e4ca023dcc39ba150029f4f1f74c1), [`c0ffa3c`](https://github.com/mastra-ai/mastra/commit/c0ffa3c897ccd326de880df734740a7f0681a18f), [`462a769`](https://github.com/mastra-ai/mastra/commit/462a769da61850862ca1be3d74134d33078ee6a7), [`0504bf5`](https://github.com/mastra-ai/mastra/commit/0504bf5e8cffc571a4b343326178de371e6f859b), [`0b5cc47`](https://github.com/mastra-ai/mastra/commit/0b5cc4726dc18d9a685a27520db39ff1b36bb89a), [`87f38a3`](https://github.com/mastra-ai/mastra/commit/87f38a3de03e24731f2dd6f8ed6a60b6722b85a1), [`d5fa3cd`](https://github.com/mastra-ai/mastra/commit/d5fa3cda1788c3cb93a361a3c6ec47de6ba21e98), [`fe98ef2`](https://github.com/mastra-ai/mastra/commit/fe98ef2e66dbfcbd7d645c88c9ee1e67b458a136), [`6ccf67b`](https://github.com/mastra-ai/mastra/commit/6ccf67bf075753754927a57bc2e1734ba2c820c5), [`793ea0f`](https://github.com/mastra-ai/mastra/commit/793ea0f52f831178837f21c83af6af93bf4ce638), [`825d8de`](https://github.com/mastra-ai/mastra/commit/825d8def9fa64c2bcc3d8dd6b49e09342c3ac5c7), [`507a5c4`](https://github.com/mastra-ai/mastra/commit/507a5c461bdc3136ad80744c0efbb55ce1f18f97), [`5afe423`](https://github.com/mastra-ai/mastra/commit/5afe423e4badf040f1b0d4525183a856fcb8146e), [`307573b`](https://github.com/mastra-ai/mastra/commit/307573b9ff3149b70c79540dbc86f1319b180f29), [`79b3626`](https://github.com/mastra-ai/mastra/commit/79b3626f8d647307eb07c8da14c9073c2699719d), [`c2c1d7b`](https://github.com/mastra-ai/mastra/commit/c2c1d7bb61d2602955f14ed3952f807c2d6eb576), [`86623c1`](https://github.com/mastra-ai/mastra/commit/86623c1adf7d22de32cc916dda17f4155184db36), [`1505c07`](https://github.com/mastra-ai/mastra/commit/1505c07603f6346bae12aa82f140e8b88ffea9ab), [`f328049`](https://github.com/mastra-ai/mastra/commit/f3280498c324afd2a8d36cd828f5b9f94a2dddc1), [`e545228`](https://github.com/mastra-ai/mastra/commit/e54522856934a5dc030b7b6385771e3548020d59), [`3eb852e`](https://github.com/mastra-ai/mastra/commit/3eb852e5435bc908b800193498103dc724f455b0), [`ffa09e7`](https://github.com/mastra-ai/mastra/commit/ffa09e772a5c92270eabe2090fc42d45bd8ec4b7), [`8c9f1c0`](https://github.com/mastra-ai/mastra/commit/8c9f1c0361d89066f9bcd14a2f69e761b01766c8), [`461a7c5`](https://github.com/mastra-ai/mastra/commit/461a7c501449295287f4f0ee4b0b42344f39fcf8), [`4211472`](https://github.com/mastra-ai/mastra/commit/4211472a5a2bd319c60cd2e42d9109c3eef7ac1c), [`9e45902`](https://github.com/mastra-ai/mastra/commit/9e4590208e745055cecca202e2db0e5c65e17d3c), [`5c0df77`](https://github.com/mastra-ai/mastra/commit/5c0df776c40efa420f8c07a2f3ee66010296618e), [`e940f09`](https://github.com/mastra-ai/mastra/commit/e940f099ef5d18b403e6f2b4937e086a4da857b1)]:
|
|
15
|
+
- @mastra/core@1.47.0
|
|
16
|
+
|
|
17
|
+
## 1.2.2-alpha.12
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- Updated dependencies [[`8a68844`](https://github.com/mastra-ai/mastra/commit/8a688443013816105a09f89c6afa34b5ff13e26d)]:
|
|
22
|
+
- @mastra/core@1.47.0-alpha.7
|
|
23
|
+
|
|
24
|
+
## 1.2.2-alpha.10
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- Updated dependencies [[`0200e75`](https://github.com/mastra-ai/mastra/commit/0200e7552d02d4221cd6040bf4eddf189a97a156), [`06e0d63`](https://github.com/mastra-ai/mastra/commit/06e0d63d42bc2a202e18bc091f3781f409f5e6fb), [`438a971`](https://github.com/mastra-ai/mastra/commit/438a9715c8b4398e5eaf8914a1f19dc8a85dc1de), [`77518cc`](https://github.com/mastra-ai/mastra/commit/77518ccb5bb8cc684875081e64213dc85cffdbee), [`bb2a13b`](https://github.com/mastra-ai/mastra/commit/bb2a13bb4b32e6bb807200fe7b18ae8fa4322118), [`a73cd1a`](https://github.com/mastra-ai/mastra/commit/a73cd1a62a5e4ca023dcc39ba150029f4f1f74c1), [`0b5cc47`](https://github.com/mastra-ai/mastra/commit/0b5cc4726dc18d9a685a27520db39ff1b36bb89a), [`87f38a3`](https://github.com/mastra-ai/mastra/commit/87f38a3de03e24731f2dd6f8ed6a60b6722b85a1), [`d5fa3cd`](https://github.com/mastra-ai/mastra/commit/d5fa3cda1788c3cb93a361a3c6ec47de6ba21e98), [`fe98ef2`](https://github.com/mastra-ai/mastra/commit/fe98ef2e66dbfcbd7d645c88c9ee1e67b458a136), [`793ea0f`](https://github.com/mastra-ai/mastra/commit/793ea0f52f831178837f21c83af6af93bf4ce638), [`507a5c4`](https://github.com/mastra-ai/mastra/commit/507a5c461bdc3136ad80744c0efbb55ce1f18f97), [`79b3626`](https://github.com/mastra-ai/mastra/commit/79b3626f8d647307eb07c8da14c9073c2699719d)]:
|
|
29
|
+
- @mastra/core@1.47.0-alpha.6
|
|
30
|
+
|
|
3
31
|
## 1.2.2-alpha.8
|
|
4
32
|
|
|
5
33
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/mcp-docs-server",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.3-alpha.1",
|
|
4
4
|
"description": "MCP server for accessing Mastra.ai documentation, changelogs, and news.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"jsdom": "^26.1.0",
|
|
29
29
|
"local-pkg": "^1.1.2",
|
|
30
30
|
"zod": "^4.4.3",
|
|
31
|
-
"@mastra/
|
|
32
|
-
"@mastra/
|
|
31
|
+
"@mastra/mcp": "^1.12.0",
|
|
32
|
+
"@mastra/core": "1.48.0-alpha.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@hono/node-server": "^1.19.11",
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
"tsx": "^4.22.4",
|
|
46
46
|
"typescript": "^6.0.3",
|
|
47
47
|
"vitest": "4.1.8",
|
|
48
|
-
"@internal/
|
|
49
|
-
"@internal/
|
|
50
|
-
"@mastra/core": "1.
|
|
48
|
+
"@internal/types-builder": "0.0.84",
|
|
49
|
+
"@internal/lint": "0.0.109",
|
|
50
|
+
"@mastra/core": "1.48.0-alpha.0"
|
|
51
51
|
},
|
|
52
52
|
"homepage": "https://mastra.ai",
|
|
53
53
|
"repository": {
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
# Harness overview
|
|
2
|
-
|
|
3
|
-
> **Beta:** The `Harness` feature is in beta stage and subject to breaking changes in minor versions until it graduates from its beta status.
|
|
4
|
-
|
|
5
|
-
The Harness is a session controller for building interactive agent applications. It handles the runtime concerns that sit between your UI and the agent loop: managing conversation threads, switching between agent modes, persisting state, gating tool execution with approvals, and coordinating subagents. You can focus on what your agent does rather than how to wire it together.
|
|
6
|
-
|
|
7
|
-
A Harness exposes a [`Session`](https://mastra.ai/docs/harness/session) — the per-conversation runtime state that tracks the active mode, model, thread binding, permission grants, follow-up queue, and token usage. The Harness is the shared host; the Session is the conversation running inside it. In a multi-user host, the same Harness can back many Sessions at once.
|
|
8
|
-
|
|
9
|
-
[Mastra Code](https://code.mastra.ai/) is the flagship Harness implementation: A terminal-based coding agent with multi-model support, persistent conversations, and plan-then-execute workflows.
|
|
10
|
-
|
|
11
|
-
## What you can build
|
|
12
|
-
|
|
13
|
-
The Harness gives you the runtime pieces to ship interactive agent applications. Each outcome below maps to a capability you can use today:
|
|
14
|
-
|
|
15
|
-
- **Resume a conversation exactly where the user left off.** Persistent [threads and state](https://mastra.ai/docs/harness/threads-and-state) reload the active mode, model, and progress across restarts, so a coding agent or assistant picks up mid-task instead of starting over.
|
|
16
|
-
- **Gate destructive actions behind human approval.** [Tool approvals and permission policies](https://mastra.ai/docs/harness/tool-approvals) let you require confirmation for risky operations like file writes or deployments, while trusted tools run automatically.
|
|
17
|
-
- **Move a task through distinct phases without losing context.** [Modes](https://mastra.ai/docs/harness/modes) switch the agent's instructions, tools, and model on the same thread, so you can build a plan-then-execute coding agent or a research-then-draft assistant.
|
|
18
|
-
- **Let users pick the right model for each step.** Per-mode [model management](https://mastra.ai/reference/harness/harness-class) switches models at runtime and tracks usage, which powers copilot UIs where users trade speed for capability.
|
|
19
|
-
- **Delegate focused work to child agents.** [Subagents](https://mastra.ai/docs/harness/subagents) run subtasks with constrained tools and can fork the parent conversation, so a research mode can spin off web search or code review without polluting the main thread.
|
|
20
|
-
- **Drive a live UI from agent activity.** The [event system](https://mastra.ai/docs/harness/session) emits typed events and coalesced display snapshots, so your TUI or web app reflects message updates, mode changes, and pending approvals in real time.
|
|
21
|
-
- **Run long-lived autonomous agents.** Structured task lists, heartbeat handlers, and observational memory keep background task runners on track and let them learn across threads.
|
|
22
|
-
|
|
23
|
-
## When to use the Harness
|
|
24
|
-
|
|
25
|
-
Use the Harness when your application needs:
|
|
26
|
-
|
|
27
|
-
- Multiple agent modes that share one conversation thread (e.g., plan → build → review)
|
|
28
|
-
- A control layer between your UI and the agent loop (model switching, state persistence, thread management)
|
|
29
|
-
- Tool approval flows and permission policies for human-in-the-loop gating
|
|
30
|
-
- Subagent orchestration to delegate focused subtasks with constrained tools
|
|
31
|
-
- Session continuity with persistent threads, state, and observational memory across restarts
|
|
32
|
-
|
|
33
|
-
You could assemble all of this yourself on top of the [Agent class](https://mastra.ai/docs/agents/overview), which exposes the full agent loop, tools, and memory. The Harness is an opinionated set of defaults that wires those pieces into one application style: an ongoing session where the agent acts as a collaborator rather than a one-shot endpoint. Reach for the Agent class directly when you want full control or a simple request-response call; reach for the Harness when you want the collaborative-session model without building the runtime around it.
|
|
34
|
-
|
|
35
|
-
## Key capabilities
|
|
36
|
-
|
|
37
|
-
- **Session**: Per-conversation state — active thread, mode, model, grants, follow-ups, token usage, and the display snapshot — accessed through `harness.session`. See [Session](https://mastra.ai/docs/harness/session).
|
|
38
|
-
- **Modes**: Define distinct agent personalities (instructions, tools, model) and switch between them without losing conversation context. See [Modes](https://mastra.ai/docs/harness/modes).
|
|
39
|
-
- **Threads and state**: Persist conversations and structured state across sessions, users, and mode switches. See [Threads and state](https://mastra.ai/docs/harness/threads-and-state).
|
|
40
|
-
- **Subagents**: Spawn focused child agents with constrained tools for subtasks, optionally forking the parent conversation. See [Subagents](https://mastra.ai/docs/harness/subagents).
|
|
41
|
-
- **Tool approvals and permissions**: Configure which tools require user confirmation, grant session-wide exceptions, and handle interactive tool suspension. See [Tool approvals](https://mastra.ai/docs/harness/tool-approvals).
|
|
42
|
-
- **Model management**: Switch models per-mode at runtime, track usage, and resolve gateway-backed models through Mastra's [model router](https://mastra.ai/models).
|
|
43
|
-
- **Follow-ups and steering**: Queue messages while the agent is running, or inject mid-stream instructions to redirect the agent. Built on [signals](https://mastra.ai/docs/agents/signals).
|
|
44
|
-
- **Event system**: Subscribe to typed events (message updates, mode changes, tool approvals) or coalesced `HarnessDisplayState` snapshots to drive your UI. See [Events](https://mastra.ai/reference/harness/harness-class).
|
|
45
|
-
- **Observational memory**: Automatic summarization and reflection across threads for long-running agent sessions. See [Observational memory](https://mastra.ai/docs/memory/observational-memory).
|
|
46
|
-
|
|
47
|
-
## Quickstart
|
|
48
|
-
|
|
49
|
-
Import the `Harness` class and create a new instance with an agent, storage backend, and modes:
|
|
50
|
-
|
|
51
|
-
```typescript
|
|
52
|
-
import { Agent } from '@mastra/core/agent'
|
|
53
|
-
import { Harness } from '@mastra/core/harness'
|
|
54
|
-
import { LibSQLStore } from '@mastra/libsql'
|
|
55
|
-
|
|
56
|
-
const agent = new Agent({
|
|
57
|
-
name: 'assistant',
|
|
58
|
-
instructions: 'Help the user plan and complete tasks.',
|
|
59
|
-
model: 'openai/gpt-5.5',
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
const harness = new Harness({
|
|
63
|
-
id: 'my-agent',
|
|
64
|
-
agent,
|
|
65
|
-
storage: new LibSQLStore({ url: 'file:./data.db' }),
|
|
66
|
-
modes: [
|
|
67
|
-
{
|
|
68
|
-
id: 'plan',
|
|
69
|
-
name: 'Plan',
|
|
70
|
-
metadata: { default: true },
|
|
71
|
-
instructions: 'Reason about changes before making them.',
|
|
72
|
-
},
|
|
73
|
-
{ id: 'build', name: 'Build', instructions: 'Implement the approved plan.' },
|
|
74
|
-
],
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
harness.subscribe(event => {
|
|
78
|
-
if (event.type === 'message_update') {
|
|
79
|
-
console.log(event.message)
|
|
80
|
-
}
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
await harness.init()
|
|
84
|
-
await harness.selectOrCreateThread()
|
|
85
|
-
await harness.sendMessage({ content: 'Hello!' })
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
> **Note:** Visit the [Harness reference](https://mastra.ai/reference/harness/harness-class) for the full constructor parameters and method signatures.
|
|
89
|
-
|
|
90
|
-
## Architecture
|
|
91
|
-
|
|
92
|
-
The Harness sits between your application layer and the underlying agent loop:
|
|
93
|
-
|
|
94
|
-
```text
|
|
95
|
-
┌───────────────────────────────────────┐
|
|
96
|
-
│ Your App (TUI/Web/API) │
|
|
97
|
-
└───────────────────────────────────────┘
|
|
98
|
-
│ commands ▲ events
|
|
99
|
-
▼ │
|
|
100
|
-
┌───────────────────────────────────────┐
|
|
101
|
-
│ Harness │
|
|
102
|
-
│ Config · storage · threads │
|
|
103
|
-
│ permissions · subagents · events │
|
|
104
|
-
│ │
|
|
105
|
-
│ ┌─────────────────────────────────┐ │
|
|
106
|
-
│ │ harness.session │ │
|
|
107
|
-
│ │ identity · thread · mode │ │
|
|
108
|
-
│ │ model · run · grants │ │
|
|
109
|
-
│ │ display state │ │
|
|
110
|
-
│ └─────────────────────────────────┘ │
|
|
111
|
-
└───────────────────────────────────────┘
|
|
112
|
-
│
|
|
113
|
-
▼
|
|
114
|
-
┌───────────────────────────────────────┐
|
|
115
|
-
│ Agent + Memory + Tools │
|
|
116
|
-
└───────────────────────────────────────┘
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
Your app sends commands — send a message, switch mode, approve a tool call — and receives typed events such as `message_update` and `tool_approval_required`. The Harness manages the lifecycle internally: persisting threads, routing to the correct mode agent, enforcing permissions, and emitting events as state changes.
|
|
120
|
-
|
|
121
|
-
## Next steps
|
|
122
|
-
|
|
123
|
-
- [Session](https://mastra.ai/docs/harness/session): The per-conversation state on a Harness
|
|
124
|
-
- [Modes](https://mastra.ai/docs/harness/modes): Define and switch between agent personalities
|
|
125
|
-
- [Threads and state](https://mastra.ai/docs/harness/threads-and-state): Manage persistent conversations
|
|
126
|
-
- [Subagents](https://mastra.ai/docs/harness/subagents): Delegate focused subtasks
|
|
127
|
-
- [Tool approvals and permissions](https://mastra.ai/docs/harness/tool-approvals): Human-in-the-loop gating
|
|
128
|
-
- [API reference](https://mastra.ai/reference/harness/harness-class): Full constructor and method docs
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
# Session
|
|
2
|
-
|
|
3
|
-
A [`Session`](https://mastra.ai/reference/harness/session) holds the live state of a Harness: who the session is for, which thread is active, the selected mode and model, permission grants, queued follow-ups, token usage, application state, and the display snapshot. You reach it through `harness.session`.
|
|
4
|
-
|
|
5
|
-
## What the Session tracks
|
|
6
|
-
|
|
7
|
-
The Session is the live state of a single user's interaction with the Harness. It answers "what is true right now": who the session belongs to, which thread is currently bound, which mode and model are selected, what the user has approved, what's queued or running, the application state, and the snapshot to render. A session has one active thread at a time but can list, switch between, and clone many threads over its lifetime. Anything that describes the current state lives here; the Harness owns the shared infrastructure every session runs on.
|
|
8
|
-
|
|
9
|
-
Because each session has its own identity and state, one Harness can serve many users at once — each backed by its own Session — without one session's mode, grants, or active thread leaking into another.
|
|
10
|
-
|
|
11
|
-
The rest of this page walks through the Session's state. Each part is a focused sub-object on `harness.session`:
|
|
12
|
-
|
|
13
|
-
- **Who and where**: [Identity](#identity) sets the stable session `id`, `ownerId`, and resource the session belongs to, and [Thread](#thread) tracks the currently bound thread.
|
|
14
|
-
- **How the agent behaves**: [Mode and model](#mode-and-model) controls which agent profile and model are active, and [Permission grants](#permission-grants) records what the user has approved to run without prompting.
|
|
15
|
-
- **What's happening right now**: [Run state](#run-state) reflects the in-flight generation, and [Follow-ups](#follow-ups) holds messages queued to send when it finishes.
|
|
16
|
-
- **What you store and render**: [State](#state) holds your application's structured data, and [Display state](#display-state) is the single snapshot your UI renders from.
|
|
17
|
-
|
|
18
|
-
The Harness performs actions that change this state — switching threads, modes, or models — because those operations coordinate shared infrastructure and emit events. The Session is where you read the result. The sections below note this split where it matters.
|
|
19
|
-
|
|
20
|
-
## Identity
|
|
21
|
-
|
|
22
|
-
`session.identity` holds three stable identifiers for the conversation: a session `id`, an `ownerId`, and the resource ID. Threads are scoped to a resource ID, so this is what groups a conversation's threads together:
|
|
23
|
-
|
|
24
|
-
```typescript
|
|
25
|
-
const sessionId = harness.session.identity.getId()
|
|
26
|
-
const ownerId = harness.session.identity.getOwnerId()
|
|
27
|
-
const resourceId = harness.session.identity.getResourceId()
|
|
28
|
-
const threadId = harness.session.thread.getId()
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
The session `id` and `ownerId` are stable for the life of the session — they don't change when the resource ID is switched. They mirror the `id` and `ownerId` fields on `SessionRecord` in storage, so storage layers can key sessions by a stable identifier rather than the mutable resource ID.
|
|
32
|
-
|
|
33
|
-
The resource ID is set when creating a session via [`harness.createSession()`](https://mastra.ai/reference/harness/harness-class) and defaults to the harness `id`. See [Resource IDs](https://mastra.ai/docs/harness/threads-and-state) for how it scopes threads.
|
|
34
|
-
|
|
35
|
-
## Thread
|
|
36
|
-
|
|
37
|
-
`session.thread` owns the active thread binding and read access to threads and messages. The Harness performs lifecycle transitions; the Session reads the result:
|
|
38
|
-
|
|
39
|
-
```typescript
|
|
40
|
-
// Lifecycle transitions live on the Harness
|
|
41
|
-
await harness.switchThread({ threadId: 'thread-abc123' })
|
|
42
|
-
|
|
43
|
-
// Reads live on the Session
|
|
44
|
-
const threads = await harness.session.thread.list()
|
|
45
|
-
const messages = await harness.session.thread.listActiveMessages()
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
See [Threads and state](https://mastra.ai/docs/harness/threads-and-state) for the full lifecycle.
|
|
49
|
-
|
|
50
|
-
## Mode and model
|
|
51
|
-
|
|
52
|
-
The Harness defines the available modes in `config.modes`. The Session tracks which mode and model are _currently_ selected:
|
|
53
|
-
|
|
54
|
-
```typescript
|
|
55
|
-
// Switch mode (aborts the run, emits events)
|
|
56
|
-
await harness.session.mode.switch({ modeId: 'build' })
|
|
57
|
-
|
|
58
|
-
// Read the current selection (Session state)
|
|
59
|
-
const modeId = harness.session.mode.get()
|
|
60
|
-
const mode = harness.session.mode.resolve()
|
|
61
|
-
const modelId = harness.session.model.get()
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
See [Modes](https://mastra.ai/docs/harness/modes) for how modes carry their own model.
|
|
65
|
-
|
|
66
|
-
## Permission grants
|
|
67
|
-
|
|
68
|
-
The Harness owns permission _policy_ — which categories or tools require approval. The Session owns the _grants_ a user makes during the conversation. A grant lets a tool run for the rest of the session without prompting again:
|
|
69
|
-
|
|
70
|
-
```typescript
|
|
71
|
-
// Grant a category or tool for the rest of the session
|
|
72
|
-
harness.session.grantCategory('edit')
|
|
73
|
-
harness.session.grantTool('mastra_workspace_execute_command')
|
|
74
|
-
|
|
75
|
-
// Inspect current grants
|
|
76
|
-
const grants = harness.session.getGrants()
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
Grants are intentionally in-memory and reset when the session restarts. See [Tool approvals](https://mastra.ai/docs/harness/tool-approvals) for the approval flow.
|
|
80
|
-
|
|
81
|
-
## Run state
|
|
82
|
-
|
|
83
|
-
`session.run` tracks the in-flight generation: whether a run is active, its run and trace IDs, and the abort signal. Use it to reflect run status in your UI:
|
|
84
|
-
|
|
85
|
-
```typescript
|
|
86
|
-
if (harness.session.run.isRunning()) {
|
|
87
|
-
// show a stop button
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Abort the active run (Harness orchestration clears related state)
|
|
91
|
-
harness.abort()
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
## Follow-ups
|
|
95
|
-
|
|
96
|
-
A user may want to add to the conversation while the agent is still working. Instead of dropping or interrupting those messages, the Session queues them on `session.followUps` and sends them when the current run finishes:
|
|
97
|
-
|
|
98
|
-
```typescript
|
|
99
|
-
const queued = harness.session.followUps.count()
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
Queue a follow-up with `harness.followUp({ content })`. To redirect the agent mid-run instead of waiting, use `harness.steer({ content })`. Both build on [signals](https://mastra.ai/docs/agents/signals).
|
|
103
|
-
|
|
104
|
-
## State
|
|
105
|
-
|
|
106
|
-
`session.state` holds the conversation's application state — structured values that agents and the UI share, such as model preferences, feature flags, or progress. The Harness defines the shape with a `stateSchema`; the Session owns the live snapshot, validates updates against the schema, and emits `state_changed` on every write:
|
|
107
|
-
|
|
108
|
-
```typescript
|
|
109
|
-
const state = harness.session.state.get()
|
|
110
|
-
await harness.session.state.set({ theme: 'light' })
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
See [Threads and state](https://mastra.ai/docs/harness/threads-and-state) for defining a schema.
|
|
114
|
-
|
|
115
|
-
## Display state
|
|
116
|
-
|
|
117
|
-
A conversation emits many fine-grained events: tokens streaming in, tools starting and finishing, approvals pending, tasks updating, token usage climbing. Subscribing to each event type and reassembling the current picture yourself is tedious and error-prone. `session.displayState` does that work for you.
|
|
118
|
-
|
|
119
|
-
It's a reducer-maintained snapshot. The Session keeps one `HarnessDisplayState` object and folds every harness event into it as it happens, so the snapshot always reflects the latest state. It captures everything a UI needs to render: whether the agent is running and what it's streaming, which tools and subagents are active, anything waiting on the user such as approvals, the current task list, and running totals like token usage and queued follow-ups.
|
|
120
|
-
|
|
121
|
-
Because it's a single object, you can drive an entire UI from one place: read the current snapshot with `get()`, and re-render whenever the Harness emits `display_state_changed` (fired after every other event):
|
|
122
|
-
|
|
123
|
-
```typescript
|
|
124
|
-
const snapshot = harness.session.displayState.get()
|
|
125
|
-
|
|
126
|
-
// Re-render from the snapshot on every change
|
|
127
|
-
harness.subscribe(event => {
|
|
128
|
-
if (event.type === 'display_state_changed') {
|
|
129
|
-
render(harness.session.displayState.get())
|
|
130
|
-
}
|
|
131
|
-
})
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
This is the recommended pattern for most UIs. Subscribe to individual typed events only when you need to react to a specific transition rather than re-render the whole view.
|
|
135
|
-
|
|
136
|
-
> **Note:** Visit the [Session reference](https://mastra.ai/reference/harness/session) for the full list of sub-objects and method signatures.
|
|
137
|
-
|
|
138
|
-
## Related
|
|
139
|
-
|
|
140
|
-
- [Harness overview](https://mastra.ai/docs/harness/overview)
|
|
141
|
-
- [Threads and state](https://mastra.ai/docs/harness/threads-and-state)
|
|
142
|
-
- [Tool approvals](https://mastra.ai/docs/harness/tool-approvals)
|
|
143
|
-
- [Session reference](https://mastra.ai/reference/harness/session)
|