@mastra/mcp-docs-server 1.2.7 → 1.2.8-alpha.17
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/agent-builder/deploying.md +1 -0
- package/.docs/docs/agent-builder/integrations.md +1 -3
- package/.docs/docs/agent-builder/overview.md +1 -1
- package/.docs/docs/agent-controller/overview.md +1 -1
- package/.docs/docs/agents/overview.md +17 -13
- package/.docs/docs/agents/skills.md +1 -3
- package/.docs/docs/agents/structured-output.md +14 -7
- package/.docs/docs/agents/using-tools.md +80 -26
- package/.docs/docs/browser/agent-browser.md +1 -0
- package/.docs/docs/browser/firecrawl.md +129 -0
- package/.docs/docs/browser/overview.md +16 -2
- package/.docs/docs/capabilities/channels/other-adapters.md +1 -1
- package/.docs/docs/capabilities/channels/overview.md +1 -0
- package/.docs/docs/capabilities/channels/slack.md +113 -3
- package/.docs/docs/deployment/mastra-server.md +35 -0
- package/.docs/docs/deployment/monorepo.md +2 -0
- package/.docs/docs/deployment/overview.md +6 -0
- package/.docs/docs/deployment/sandbox.md +277 -0
- package/.docs/docs/editor/overview.md +2 -6
- package/.docs/docs/editor/tools.md +2 -6
- package/.docs/docs/evals/multi-turn.md +178 -0
- package/.docs/docs/evals/overview.md +1 -0
- package/.docs/docs/evals/running-in-ci.md +3 -9
- package/.docs/docs/getting-started/file-based-agents.md +2 -2
- package/.docs/docs/index.md +17 -13
- package/.docs/docs/long-running-agents/background-tasks.md +2 -2
- package/.docs/docs/long-running-agents/durable-agents.md +2 -1
- package/.docs/docs/long-running-agents/schedules.md +2 -2
- package/.docs/docs/mastra-platform/database.md +13 -6
- package/.docs/docs/mastra-platform/deploy.md +17 -8
- package/.docs/docs/mastra-platform/environments.md +5 -4
- package/.docs/docs/mastra-platform/regions.md +73 -0
- package/.docs/docs/mcp/overview.md +1 -1
- package/.docs/docs/memory/multi-user-threads.md +4 -4
- package/.docs/docs/memory/observational-memory.md +78 -3
- package/.docs/docs/memory/overview.md +4 -0
- package/.docs/docs/memory/working-memory.md +1 -1
- package/.docs/docs/observability/integrations/bridges/otel.md +1 -3
- package/.docs/docs/observability/integrations/exporters/braintrust.md +34 -2
- package/.docs/docs/observability/integrations/exporters/otel.md +1 -3
- package/.docs/docs/server/auth/simple-auth.md +1 -3
- package/.docs/docs/server/request-context.md +2 -0
- package/.docs/docs/studio/overview.md +2 -0
- package/.docs/docs/voice/livekit.md +1 -1
- package/.docs/docs/workflows/control-flow.md +1 -3
- package/.docs/guides/build-your-ui/ai-sdk-ui.md +1 -0
- package/.docs/guides/guide/signal-provider.md +2 -0
- package/.docs/guides/migrations/vnext-to-standard-apis.md +1 -3
- package/.docs/models/environment-variables.md +1 -0
- package/.docs/models/gateways/openrouter.md +339 -345
- package/.docs/models/gateways/vercel.md +6 -5
- package/.docs/models/index.md +1 -1
- package/.docs/models/providers/ambient.md +12 -10
- package/.docs/models/providers/baseten.md +3 -2
- package/.docs/models/providers/crossmodel.md +2 -1
- package/.docs/models/providers/deepinfra.md +4 -7
- package/.docs/models/providers/empiriolabs.md +2 -1
- package/.docs/models/providers/evroc.md +3 -2
- package/.docs/models/providers/google.md +2 -2
- package/.docs/models/providers/kilo.md +1 -1
- package/.docs/models/providers/kimi-for-coding.md +10 -11
- package/.docs/models/providers/llmgateway.md +3 -8
- package/.docs/models/providers/moonshotai-cn.md +3 -2
- package/.docs/models/providers/moonshotai.md +3 -2
- package/.docs/models/providers/nebius.md +3 -1
- package/.docs/models/providers/ollama-cloud.md +25 -42
- package/.docs/models/providers/opencode-go.md +5 -3
- package/.docs/models/providers/orcarouter.md +1 -1
- package/.docs/models/providers/privatemode-ai.md +10 -10
- package/.docs/models/providers/thinkingmachines.md +73 -0
- package/.docs/models/providers/togetherai.md +2 -6
- package/.docs/models/providers/zenmux.md +2 -1
- package/.docs/models/providers.md +1 -0
- package/.docs/reference/acp/acp-agent.md +2 -0
- package/.docs/reference/acp/create-acp-tool.md +28 -0
- package/.docs/reference/agent-controller/agent-controller-class.md +1 -1
- package/.docs/reference/agent-controller/session.md +15 -0
- package/.docs/reference/agents/agent.md +14 -2
- package/.docs/reference/agents/durable-agent.md +23 -0
- package/.docs/reference/agents/generate.md +19 -1
- package/.docs/reference/browser/firecrawl-browser.md +71 -0
- package/.docs/reference/cli/mastra.md +14 -6
- package/.docs/reference/code-sdk/mount-agent-controller.md +1 -3
- package/.docs/reference/core/getMCPServer.md +1 -3
- package/.docs/reference/core/getMCPServerById.md +1 -3
- package/.docs/reference/core/getTool.md +33 -0
- package/.docs/reference/core/getToolById.md +48 -0
- package/.docs/reference/core/getWorkflow.md +1 -3
- package/.docs/reference/core/listMCPServers.md +2 -6
- package/.docs/reference/core/listTools.md +38 -0
- package/.docs/reference/core/mastra-class.md +1 -1
- package/.docs/reference/datasets/addItem.md +1 -3
- package/.docs/reference/datasets/addItems.md +1 -3
- package/.docs/reference/datasets/compareExperiments.md +1 -3
- package/.docs/reference/datasets/create.md +1 -3
- package/.docs/reference/datasets/dataset.md +2 -6
- package/.docs/reference/datasets/datasets-manager.md +5 -15
- package/.docs/reference/datasets/delete.md +1 -3
- package/.docs/reference/datasets/deleteExperiment.md +1 -3
- package/.docs/reference/datasets/deleteItem.md +1 -3
- package/.docs/reference/datasets/deleteItems.md +1 -3
- package/.docs/reference/datasets/get.md +1 -3
- package/.docs/reference/datasets/getDetails.md +1 -3
- package/.docs/reference/datasets/getExperiment.md +1 -3
- package/.docs/reference/datasets/getItem.md +1 -3
- package/.docs/reference/datasets/getItemHistory.md +1 -3
- package/.docs/reference/datasets/list.md +1 -3
- package/.docs/reference/datasets/listExperimentResults.md +1 -3
- package/.docs/reference/datasets/listExperiments.md +1 -3
- package/.docs/reference/datasets/listItems.md +1 -3
- package/.docs/reference/datasets/listVersions.md +1 -3
- package/.docs/reference/datasets/startExperiment.md +1 -3
- package/.docs/reference/datasets/startExperimentAsync.md +1 -3
- package/.docs/reference/datasets/update.md +1 -3
- package/.docs/reference/datasets/updateItem.md +1 -3
- package/.docs/reference/editor/mastra-editor.md +1 -3
- package/.docs/reference/evals/create-scorer.md +4 -10
- package/.docs/reference/evals/mastra-scorer.md +1 -3
- package/.docs/reference/evals/run-evals.md +94 -2
- package/.docs/reference/file-based-agents/logger.md +1 -1
- package/.docs/reference/file-based-agents/tools.md +7 -6
- package/.docs/reference/index.md +5 -0
- package/.docs/reference/memory/observational-memory.md +21 -0
- package/.docs/reference/observability/tracing/processors/sensitive-data-filter.md +1 -3
- package/.docs/reference/processors/token-limiter-processor.md +1 -3
- package/.docs/reference/rag/database-config.md +12 -0
- package/.docs/reference/storage/clickhouse.md +1 -1
- package/.docs/reference/storage/convex.md +17 -10
- package/.docs/reference/storage/retention.md +1 -1
- package/.docs/reference/streaming/agents/stream.md +3 -1
- package/.docs/reference/tools/create-tool.md +78 -52
- package/.docs/reference/tools/mcp-client.md +104 -24
- package/.docs/reference/tools/mcp-server.md +143 -44
- package/.docs/reference/tools/task-tools.md +2 -2
- package/.docs/reference/tools/tavily.md +1 -1
- package/.docs/reference/tools/vector-query-tool.md +22 -0
- package/.docs/reference/vectors/mongodb.md +2 -0
- package/.docs/reference/vectors/turbopuffer.md +4 -0
- package/.docs/reference/voice/mistral.md +127 -0
- package/.docs/reference/workspace/daytona-sandbox.md +2 -6
- package/CHANGELOG.md +64 -0
- package/dist/{chunk-GLPCVXXO.js → chunk-HGADBLKG.js} +2 -2
- package/dist/{chunk-GLPCVXXO.js.map → chunk-HGADBLKG.js.map} +1 -1
- package/dist/index.js +1 -1
- package/dist/stdio.js +1 -1
- package/dist/tools/docs.d.ts.map +1 -1
- package/package.json +7 -7
package/.docs/reference/index.md
CHANGED
|
@@ -57,6 +57,7 @@ The Reference section provides documentation of Mastra's API, including paramete
|
|
|
57
57
|
- [WorkOS](https://mastra.ai/reference/auth/workos)
|
|
58
58
|
- [AgentBrowser](https://mastra.ai/reference/browser/agent-browser)
|
|
59
59
|
- [BrowserViewer](https://mastra.ai/reference/browser/browser-viewer)
|
|
60
|
+
- [FirecrawlBrowser](https://mastra.ai/reference/browser/firecrawl-browser)
|
|
60
61
|
- [MastraBrowser Class](https://mastra.ai/reference/browser/mastra-browser)
|
|
61
62
|
- [StagehandBrowser](https://mastra.ai/reference/browser/stagehand-browser)
|
|
62
63
|
- [ChannelProvider](https://mastra.ai/reference/channels/channel-provider)
|
|
@@ -97,6 +98,8 @@ The Reference section provides documentation of Mastra's API, including paramete
|
|
|
97
98
|
- [.getServer()](https://mastra.ai/reference/core/getServer)
|
|
98
99
|
- [.getStorage()](https://mastra.ai/reference/core/getStorage)
|
|
99
100
|
- [.getTelemetry()](https://mastra.ai/reference/core/getTelemetry)
|
|
101
|
+
- [.getTool()](https://mastra.ai/reference/core/getTool)
|
|
102
|
+
- [.getToolById()](https://mastra.ai/reference/core/getToolById)
|
|
100
103
|
- [.getVector()](https://mastra.ai/reference/core/getVector)
|
|
101
104
|
- [.getWorkflow()](https://mastra.ai/reference/core/getWorkflow)
|
|
102
105
|
- [.listAgents()](https://mastra.ai/reference/core/listAgents)
|
|
@@ -106,6 +109,7 @@ The Reference section provides documentation of Mastra's API, including paramete
|
|
|
106
109
|
- [.listMCPServers()](https://mastra.ai/reference/core/listMCPServers)
|
|
107
110
|
- [.listMemory()](https://mastra.ai/reference/core/listMemory)
|
|
108
111
|
- [.listScorers()](https://mastra.ai/reference/core/listScorers)
|
|
112
|
+
- [.listTools()](https://mastra.ai/reference/core/listTools)
|
|
109
113
|
- [.listVectors()](https://mastra.ai/reference/core/listVectors)
|
|
110
114
|
- [.listWorkflows()](https://mastra.ai/reference/core/listWorkflows)
|
|
111
115
|
- [.removeWorkspace()](https://mastra.ai/reference/core/removeWorkspace)
|
|
@@ -333,6 +337,7 @@ The Reference section provides documentation of Mastra's API, including paramete
|
|
|
333
337
|
- [Inworld Realtime](https://mastra.ai/reference/voice/inworld-realtime)
|
|
334
338
|
- [LiveKit](https://mastra.ai/reference/voice/livekit)
|
|
335
339
|
- [Mastra Voice](https://mastra.ai/reference/voice/mastra-voice)
|
|
340
|
+
- [Mistral](https://mastra.ai/reference/voice/mistral)
|
|
336
341
|
- [Murf](https://mastra.ai/reference/voice/murf)
|
|
337
342
|
- [OpenAI](https://mastra.ai/reference/voice/openai)
|
|
338
343
|
- [OpenAI Realtime](https://mastra.ai/reference/voice/openai-realtime)
|
|
@@ -408,6 +408,27 @@ Setting `bufferTokens: false` disables both observation and reflection async buf
|
|
|
408
408
|
|
|
409
409
|
Observational Memory emits typed data parts during agent execution that clients can use for real-time UI feedback. These are streamed alongside the agent's response.
|
|
410
410
|
|
|
411
|
+
### Read extractor results
|
|
412
|
+
|
|
413
|
+
Both completion events carry extractor output in their `data` payload. The extractor fields are:
|
|
414
|
+
|
|
415
|
+
```typescript
|
|
416
|
+
interface DataOmObservationEndPart {
|
|
417
|
+
type: 'data-om-observation-end'
|
|
418
|
+
data: {
|
|
419
|
+
/** Whether the completed work was an observation or reflection */
|
|
420
|
+
operationType: 'observation' | 'reflection'
|
|
421
|
+
/** Values extracted during this OM operation, keyed by extractor slug */
|
|
422
|
+
extractedValues?: Record<string, unknown>
|
|
423
|
+
/** Extractor failures from this OM operation. Successful extractor values are still included */
|
|
424
|
+
extractionFailures?: Array<{ slug: string; error: string }>
|
|
425
|
+
// ...other fields documented in the tables below
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
Both extractor fields are optional. A completion can include values, failures, both, or neither. `data-om-observation-end` reports synchronous completion. `data-om-buffering-end` reports completed background work whose buffered content still awaits activation, although extractor metadata is already persisted. `DataOmBufferingEndPart` carries the same extractor fields, and both types are exported from `@mastra/memory/processors`. See [Read extracted values from a stream](https://mastra.ai/docs/memory/observational-memory) for a consumer example.
|
|
431
|
+
|
|
411
432
|
### `data-om-status`
|
|
412
433
|
|
|
413
434
|
Emitted once per agent loop step, before model generation. Provides a snapshot of the current memory state, including token usage for both context windows and the state of any async buffered content.
|
|
@@ -14,9 +14,7 @@ To opt out or customize the auto-applied filter, use the `sensitiveDataFilter` o
|
|
|
14
14
|
import { Observability } from '@mastra/observability'
|
|
15
15
|
|
|
16
16
|
new Observability({
|
|
17
|
-
configs: {
|
|
18
|
-
/* ... */
|
|
19
|
-
},
|
|
17
|
+
configs: {/* ... */},
|
|
20
18
|
// disable the auto-applied filter
|
|
21
19
|
sensitiveDataFilter: false,
|
|
22
20
|
// or customize it
|
|
@@ -85,9 +85,7 @@ export const agent = new Agent({
|
|
|
85
85
|
name: 'context-limited-agent',
|
|
86
86
|
instructions: 'You are a helpful assistant',
|
|
87
87
|
model: 'openai/gpt-5.5',
|
|
88
|
-
memory: new Memory({
|
|
89
|
-
/* ... */
|
|
90
|
-
}),
|
|
88
|
+
memory: new Memory({/* ... */}),
|
|
91
89
|
inputProcessors: [
|
|
92
90
|
new TokenLimiterProcessor({ limit: 4000 }), // Limits historical messages to ~4000 tokens
|
|
93
91
|
],
|
|
@@ -11,6 +11,7 @@ export type DatabaseConfig = {
|
|
|
11
11
|
pinecone?: PineconeConfig
|
|
12
12
|
pgvector?: PgVectorConfig
|
|
13
13
|
chroma?: ChromaConfig
|
|
14
|
+
turbopuffer?: TurbopufferConfig
|
|
14
15
|
[key: string]: any // Extensible for future databases
|
|
15
16
|
}
|
|
16
17
|
```
|
|
@@ -90,6 +91,17 @@ whereDocument: { "$contains": "API documentation" }
|
|
|
90
91
|
- Content-based document filtering
|
|
91
92
|
- Complex query combinations
|
|
92
93
|
|
|
94
|
+
### `TurbopufferConfig`
|
|
95
|
+
|
|
96
|
+
Configuration options specific to Turbopuffer vector store.
|
|
97
|
+
|
|
98
|
+
**consistency** (`'strong' | 'eventual'`): The consistency level for queries. "strong" (default) guarantees queries see all data written before the query started, at the cost of higher latency. "eventual" offers lower latency, but recently written data may not be visible yet.
|
|
99
|
+
|
|
100
|
+
**Use Cases:**
|
|
101
|
+
|
|
102
|
+
- Latency-sensitive queries where slightly stale data is acceptable (`eventual`)
|
|
103
|
+
- Read-your-writes workflows that must see the latest data (`strong`)
|
|
104
|
+
|
|
93
105
|
## Usage examples
|
|
94
106
|
|
|
95
107
|
**Basic Usage**:
|
|
@@ -131,7 +131,7 @@ bun x mastra migrate
|
|
|
131
131
|
|
|
132
132
|
The migration copies span data from `mastra_ai_spans` into `mastra_span_events` in day-sized batches. It handles column mapping, deduplicates legacy rows, and preserves the original table as a backup. After migration, traces appear in Studio through the vNext adapter.
|
|
133
133
|
|
|
134
|
-
> **Note:** The legacy table
|
|
134
|
+
> **Note:** The legacy table isn't deleted. Drop it manually after verifying the migration.
|
|
135
135
|
|
|
136
136
|
### ClickHouse for every domain
|
|
137
137
|
|
|
@@ -50,6 +50,7 @@ import {
|
|
|
50
50
|
mastraResourcesTable,
|
|
51
51
|
mastraWorkflowSnapshotsTable,
|
|
52
52
|
mastraScoresTable,
|
|
53
|
+
mastraObservationalMemoryTable,
|
|
53
54
|
mastraVectorIndexesTable,
|
|
54
55
|
mastraVectorsTable,
|
|
55
56
|
mastraCacheTable,
|
|
@@ -63,6 +64,7 @@ export default defineSchema({
|
|
|
63
64
|
mastra_resources: mastraResourcesTable,
|
|
64
65
|
mastra_workflow_snapshots: mastraWorkflowSnapshotsTable,
|
|
65
66
|
mastra_scorers: mastraScoresTable,
|
|
67
|
+
mastra_observational_memory: mastraObservationalMemoryTable,
|
|
66
68
|
mastra_vector_indexes: mastraVectorIndexesTable,
|
|
67
69
|
mastra_vectors: mastraVectorsTable,
|
|
68
70
|
mastra_cache: mastraCacheTable,
|
|
@@ -192,16 +194,21 @@ Use a non-empty `keyPrefix` unless you intentionally want `clear()` to remove ev
|
|
|
192
194
|
|
|
193
195
|
The storage implementation uses typed Convex tables for each Mastra domain:
|
|
194
196
|
|
|
195
|
-
| Domain
|
|
196
|
-
|
|
|
197
|
-
| Threads
|
|
198
|
-
| Messages
|
|
199
|
-
| Resources
|
|
200
|
-
|
|
|
201
|
-
|
|
|
202
|
-
|
|
|
203
|
-
| Cache
|
|
204
|
-
|
|
|
197
|
+
| Domain | Convex Table | Purpose |
|
|
198
|
+
| -------------------- | ----------------------------- | ----------------------------------------- |
|
|
199
|
+
| Threads | `mastra_threads` | Conversation threads |
|
|
200
|
+
| Messages | `mastra_messages` | Chat messages |
|
|
201
|
+
| Resources | `mastra_resources` | User working memory |
|
|
202
|
+
| Observational Memory | `mastra_observational_memory` | Observational memory generations |
|
|
203
|
+
| Workflows | `mastra_workflow_snapshots` | Workflow state |
|
|
204
|
+
| Scorers | `mastra_scorers` | Evaluation data |
|
|
205
|
+
| Cache | `mastra_cache` | Cache values, counters, and list metadata |
|
|
206
|
+
| Cache Items | `mastra_cache_list_items` | Cache list entries |
|
|
207
|
+
| Fallback | `mastra_documents` | Unknown tables |
|
|
208
|
+
|
|
209
|
+
### Observational memory
|
|
210
|
+
|
|
211
|
+
`ConvexStore` supports [observational memory](https://mastra.ai/docs/memory/observational-memory). Add `mastraObservationalMemoryTable` to your Convex schema and redeploy with `npx convex deploy` to enable it. Existing deployments created before this table was added need the same schema update.
|
|
205
212
|
|
|
206
213
|
### Architecture
|
|
207
214
|
|
|
@@ -228,7 +228,7 @@ const storage = new MongoDBStore({
|
|
|
228
228
|
})
|
|
229
229
|
```
|
|
230
230
|
|
|
231
|
-
> **Tip:** TTL indexes delete documents shortly after they expire (background thread runs every \~60 seconds), but the exact timing
|
|
231
|
+
> **Tip:** TTL indexes delete documents shortly after they expire (background thread runs every \~60 seconds), but the exact timing isn't guaranteed. For precise, immediate cleanup, use `prune()` instead.
|
|
232
232
|
|
|
233
233
|
## Reclaiming disk
|
|
234
234
|
|
|
@@ -100,7 +100,7 @@ const stream = await agent.stream('message for agent')
|
|
|
100
100
|
|
|
101
101
|
**options.structuredOutput.instructions** (`string`): Additional instructions for the structured output model.
|
|
102
102
|
|
|
103
|
-
**options.structuredOutput.jsonPromptInjection** (`boolean`):
|
|
103
|
+
**options.structuredOutput.jsonPromptInjection** (`boolean | 'system' | 'inline' | 'auto'`): Controls how the JSON schema reaches the model. Set to 'auto' to use native structured output when supported and inline prompt injection otherwise.
|
|
104
104
|
|
|
105
105
|
**options.structuredOutput.providerOptions** (`ProviderOptions`): Provider-specific options passed to the internal structuring agent. Use this to control model behavior like reasoning effort for thinking models (e.g., { openai: { reasoningEffort: 'low' } }).
|
|
106
106
|
|
|
@@ -124,6 +124,8 @@ const stream = await agent.stream('message for agent')
|
|
|
124
124
|
|
|
125
125
|
**options.memory.options** (`MemoryConfig`): Configuration for memory behavior including lastMessages, readOnly, semanticRecall, workingMemory, and filterIncompleteToolCalls.
|
|
126
126
|
|
|
127
|
+
**options.memory.onTitleGenerated** (`(title: string) => void | Promise<void>`): Callback fired asynchronously when a thread title is generated and persisted to storage. Title generation runs in the background and may complete after the stream ends. Only fires when generateTitle is enabled in memory options and the thread has no existing title.
|
|
128
|
+
|
|
127
129
|
**options.onFinish** (`StreamTextOnFinishCallback<any> | StreamObjectOnFinishCallback<OUTPUT>`): Callback function called when streaming completes. Receives the final result.
|
|
128
130
|
|
|
129
131
|
**options.onStepFinish** (`StreamTextOnStepFinishCallback<any> | never`): Callback function called after each execution step. Receives step details as a JSON string. Unavailable for structured output
|
|
@@ -10,25 +10,29 @@ The `createTool()` function is used to define custom tools that your Mastra agen
|
|
|
10
10
|
import { createTool } from '@mastra/core/tools'
|
|
11
11
|
import { z } from 'zod'
|
|
12
12
|
|
|
13
|
-
export const
|
|
14
|
-
id: '
|
|
15
|
-
description: '
|
|
13
|
+
export const weatherTool = createTool({
|
|
14
|
+
id: 'weather-tool',
|
|
15
|
+
description: 'Get the current weather for a location',
|
|
16
16
|
inputSchema: z.object({
|
|
17
|
-
|
|
17
|
+
location: z.string(),
|
|
18
18
|
}),
|
|
19
19
|
outputSchema: z.object({
|
|
20
|
-
|
|
20
|
+
location: z.string(),
|
|
21
|
+
temperatureCelsius: z.number(),
|
|
22
|
+
conditions: z.string(),
|
|
21
23
|
}),
|
|
22
|
-
execute: async
|
|
23
|
-
const reversed = inputData.input.split('').reverse().join('')
|
|
24
|
-
|
|
24
|
+
execute: async ({ location }) => {
|
|
25
25
|
return {
|
|
26
|
-
|
|
26
|
+
location,
|
|
27
|
+
temperatureCelsius: 21,
|
|
28
|
+
conditions: 'sunny',
|
|
27
29
|
}
|
|
28
30
|
},
|
|
29
31
|
})
|
|
30
32
|
```
|
|
31
33
|
|
|
34
|
+
The first `execute` parameter is the validated value from `inputSchema`. Destructure schema fields directly in the function signature, as shown with `{ location }`. The optional second parameter contains the execution context.
|
|
35
|
+
|
|
32
36
|
## Parameters
|
|
33
37
|
|
|
34
38
|
**id** (`string`): A unique identifier for the tool.
|
|
@@ -112,10 +116,12 @@ export const weatherTool = createTool({
|
|
|
112
116
|
location: z.string(),
|
|
113
117
|
}),
|
|
114
118
|
outputSchema: z.object({
|
|
115
|
-
|
|
119
|
+
location: z.string(),
|
|
120
|
+
temperatureCelsius: z.number(),
|
|
121
|
+
conditions: z.string(),
|
|
116
122
|
}),
|
|
117
|
-
execute: async
|
|
118
|
-
|
|
123
|
+
execute: async ({ location }) => {
|
|
124
|
+
return { location, temperatureCelsius: 21, conditions: 'sunny' }
|
|
119
125
|
},
|
|
120
126
|
})
|
|
121
127
|
```
|
|
@@ -137,11 +143,13 @@ export const weatherTool = createTool({
|
|
|
137
143
|
),
|
|
138
144
|
outputSchema: toStandardJsonSchema(
|
|
139
145
|
v.object({
|
|
140
|
-
|
|
146
|
+
location: v.string(),
|
|
147
|
+
temperatureCelsius: v.number(),
|
|
148
|
+
conditions: v.string(),
|
|
141
149
|
}),
|
|
142
150
|
),
|
|
143
|
-
execute: async
|
|
144
|
-
|
|
151
|
+
execute: async ({ location }) => {
|
|
152
|
+
return { location, temperatureCelsius: 21, conditions: 'sunny' }
|
|
145
153
|
},
|
|
146
154
|
})
|
|
147
155
|
```
|
|
@@ -159,10 +167,12 @@ export const weatherTool = createTool({
|
|
|
159
167
|
location: 'string',
|
|
160
168
|
}),
|
|
161
169
|
outputSchema: type({
|
|
162
|
-
|
|
170
|
+
location: 'string',
|
|
171
|
+
temperatureCelsius: 'number',
|
|
172
|
+
conditions: 'string',
|
|
163
173
|
}),
|
|
164
|
-
execute: async
|
|
165
|
-
|
|
174
|
+
execute: async ({ location }) => {
|
|
175
|
+
return { location, temperatureCelsius: 21, conditions: 'sunny' }
|
|
166
176
|
},
|
|
167
177
|
})
|
|
168
178
|
```
|
|
@@ -176,18 +186,22 @@ import { createTool } from '@mastra/core/tools'
|
|
|
176
186
|
import { z } from 'zod'
|
|
177
187
|
|
|
178
188
|
export const weatherTool = createTool({
|
|
179
|
-
id: '
|
|
180
|
-
description: 'Get weather for a
|
|
189
|
+
id: 'weather-tool',
|
|
190
|
+
description: 'Get the current weather for a location',
|
|
181
191
|
strict: true,
|
|
182
192
|
inputSchema: z.object({
|
|
183
|
-
|
|
184
|
-
|
|
193
|
+
location: z.string(),
|
|
194
|
+
}),
|
|
195
|
+
outputSchema: z.object({
|
|
196
|
+
location: z.string(),
|
|
197
|
+
temperatureCelsius: z.number(),
|
|
198
|
+
conditions: z.string(),
|
|
185
199
|
}),
|
|
186
|
-
execute: async ({
|
|
200
|
+
execute: async ({ location }) => {
|
|
187
201
|
return {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
202
|
+
location,
|
|
203
|
+
temperatureCelsius: 21,
|
|
204
|
+
conditions: 'sunny',
|
|
191
205
|
}
|
|
192
206
|
},
|
|
193
207
|
})
|
|
@@ -204,28 +218,31 @@ import { createTool } from '@mastra/core/tools'
|
|
|
204
218
|
import { z } from 'zod'
|
|
205
219
|
|
|
206
220
|
export const weatherTool = createTool({
|
|
207
|
-
id: '
|
|
208
|
-
description: 'Get weather for a
|
|
221
|
+
id: 'weather-tool',
|
|
222
|
+
description: 'Get the current weather for a location',
|
|
209
223
|
inputSchema: z.object({
|
|
210
|
-
|
|
224
|
+
location: z.string(),
|
|
211
225
|
}),
|
|
212
226
|
outputSchema: z.object({
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
227
|
+
location: z.string(),
|
|
228
|
+
temperatureCelsius: z.number(),
|
|
229
|
+
conditions: z.string(),
|
|
216
230
|
radarImageUrl: z.string().url(),
|
|
217
231
|
}),
|
|
218
|
-
execute: async ({
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
232
|
+
execute: async ({ location }) => ({
|
|
233
|
+
location,
|
|
234
|
+
temperatureCelsius: 21,
|
|
235
|
+
conditions: 'sunny',
|
|
222
236
|
radarImageUrl: 'https://example.com/radar/seattle.png',
|
|
223
237
|
}),
|
|
224
238
|
toModelOutput: output => {
|
|
225
239
|
return {
|
|
226
240
|
type: 'content',
|
|
227
241
|
value: [
|
|
228
|
-
{
|
|
242
|
+
{
|
|
243
|
+
type: 'text',
|
|
244
|
+
text: `${output.location}: ${output.temperatureCelsius}°C and ${output.conditions}`,
|
|
245
|
+
},
|
|
229
246
|
{ type: 'image-url', url: output.radarImageUrl },
|
|
230
247
|
],
|
|
231
248
|
}
|
|
@@ -294,11 +311,16 @@ import { createTool } from '@mastra/core/tools'
|
|
|
294
311
|
import { z } from 'zod'
|
|
295
312
|
|
|
296
313
|
export const weatherTool = createTool({
|
|
297
|
-
id: '
|
|
298
|
-
description: 'Get current weather for a location',
|
|
314
|
+
id: 'weather-tool',
|
|
315
|
+
description: 'Get the current weather for a location',
|
|
299
316
|
inputSchema: z.object({
|
|
300
317
|
location: z.string().describe('City name or coordinates'),
|
|
301
318
|
}),
|
|
319
|
+
outputSchema: z.object({
|
|
320
|
+
location: z.string(),
|
|
321
|
+
temperatureCelsius: z.number(),
|
|
322
|
+
conditions: z.string(),
|
|
323
|
+
}),
|
|
302
324
|
// MCP-specific properties
|
|
303
325
|
mcp: {
|
|
304
326
|
// Annotations for client behavior hints
|
|
@@ -315,9 +337,11 @@ export const weatherTool = createTool({
|
|
|
315
337
|
category: 'weather',
|
|
316
338
|
},
|
|
317
339
|
},
|
|
318
|
-
execute: async
|
|
340
|
+
execute: async ({ location }) => {
|
|
319
341
|
return {
|
|
320
|
-
|
|
342
|
+
location,
|
|
343
|
+
temperatureCelsius: 21,
|
|
344
|
+
conditions: 'sunny',
|
|
321
345
|
}
|
|
322
346
|
},
|
|
323
347
|
})
|
|
@@ -334,19 +358,21 @@ import { createTool } from '@mastra/core/tools'
|
|
|
334
358
|
import { z } from 'zod'
|
|
335
359
|
|
|
336
360
|
export const weatherTool = createTool({
|
|
337
|
-
id: '
|
|
338
|
-
description: 'Get weather for a
|
|
361
|
+
id: 'weather-tool',
|
|
362
|
+
description: 'Get the current weather for a location',
|
|
339
363
|
inputSchema: z.object({
|
|
340
|
-
|
|
364
|
+
location: z.string(),
|
|
341
365
|
}),
|
|
342
366
|
outputSchema: z.object({
|
|
343
|
-
|
|
344
|
-
|
|
367
|
+
location: z.string(),
|
|
368
|
+
temperatureCelsius: z.number(),
|
|
369
|
+
conditions: z.string(),
|
|
345
370
|
}),
|
|
346
|
-
execute: async ({
|
|
371
|
+
execute: async ({ location }) => {
|
|
347
372
|
return {
|
|
348
|
-
|
|
349
|
-
|
|
373
|
+
location,
|
|
374
|
+
temperatureCelsius: 21,
|
|
375
|
+
conditions: 'sunny',
|
|
350
376
|
}
|
|
351
377
|
},
|
|
352
378
|
onInputStart: ({ toolCallId }) => {
|
|
@@ -356,10 +382,10 @@ export const weatherTool = createTool({
|
|
|
356
382
|
console.log(`Tool call ${toolCallId} received input chunk: ${inputTextDelta}`)
|
|
357
383
|
},
|
|
358
384
|
onInputAvailable: ({ input, toolCallId }) => {
|
|
359
|
-
console.log(`Tool call ${toolCallId} received
|
|
385
|
+
console.log(`Tool call ${toolCallId} received location: ${input.location}`)
|
|
360
386
|
},
|
|
361
387
|
onOutput: ({ output, toolCallId, toolName }) => {
|
|
362
|
-
console.log(`Tool ${toolName} call ${toolCallId} returned
|
|
388
|
+
console.log(`Tool ${toolName} call ${toolCallId} returned conditions: ${output.conditions}`)
|
|
363
389
|
},
|
|
364
390
|
})
|
|
365
391
|
```
|
|
@@ -403,7 +429,7 @@ export const tool = createTool({
|
|
|
403
429
|
id: 'example-tool',
|
|
404
430
|
description: 'Example tool with hooks',
|
|
405
431
|
inputSchema: z.object({
|
|
406
|
-
|
|
432
|
+
location: z.string(),
|
|
407
433
|
}),
|
|
408
434
|
onInputAvailable: ({ input, toolCallId, messages, abortSignal }) => {
|
|
409
435
|
console.log(`Tool received complete input:`, input)
|
|
@@ -207,6 +207,34 @@ const instructionsByServer = mcp.getServerInstructions()
|
|
|
207
207
|
console.log(instructionsByServer.db)
|
|
208
208
|
```
|
|
209
209
|
|
|
210
|
+
### `authenticate()`
|
|
211
|
+
|
|
212
|
+
Runs the interactive OAuth authorization-code flow for a server configured with an `MCPOAuthClientProvider` whose redirect URL points at a loopback address. Starts a local callback server, delivers the authorization URL through the provider's `onRedirectToAuthorization` callback, waits for the browser to return the authorization code, exchanges it for tokens, and reconnects. See [Interactive browser authentication](#interactive-browser-authentication).
|
|
213
|
+
|
|
214
|
+
The optional `timeoutMs` bounds how long the flow waits for the browser to return the authorization code before rejecting, and defaults to 5 minutes.
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
async authenticate(serverName: string, options?: { timeoutMs?: number }): Promise<void>
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### `getServerAuthState()`
|
|
221
|
+
|
|
222
|
+
Returns the OAuth authorization state of a configured server: `'needs-auth'` after a connection attempt was rejected with an authorization error, `'authorized'` once the server accepted the provider's credentials, or `undefined` for servers without an `authProvider` or that haven't attempted a connection yet.
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
getServerAuthState(serverName: string): 'needs-auth' | 'authorized' | undefined
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### `cancelAuthentication()`
|
|
229
|
+
|
|
230
|
+
Cancels an in-progress `authenticate()` flow for a server, so an abandoned browser authorization does not leave the client waiting indefinitely. It aborts the flow (including its setup phase, before the callback server binds), closes the local callback server if one is listening, and the pending `authenticate()` call rejects. Returns `true` if a flow was cancelled, or `false` when no flow was in progress.
|
|
231
|
+
|
|
232
|
+
The resulting `getServerAuthState()` depends on how far the flow had progressed: a flow cancelled after the server rejected the connection with `401` stays at `'needs-auth'` and can be retried immediately, while a flow cancelled during the setup phase — before any connection was attempted — leaves the state unchanged (typically `undefined`).
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
async cancelAuthentication(serverName: string): Promise<boolean>
|
|
236
|
+
```
|
|
237
|
+
|
|
210
238
|
### `disconnect()`
|
|
211
239
|
|
|
212
240
|
Disconnects from all MCP servers and cleans up resources.
|
|
@@ -252,9 +280,7 @@ This is useful for connecting external MCP servers that implement the MCP Apps e
|
|
|
252
280
|
The `MCPClient` instance has a `resources` property that provides access to resource-related operations.
|
|
253
281
|
|
|
254
282
|
```typescript
|
|
255
|
-
const mcpClient = new MCPClient({
|
|
256
|
-
/* ...servers configuration... */
|
|
257
|
-
})
|
|
283
|
+
const mcpClient = new MCPClient({/* ...servers configuration... */})
|
|
258
284
|
|
|
259
285
|
// Access resource methods via mcpClient.resources
|
|
260
286
|
const allResourcesByServer = await mcpClient.resources.list()
|
|
@@ -383,9 +409,7 @@ mcpClient.resources.onListChanged('myWeatherServer', () => {
|
|
|
383
409
|
The `MCPClient` instance has an `elicitation` property that provides access to elicitation-related operations. Elicitation allows MCP servers to request structured information from users.
|
|
384
410
|
|
|
385
411
|
```typescript
|
|
386
|
-
const mcpClient = new MCPClient({
|
|
387
|
-
/* ...servers configuration... */
|
|
388
|
-
})
|
|
412
|
+
const mcpClient = new MCPClient({/* ...servers configuration... */})
|
|
389
413
|
|
|
390
414
|
// Set up elicitation handler
|
|
391
415
|
mcpClient.elicitation.onRequest('serverName', async request => {
|
|
@@ -524,9 +548,7 @@ await mcpClient.elicitation.onRequest('interactiveServer', async request => {
|
|
|
524
548
|
The `MCPClient` instance has a `prompts` property that provides access to prompt-related operations.
|
|
525
549
|
|
|
526
550
|
```typescript
|
|
527
|
-
const mcpClient = new MCPClient({
|
|
528
|
-
/* ...servers configuration... */
|
|
529
|
-
})
|
|
551
|
+
const mcpClient = new MCPClient({/* ...servers configuration... */})
|
|
530
552
|
|
|
531
553
|
// Access prompt methods via mcpClient.prompts
|
|
532
554
|
const allPromptsByServer = await mcpClient.prompts.list()
|
|
@@ -821,6 +843,74 @@ const client = new MCPClient({
|
|
|
821
843
|
})
|
|
822
844
|
```
|
|
823
845
|
|
|
846
|
+
Give each server its own `MCPOAuthClientProvider` instance. A provider holds per-server session and credential state during authorization, so sharing one instance across multiple servers lets their flows overwrite each other. When configuring several protected servers, construct a separate provider for each.
|
|
847
|
+
|
|
848
|
+
### Interactive browser authentication
|
|
849
|
+
|
|
850
|
+
When a server rejects a connection because authorization is required, the client records a `'needs-auth'` state instead of failing outright. Calling `authenticate()` then completes the flow end to end: it starts a one-shot callback server on the provider's loopback redirect URL (falling back to the next sequential ports when it is in use), lets the SDK run discovery and dynamic client registration, delivers the authorization URL through `onRedirectToAuthorization` — open it in the user's browser — and finishes the token exchange once the browser returns the authorization code:
|
|
851
|
+
|
|
852
|
+
```typescript
|
|
853
|
+
import { MCPClient, MCPOAuthClientProvider } from '@mastra/mcp'
|
|
854
|
+
|
|
855
|
+
const oauthProvider = new MCPOAuthClientProvider({
|
|
856
|
+
redirectUrl: 'http://127.0.0.1:5533/oauth/callback',
|
|
857
|
+
clientMetadata: {
|
|
858
|
+
redirect_uris: ['http://127.0.0.1:5533/oauth/callback'],
|
|
859
|
+
client_name: 'My MCP Client',
|
|
860
|
+
grant_types: ['authorization_code', 'refresh_token'],
|
|
861
|
+
response_types: ['code'],
|
|
862
|
+
},
|
|
863
|
+
onRedirectToAuthorization: url => {
|
|
864
|
+
// Open the user's browser at the consent page
|
|
865
|
+
console.log(`Please visit: ${url}`)
|
|
866
|
+
},
|
|
867
|
+
})
|
|
868
|
+
|
|
869
|
+
const mcp = new MCPClient({
|
|
870
|
+
servers: {
|
|
871
|
+
protectedServer: {
|
|
872
|
+
url: new URL('https://mcp.example.com/mcp'),
|
|
873
|
+
authProvider: oauthProvider,
|
|
874
|
+
},
|
|
875
|
+
},
|
|
876
|
+
})
|
|
877
|
+
|
|
878
|
+
try {
|
|
879
|
+
await mcp.listTools()
|
|
880
|
+
} catch {
|
|
881
|
+
if (mcp.getServerAuthState('protectedServer') === 'needs-auth') {
|
|
882
|
+
await mcp.authenticate('protectedServer')
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
```
|
|
886
|
+
|
|
887
|
+
Concurrent `authenticate()` calls for the same server join the pending flow; different servers authenticate independently. With valid stored tokens the call simply reconnects without opening a browser.
|
|
888
|
+
|
|
889
|
+
Hosts that drive the flow themselves can capture the authorization code with the exported `createOAuthCallbackServer` helper, which binds a one-shot loopback server, validates the OAuth `state` parameter, and resolves with the code. It creates a plain HTTP server, so it is only for local loopback redirects. Web applications that use an HTTPS redirect URL must host their own callback endpoint and drive the provider directly rather than using this helper:
|
|
890
|
+
|
|
891
|
+
```typescript
|
|
892
|
+
import { createOAuthCallbackServer, getCallbackUrlCandidates } from '@mastra/mcp'
|
|
893
|
+
|
|
894
|
+
// getCallbackUrlCandidates() lists every URL the helper may bind, so register
|
|
895
|
+
// all of them as redirect_uris during client registration to cover port fallback.
|
|
896
|
+
const redirectUris = getCallbackUrlCandidates('http://127.0.0.1:5533/oauth/callback').map(url =>
|
|
897
|
+
url.toString(),
|
|
898
|
+
)
|
|
899
|
+
|
|
900
|
+
const server = await createOAuthCallbackServer({
|
|
901
|
+
redirectUrl: 'http://127.0.0.1:5533/oauth/callback',
|
|
902
|
+
state: expectedState,
|
|
903
|
+
})
|
|
904
|
+
|
|
905
|
+
// server.url reflects the port actually bound — use it as the redirect_uri.
|
|
906
|
+
try {
|
|
907
|
+
const { code } = await server.waitForCode()
|
|
908
|
+
// Exchange the code here.
|
|
909
|
+
} finally {
|
|
910
|
+
await server.close()
|
|
911
|
+
}
|
|
912
|
+
```
|
|
913
|
+
|
|
824
914
|
### Quick Token Provider
|
|
825
915
|
|
|
826
916
|
For testing or when you already have a valid access token:
|
|
@@ -884,9 +974,7 @@ class DatabaseOAuthStorage implements OAuthStorage {
|
|
|
884
974
|
|
|
885
975
|
const provider = new MCPOAuthClientProvider({
|
|
886
976
|
redirectUrl: 'http://localhost:3000/callback',
|
|
887
|
-
clientMetadata: {
|
|
888
|
-
/* ... */
|
|
889
|
-
},
|
|
977
|
+
clientMetadata: {/* ... */},
|
|
890
978
|
storage: new DatabaseOAuthStorage(db, 'user-123'),
|
|
891
979
|
})
|
|
892
980
|
```
|
|
@@ -1021,33 +1109,25 @@ For example, if you try to create multiple instances with the same configuration
|
|
|
1021
1109
|
```typescript
|
|
1022
1110
|
// First instance - OK
|
|
1023
1111
|
const mcp1 = new MCPClient({
|
|
1024
|
-
servers: {
|
|
1025
|
-
/* ... */
|
|
1026
|
-
},
|
|
1112
|
+
servers: {/* ... */},
|
|
1027
1113
|
})
|
|
1028
1114
|
|
|
1029
1115
|
// Second instance with same config - Will throw an error
|
|
1030
1116
|
const mcp2 = new MCPClient({
|
|
1031
|
-
servers: {
|
|
1032
|
-
/* ... */
|
|
1033
|
-
},
|
|
1117
|
+
servers: {/* ... */},
|
|
1034
1118
|
})
|
|
1035
1119
|
|
|
1036
1120
|
// To fix, either:
|
|
1037
1121
|
// 1. Add unique IDs
|
|
1038
1122
|
const mcp3 = new MCPClient({
|
|
1039
1123
|
id: 'instance-1',
|
|
1040
|
-
servers: {
|
|
1041
|
-
/* ... */
|
|
1042
|
-
},
|
|
1124
|
+
servers: {/* ... */},
|
|
1043
1125
|
})
|
|
1044
1126
|
|
|
1045
1127
|
// 2. Or disconnect before recreating
|
|
1046
1128
|
await mcp1.disconnect()
|
|
1047
1129
|
const mcp4 = new MCPClient({
|
|
1048
|
-
servers: {
|
|
1049
|
-
/* ... */
|
|
1050
|
-
},
|
|
1130
|
+
servers: {/* ... */},
|
|
1051
1131
|
})
|
|
1052
1132
|
```
|
|
1053
1133
|
|