@mastra/mcp-docs-server 0.13.2-alpha.1 → 0.13.2-alpha.2
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/organized/changelogs/%40mastra%2Fastra.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fchroma.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fclickhouse.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fclient-js.md +18 -18
- package/.docs/organized/changelogs/%40mastra%2Fcloudflare-d1.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fcloudflare.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fcore.md +15 -15
- package/.docs/organized/changelogs/%40mastra%2Fcouchbase.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fdeployer-cloudflare.md +20 -20
- package/.docs/organized/changelogs/%40mastra%2Fdeployer-netlify.md +24 -24
- package/.docs/organized/changelogs/%40mastra%2Fdeployer-vercel.md +24 -24
- package/.docs/organized/changelogs/%40mastra%2Fdeployer.md +22 -22
- package/.docs/organized/changelogs/%40mastra%2Fdynamodb.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Flance.md +13 -0
- package/.docs/organized/changelogs/%40mastra%2Flibsql.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fmcp-docs-server.md +10 -10
- package/.docs/organized/changelogs/%40mastra%2Fmcp.md +9 -9
- package/.docs/organized/changelogs/%40mastra%2Fmemory.md +22 -22
- package/.docs/organized/changelogs/%40mastra%2Fmongodb.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fopensearch.md +13 -0
- package/.docs/organized/changelogs/%40mastra%2Fpg.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fpinecone.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fplayground-ui.md +20 -20
- package/.docs/organized/changelogs/%40mastra%2Fqdrant.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fserver.md +20 -20
- package/.docs/organized/changelogs/%40mastra%2Fturbopuffer.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fupstash.md +14 -14
- package/.docs/organized/changelogs/%40mastra%2Fvectorize.md +14 -14
- package/.docs/organized/changelogs/mastra.md +22 -22
- package/.docs/organized/code-examples/agent.md +182 -5
- package/.docs/organized/code-examples/assistant-ui.md +1 -1
- package/.docs/organized/code-examples/bird-checker-with-nextjs-and-eval.md +1 -1
- package/.docs/organized/code-examples/bird-checker-with-nextjs.md +1 -1
- package/.docs/organized/code-examples/crypto-chatbot.md +2 -2
- package/.docs/organized/code-examples/openapi-spec-writer.md +1 -1
- package/.docs/raw/agents/using-tools-and-mcp.mdx +3 -2
- package/.docs/raw/deployment/cloud-providers/digital-ocean.mdx +111 -0
- package/.docs/raw/deployment/cloud-providers/index.mdx +15 -0
- package/.docs/raw/memory/working-memory.mdx +56 -0
- package/.docs/raw/networks-vnext/complex-task-execution.mdx +137 -0
- package/.docs/raw/networks-vnext/overview.mdx +85 -0
- package/.docs/raw/networks-vnext/single-task-execution.mdx +131 -0
- package/.docs/raw/reference/client-js/agents.mdx +41 -0
- package/.docs/raw/reference/deployer/netlify.mdx +22 -68
- package/.docs/raw/reference/deployer/vercel.mdx +7 -77
- package/.docs/raw/reference/tools/mcp-client.mdx +244 -0
- package/.docs/raw/reference/tools/mcp-server.mdx +186 -0
- package/.docs/raw/reference/workflows/create-run.mdx +1 -1
- package/.docs/raw/reference/workflows/resume.mdx +1 -1
- package/.docs/raw/reference/workflows/start.mdx +1 -1
- package/.docs/raw/reference/workflows/stream.mdx +1 -1
- package/.docs/raw/reference/workflows/watch.mdx +1 -1
- package/.docs/raw/reference/workflows/workflow.mdx +6 -2
- package/.docs/raw/workflows/control-flow.mdx +42 -1
- package/.docs/raw/workflows/overview.mdx +73 -5
- package/.docs/raw/workflows/pausing-execution.mdx +1 -1
- package/.docs/raw/workflows/suspend-and-resume.mdx +68 -23
- package/.docs/raw/workflows/using-with-agents-and-tools.mdx +1 -1
- package/package.json +3 -3
|
@@ -308,6 +308,145 @@ const { prompt, messages } = await mcpClient.prompts.get({
|
|
|
308
308
|
});
|
|
309
309
|
```
|
|
310
310
|
|
|
311
|
+
### `elicitation` Property
|
|
312
|
+
|
|
313
|
+
The `MCPClient` instance has an `elicitation` property that provides access to elicitation-related operations. Elicitation allows MCP servers to request structured information from users.
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
const mcpClient = new MCPClient({
|
|
317
|
+
/* ...servers configuration... */
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
// Set up elicitation handler
|
|
321
|
+
mcpClient.elicitation.onRequest('serverName', async (request) => {
|
|
322
|
+
// Handle elicitation request from server
|
|
323
|
+
console.log('Server requests:', request.message);
|
|
324
|
+
console.log('Schema:', request.requestedSchema);
|
|
325
|
+
|
|
326
|
+
// Return user response
|
|
327
|
+
return {
|
|
328
|
+
action: 'accept',
|
|
329
|
+
content: { name: 'John Doe', email: 'john@example.com' }
|
|
330
|
+
};
|
|
331
|
+
});
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
#### `elicitation.onRequest(serverName: string, handler: ElicitationHandler)`
|
|
335
|
+
|
|
336
|
+
Sets up a handler function that will be called when any connected MCP server sends an elicitation request. The handler receives the request and must return a response.
|
|
337
|
+
|
|
338
|
+
**ElicitationHandler Function:**
|
|
339
|
+
|
|
340
|
+
The handler function receives a request object with:
|
|
341
|
+
- `message`: A human-readable message describing what information is needed
|
|
342
|
+
- `requestedSchema`: A JSON schema defining the structure of the expected response
|
|
343
|
+
|
|
344
|
+
The handler must return an `ElicitResult` with:
|
|
345
|
+
- `action`: One of `'accept'`, `'reject'`, or `'cancel'`
|
|
346
|
+
- `content`: The user's data (only when action is `'accept'`)
|
|
347
|
+
|
|
348
|
+
**Example:**
|
|
349
|
+
|
|
350
|
+
```typescript
|
|
351
|
+
mcpClient.elicitation.onRequest('serverName', async (request) => {
|
|
352
|
+
console.log(`Server requests: ${request.message}`);
|
|
353
|
+
|
|
354
|
+
// Example: Simple user input collection
|
|
355
|
+
if (request.requestedSchema.properties.name) {
|
|
356
|
+
// Simulate user accepting and providing data
|
|
357
|
+
return {
|
|
358
|
+
action: 'accept',
|
|
359
|
+
content: {
|
|
360
|
+
name: 'Alice Smith',
|
|
361
|
+
email: 'alice@example.com'
|
|
362
|
+
}
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// Simulate user rejecting the request
|
|
367
|
+
return { action: 'reject' };
|
|
368
|
+
});
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
**Complete Interactive Example:**
|
|
372
|
+
|
|
373
|
+
```typescript
|
|
374
|
+
import { MCPClient } from '@mastra/mcp';
|
|
375
|
+
import { createInterface } from 'readline';
|
|
376
|
+
|
|
377
|
+
const readline = createInterface({
|
|
378
|
+
input: process.stdin,
|
|
379
|
+
output: process.stdout,
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
function askQuestion(question: string): Promise<string> {
|
|
383
|
+
return new Promise(resolve => {
|
|
384
|
+
readline.question(question, answer => resolve(answer.trim()));
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
const mcpClient = new MCPClient({
|
|
389
|
+
servers: {
|
|
390
|
+
interactiveServer: {
|
|
391
|
+
url: new URL('http://localhost:3000/mcp'),
|
|
392
|
+
},
|
|
393
|
+
},
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
// Set up interactive elicitation handler
|
|
397
|
+
await mcpClient.elicitation.onRequest('interactiveServer', async (request) => {
|
|
398
|
+
console.log(`\n📋 Server Request: ${request.message}`);
|
|
399
|
+
console.log('Required information:');
|
|
400
|
+
|
|
401
|
+
const schema = request.requestedSchema;
|
|
402
|
+
const properties = schema.properties || {};
|
|
403
|
+
const required = schema.required || [];
|
|
404
|
+
const content: Record<string, any> = {};
|
|
405
|
+
|
|
406
|
+
// Collect input for each field
|
|
407
|
+
for (const [fieldName, fieldSchema] of Object.entries(properties)) {
|
|
408
|
+
const field = fieldSchema as any;
|
|
409
|
+
const isRequired = required.includes(fieldName);
|
|
410
|
+
|
|
411
|
+
let prompt = `${field.title || fieldName}`;
|
|
412
|
+
if (field.description) prompt += ` (${field.description})`;
|
|
413
|
+
if (isRequired) prompt += ' *required*';
|
|
414
|
+
prompt += ': ';
|
|
415
|
+
|
|
416
|
+
const answer = await askQuestion(prompt);
|
|
417
|
+
|
|
418
|
+
// Handle cancellation
|
|
419
|
+
if (answer.toLowerCase() === 'cancel') {
|
|
420
|
+
return { action: 'cancel' };
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// Validate required fields
|
|
424
|
+
if (answer === '' && isRequired) {
|
|
425
|
+
console.log(`❌ ${fieldName} is required`);
|
|
426
|
+
return { action: 'reject' };
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
if (answer !== '') {
|
|
430
|
+
content[fieldName] = answer;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Confirm submission
|
|
435
|
+
console.log('\n📝 You provided:');
|
|
436
|
+
console.log(JSON.stringify(content, null, 2));
|
|
437
|
+
|
|
438
|
+
const confirm = await askQuestion('\nSubmit this information? (yes/no/cancel): ');
|
|
439
|
+
|
|
440
|
+
if (confirm.toLowerCase() === 'yes' || confirm.toLowerCase() === 'y') {
|
|
441
|
+
return { action: 'accept', content };
|
|
442
|
+
} else if (confirm.toLowerCase() === 'cancel') {
|
|
443
|
+
return { action: 'cancel' };
|
|
444
|
+
} else {
|
|
445
|
+
return { action: 'reject' };
|
|
446
|
+
}
|
|
447
|
+
});
|
|
448
|
+
```
|
|
449
|
+
|
|
311
450
|
#### `prompts.list()`
|
|
312
451
|
|
|
313
452
|
Retrieves all available prompts from all connected MCP servers, grouped by server name.
|
|
@@ -373,6 +512,111 @@ mcpClient.prompts.onListChanged("myWeatherServer", () => {
|
|
|
373
512
|
});
|
|
374
513
|
```
|
|
375
514
|
|
|
515
|
+
## Elicitation
|
|
516
|
+
|
|
517
|
+
Elicitation is a feature that allows MCP servers to request structured information from users. When a server needs additional data, it can send an elicitation request that the client handles by prompting the user. A common example is during a tool call.
|
|
518
|
+
|
|
519
|
+
### How Elicitation Works
|
|
520
|
+
|
|
521
|
+
1. **Server Request**: An MCP server tool calls `server.elicitation.sendRequest()` with a message and schema
|
|
522
|
+
2. **Client Handler**: Your elicitation handler function is called with the request
|
|
523
|
+
3. **User Interaction**: Your handler collects user input (via UI, CLI, etc.)
|
|
524
|
+
4. **Response**: Your handler returns the user's response (accept/reject/cancel)
|
|
525
|
+
5. **Tool Continuation**: The server tool receives the response and continues execution
|
|
526
|
+
|
|
527
|
+
### Setting Up Elicitation
|
|
528
|
+
|
|
529
|
+
You must set up an elicitation handler before tools that use elicitation are called:
|
|
530
|
+
|
|
531
|
+
```typescript
|
|
532
|
+
import { MCPClient } from '@mastra/mcp';
|
|
533
|
+
|
|
534
|
+
const mcpClient = new MCPClient({
|
|
535
|
+
servers: {
|
|
536
|
+
interactiveServer: {
|
|
537
|
+
url: new URL('http://localhost:3000/mcp'),
|
|
538
|
+
},
|
|
539
|
+
},
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
// Set up elicitation handler
|
|
543
|
+
mcpClient.elicitation.onRequest('interactiveServer', async (request) => {
|
|
544
|
+
// Handle the server's request for user input
|
|
545
|
+
console.log(`Server needs: ${request.message}`);
|
|
546
|
+
|
|
547
|
+
// Your logic to collect user input
|
|
548
|
+
const userData = await collectUserInput(request.requestedSchema);
|
|
549
|
+
|
|
550
|
+
return {
|
|
551
|
+
action: 'accept',
|
|
552
|
+
content: userData
|
|
553
|
+
};
|
|
554
|
+
});
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
### Response Types
|
|
558
|
+
|
|
559
|
+
Your elicitation handler must return one of three response types:
|
|
560
|
+
|
|
561
|
+
- **Accept**: User provided data and confirmed submission
|
|
562
|
+
```typescript
|
|
563
|
+
return {
|
|
564
|
+
action: 'accept',
|
|
565
|
+
content: { name: 'John Doe', email: 'john@example.com' }
|
|
566
|
+
};
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
- **Reject**: User explicitly declined to provide the information
|
|
570
|
+
```typescript
|
|
571
|
+
return { action: 'reject' };
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
- **Cancel**: User dismissed or cancelled the request
|
|
575
|
+
```typescript
|
|
576
|
+
return { action: 'cancel' };
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
### Schema-Based Input Collection
|
|
580
|
+
|
|
581
|
+
The `requestedSchema` provides structure for the data the server needs:
|
|
582
|
+
|
|
583
|
+
```typescript
|
|
584
|
+
await mcpClient.elicitation.onRequest('interactiveServer', async (request) => {
|
|
585
|
+
const { properties, required = [] } = request.requestedSchema;
|
|
586
|
+
const content: Record<string, any> = {};
|
|
587
|
+
|
|
588
|
+
for (const [fieldName, fieldSchema] of Object.entries(properties || {})) {
|
|
589
|
+
const field = fieldSchema as any;
|
|
590
|
+
const isRequired = required.includes(fieldName);
|
|
591
|
+
|
|
592
|
+
// Collect input based on field type and requirements
|
|
593
|
+
const value = await promptUser({
|
|
594
|
+
name: fieldName,
|
|
595
|
+
title: field.title,
|
|
596
|
+
description: field.description,
|
|
597
|
+
type: field.type,
|
|
598
|
+
required: isRequired,
|
|
599
|
+
format: field.format,
|
|
600
|
+
enum: field.enum,
|
|
601
|
+
});
|
|
602
|
+
|
|
603
|
+
if (value !== null) {
|
|
604
|
+
content[fieldName] = value;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
return { action: 'accept', content };
|
|
609
|
+
});
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
### Best Practices
|
|
613
|
+
|
|
614
|
+
- **Always handle elicitation**: Set up your handler before calling tools that might use elicitation
|
|
615
|
+
- **Validate input**: Check that required fields are provided
|
|
616
|
+
- **Respect user choice**: Handle reject and cancel responses gracefully
|
|
617
|
+
- **Clear UI**: Make it obvious what information is being requested and why
|
|
618
|
+
- **Security**: Never auto-accept requests for sensitive information
|
|
619
|
+
|
|
376
620
|
## Examples
|
|
377
621
|
|
|
378
622
|
### Static Tool Configuration
|
|
@@ -833,6 +833,192 @@ For practical examples of setting up and deploying an MCPServer, see the [Deploy
|
|
|
833
833
|
|
|
834
834
|
The example at the beginning of this page also demonstrates how to instantiate `MCPServer` with both tools and agents.
|
|
835
835
|
|
|
836
|
+
## Elicitation
|
|
837
|
+
|
|
838
|
+
### What is Elicitation?
|
|
839
|
+
|
|
840
|
+
Elicitation is a feature in the Model Context Protocol (MCP) that allows servers to request structured information from users. This enables interactive workflows where servers can collect additional data dynamically.
|
|
841
|
+
|
|
842
|
+
The `MCPServer` class automatically includes elicitation capabilities. Tools receive an `options` parameter in their `execute` function that includes an `elicitation.sendRequest()` method for requesting user input.
|
|
843
|
+
|
|
844
|
+
### Tool Execution Signature
|
|
845
|
+
|
|
846
|
+
When tools are executed within an MCP server context, they receive an additional `options` parameter:
|
|
847
|
+
|
|
848
|
+
```typescript
|
|
849
|
+
execute: async ({ context }, options) => {
|
|
850
|
+
// context contains the tool's input parameters
|
|
851
|
+
// options contains server capabilities like elicitation
|
|
852
|
+
|
|
853
|
+
const result = await options.elicitation.sendRequest({
|
|
854
|
+
message: "Please provide information",
|
|
855
|
+
requestedSchema: { /* schema */ }
|
|
856
|
+
});
|
|
857
|
+
|
|
858
|
+
return result;
|
|
859
|
+
}
|
|
860
|
+
```
|
|
861
|
+
|
|
862
|
+
### How Elicitation Works
|
|
863
|
+
|
|
864
|
+
A common use case is during tool execution. When a tool needs user input, it can use the elicitation functionality provided through the tool's execution options:
|
|
865
|
+
|
|
866
|
+
1. The tool calls `options.elicitation.sendRequest()` with a message and schema
|
|
867
|
+
2. The request is sent to the connected MCP client
|
|
868
|
+
3. The client presents the request to the user (via UI, command line, etc.)
|
|
869
|
+
4. The user provides input, rejects, or cancels the request
|
|
870
|
+
5. The client sends the response back to the server
|
|
871
|
+
6. The tool receives the response and continues execution
|
|
872
|
+
|
|
873
|
+
### Using Elicitation in Tools
|
|
874
|
+
|
|
875
|
+
Here's an example of a tool that uses elicitation to collect user contact information:
|
|
876
|
+
|
|
877
|
+
```typescript
|
|
878
|
+
import { MCPServer } from "@mastra/mcp";
|
|
879
|
+
import { createTool } from "@mastra/core/tools";
|
|
880
|
+
import { z } from "zod";
|
|
881
|
+
|
|
882
|
+
const server = new MCPServer({
|
|
883
|
+
name: "Interactive Server",
|
|
884
|
+
version: "1.0.0",
|
|
885
|
+
tools: {
|
|
886
|
+
collectContactInfo: createTool({
|
|
887
|
+
id: "collectContactInfo",
|
|
888
|
+
description: "Collects user contact information through elicitation",
|
|
889
|
+
inputSchema: z.object({
|
|
890
|
+
reason: z.string().optional().describe("Reason for collecting contact info"),
|
|
891
|
+
}),
|
|
892
|
+
execute: async ({ context }, options) => {
|
|
893
|
+
const { reason } = context;
|
|
894
|
+
|
|
895
|
+
try {
|
|
896
|
+
// Request user input via elicitation through the options parameter
|
|
897
|
+
const result = await options.elicitation.sendRequest({
|
|
898
|
+
message: reason
|
|
899
|
+
? `Please provide your contact information. ${reason}`
|
|
900
|
+
: 'Please provide your contact information',
|
|
901
|
+
requestedSchema: {
|
|
902
|
+
type: 'object',
|
|
903
|
+
properties: {
|
|
904
|
+
name: {
|
|
905
|
+
type: 'string',
|
|
906
|
+
title: 'Full Name',
|
|
907
|
+
description: 'Your full name',
|
|
908
|
+
},
|
|
909
|
+
email: {
|
|
910
|
+
type: 'string',
|
|
911
|
+
title: 'Email Address',
|
|
912
|
+
description: 'Your email address',
|
|
913
|
+
format: 'email',
|
|
914
|
+
},
|
|
915
|
+
phone: {
|
|
916
|
+
type: 'string',
|
|
917
|
+
title: 'Phone Number',
|
|
918
|
+
description: 'Your phone number (optional)',
|
|
919
|
+
},
|
|
920
|
+
},
|
|
921
|
+
required: ['name', 'email'],
|
|
922
|
+
},
|
|
923
|
+
});
|
|
924
|
+
|
|
925
|
+
// Handle the user's response
|
|
926
|
+
if (result.action === 'accept') {
|
|
927
|
+
return `Contact information collected: ${JSON.stringify(result.content, null, 2)}`;
|
|
928
|
+
} else if (result.action === 'reject') {
|
|
929
|
+
return 'Contact information collection was declined by the user.';
|
|
930
|
+
} else {
|
|
931
|
+
return 'Contact information collection was cancelled by the user.';
|
|
932
|
+
}
|
|
933
|
+
} catch (error) {
|
|
934
|
+
return `Error collecting contact information: ${error}`;
|
|
935
|
+
}
|
|
936
|
+
},
|
|
937
|
+
}),
|
|
938
|
+
},
|
|
939
|
+
});
|
|
940
|
+
```
|
|
941
|
+
|
|
942
|
+
### Elicitation Request Schema
|
|
943
|
+
|
|
944
|
+
The `requestedSchema` must be a flat object with primitive properties only. Supported types include:
|
|
945
|
+
|
|
946
|
+
- **String**: `{ type: 'string', title: 'Display Name', description: 'Help text' }`
|
|
947
|
+
- **Number**: `{ type: 'number', minimum: 0, maximum: 100 }`
|
|
948
|
+
- **Boolean**: `{ type: 'boolean', default: false }`
|
|
949
|
+
- **Enum**: `{ type: 'string', enum: ['option1', 'option2'] }`
|
|
950
|
+
|
|
951
|
+
Example schema:
|
|
952
|
+
|
|
953
|
+
```typescript
|
|
954
|
+
{
|
|
955
|
+
type: 'object',
|
|
956
|
+
properties: {
|
|
957
|
+
name: {
|
|
958
|
+
type: 'string',
|
|
959
|
+
title: 'Full Name',
|
|
960
|
+
description: 'Your complete name',
|
|
961
|
+
},
|
|
962
|
+
age: {
|
|
963
|
+
type: 'number',
|
|
964
|
+
title: 'Age',
|
|
965
|
+
minimum: 18,
|
|
966
|
+
maximum: 120,
|
|
967
|
+
},
|
|
968
|
+
newsletter: {
|
|
969
|
+
type: 'boolean',
|
|
970
|
+
title: 'Subscribe to Newsletter',
|
|
971
|
+
default: false,
|
|
972
|
+
},
|
|
973
|
+
},
|
|
974
|
+
required: ['name'],
|
|
975
|
+
}
|
|
976
|
+
```
|
|
977
|
+
|
|
978
|
+
### Response Actions
|
|
979
|
+
|
|
980
|
+
Users can respond to elicitation requests in three ways:
|
|
981
|
+
|
|
982
|
+
1. **Accept** (`action: 'accept'`): User provided data and confirmed submission
|
|
983
|
+
- Contains `content` field with the submitted data
|
|
984
|
+
2. **Reject** (`action: 'reject'`): User explicitly declined to provide information
|
|
985
|
+
- No content field
|
|
986
|
+
3. **Cancel** (`action: 'cancel'`): User dismissed the request without deciding
|
|
987
|
+
- No content field
|
|
988
|
+
|
|
989
|
+
Tools should handle all three response types appropriately.
|
|
990
|
+
|
|
991
|
+
### Security Considerations
|
|
992
|
+
|
|
993
|
+
- **Never request sensitive information** like passwords, SSNs, or credit card numbers
|
|
994
|
+
- Validate all user input against the provided schema
|
|
995
|
+
- Handle rejection and cancellation gracefully
|
|
996
|
+
- Provide clear reasons for data collection
|
|
997
|
+
- Respect user privacy and preferences
|
|
998
|
+
|
|
999
|
+
### Tool Execution API
|
|
1000
|
+
|
|
1001
|
+
The elicitation functionality is available through the `options` parameter in tool execution:
|
|
1002
|
+
|
|
1003
|
+
```typescript
|
|
1004
|
+
// Within a tool's execute function
|
|
1005
|
+
options.elicitation.sendRequest({
|
|
1006
|
+
message: string, // Message to display to user
|
|
1007
|
+
requestedSchema: object // JSON schema defining expected response structure
|
|
1008
|
+
}): Promise<ElicitResult>
|
|
1009
|
+
```
|
|
1010
|
+
|
|
1011
|
+
Note that elicitation is **session-aware** when using HTTP-based transports (SSE or HTTP). This means that when multiple clients are connected to the same server, elicitation requests are routed to the correct client session that initiated the tool execution.
|
|
1012
|
+
|
|
1013
|
+
The `ElicitResult` type:
|
|
1014
|
+
|
|
1015
|
+
```typescript
|
|
1016
|
+
type ElicitResult = {
|
|
1017
|
+
action: 'accept' | 'reject' | 'cancel';
|
|
1018
|
+
content?: any; // Only present when action is 'accept'
|
|
1019
|
+
}
|
|
1020
|
+
```
|
|
1021
|
+
|
|
836
1022
|
## Related Information
|
|
837
1023
|
|
|
838
1024
|
- For connecting to MCP servers in Mastra, see the [MCPClient documentation](./mcp-client).
|
|
@@ -10,7 +10,7 @@ The `.resume()` method resumes a suspended workflow run with new data, allowing
|
|
|
10
10
|
## Usage
|
|
11
11
|
|
|
12
12
|
```typescript
|
|
13
|
-
const run = counterWorkflow.
|
|
13
|
+
const run = await counterWorkflow.createRunAsync();
|
|
14
14
|
const result = await run.start({ inputData: { startValue: 0 } });
|
|
15
15
|
|
|
16
16
|
if (result.status === "suspended") {
|
|
@@ -10,7 +10,7 @@ The `.start()` method starts a workflow run with input data, allowing you to exe
|
|
|
10
10
|
## Usage
|
|
11
11
|
|
|
12
12
|
```typescript
|
|
13
|
-
const run = myWorkflow.
|
|
13
|
+
const run = await myWorkflow.createRunAsync();
|
|
14
14
|
|
|
15
15
|
// Start the workflow with input data
|
|
16
16
|
const result = await run.start({
|
|
@@ -10,7 +10,7 @@ The `.stream()` method allows you to monitor the execution of a workflow run, pr
|
|
|
10
10
|
## Usage
|
|
11
11
|
|
|
12
12
|
```typescript
|
|
13
|
-
const run = myWorkflow.
|
|
13
|
+
const run = await myWorkflow.createRunAsync();
|
|
14
14
|
|
|
15
15
|
// Add a stream to monitor execution
|
|
16
16
|
const result = run.stream({ inputData: {...} });
|
|
@@ -10,7 +10,7 @@ The `.watch()` method allows you to monitor the execution of a workflow run, pro
|
|
|
10
10
|
## Usage
|
|
11
11
|
|
|
12
12
|
```typescript
|
|
13
|
-
const run = myWorkflow.
|
|
13
|
+
const run = await myWorkflow.createRunAsync();
|
|
14
14
|
|
|
15
15
|
// Add a watcher to monitor execution
|
|
16
16
|
run.watch(event => {
|
|
@@ -31,7 +31,7 @@ const mastra = new Mastra({
|
|
|
31
31
|
},
|
|
32
32
|
});
|
|
33
33
|
|
|
34
|
-
const run = mastra.getWorkflow("myWorkflow").
|
|
34
|
+
const run = await mastra.getWorkflow("myWorkflow").createRunAsync();
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
## API Reference
|
|
@@ -99,7 +99,11 @@ Validates and finalizes the workflow configuration. Must be called after adding
|
|
|
99
99
|
|
|
100
100
|
#### `createRun()`
|
|
101
101
|
|
|
102
|
-
Creates a new workflow run instance, allowing you to execute the workflow with specific input data. Accepts optional run ID.
|
|
102
|
+
Deprecated. Creates a new workflow run instance, allowing you to execute the workflow with specific input data. Accepts optional run ID.
|
|
103
|
+
|
|
104
|
+
#### `createRunAsync()`
|
|
105
|
+
|
|
106
|
+
Creates a new workflow run instance, allowing you to execute the workflow with specific input data. Accepts optional run ID. Stores a pending workflow run snapshot into storage.
|
|
103
107
|
|
|
104
108
|
#### `execute()`
|
|
105
109
|
|
|
@@ -126,6 +126,47 @@ export const testWorkflow = createWorkflow({...})
|
|
|
126
126
|
.commit();
|
|
127
127
|
```
|
|
128
128
|
|
|
129
|
+
### Early exit
|
|
130
|
+
|
|
131
|
+
You can bail out of a workflow execution successfully by calling `bail()` in a step. This returns whatever payload is passed to the `bail()` function as the result of the workflow.
|
|
132
|
+
|
|
133
|
+
```typescript {7} filename="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
|
|
134
|
+
import { createWorkflow, createStep } from "@mastra/core/workflows";
|
|
135
|
+
import { z } from "zod";
|
|
136
|
+
|
|
137
|
+
const step1 = createStep({
|
|
138
|
+
id: 'step1',
|
|
139
|
+
execute: async ({ bail, inputData }) => {
|
|
140
|
+
return bail({ result: 'bailed' });
|
|
141
|
+
},
|
|
142
|
+
inputSchema: z.object({ value: z.string() }),
|
|
143
|
+
outputSchema: z.object({ result: z.string() }),
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
export const testWorkflow = createWorkflow({...})
|
|
147
|
+
.then(step1)
|
|
148
|
+
.commit();
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Unsuccessful bails happen through throwing an error in the step.
|
|
152
|
+
|
|
153
|
+
```typescript {7} filename="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
|
|
154
|
+
import { createWorkflow, createStep } from "@mastra/core/workflows";
|
|
155
|
+
import { z } from "zod";
|
|
156
|
+
|
|
157
|
+
const step1 = createStep({
|
|
158
|
+
id: 'step1',
|
|
159
|
+
execute: async ({ bail, inputData }) => {
|
|
160
|
+
throw new Error('bailed');
|
|
161
|
+
},
|
|
162
|
+
inputSchema: z.object({ value: z.string() }),
|
|
163
|
+
outputSchema: z.object({ result: z.string() }),
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
export const testWorkflow = createWorkflow({...})
|
|
167
|
+
.then(step1)
|
|
168
|
+
.commit();
|
|
169
|
+
```
|
|
129
170
|
#### Example Run Instance
|
|
130
171
|
|
|
131
172
|
The following example demonstrates how to start a run with multiple inputs. Each input will pass through the `mapStep` sequentially.
|
|
@@ -133,7 +174,7 @@ The following example demonstrates how to start a run with multiple inputs. Each
|
|
|
133
174
|
```typescript {6} filename="src/test-workflow.ts" showLineNumbers copy
|
|
134
175
|
import { mastra } from "./mastra";
|
|
135
176
|
|
|
136
|
-
const run = mastra.getWorkflow("testWorkflow").
|
|
177
|
+
const run = await mastra.getWorkflow("testWorkflow").createRunAsync();
|
|
137
178
|
|
|
138
179
|
const result = await run.start({
|
|
139
180
|
inputData: [{ number: 10 }, { number: 100 }, { number: 200 }]
|
|
@@ -157,12 +157,12 @@ With the Mastra Dev Server running you can run the workflow from the Mastra Play
|
|
|
157
157
|
|
|
158
158
|
#### Command line
|
|
159
159
|
|
|
160
|
-
Create a run instance of any Mastra workflow using `
|
|
160
|
+
Create a run instance of any Mastra workflow using `createRunAsync` and `start`:
|
|
161
161
|
|
|
162
162
|
```typescript {3,5} filename="src/test-workflow.ts" showLineNumbers copy
|
|
163
163
|
import { mastra } from "./mastra";
|
|
164
164
|
|
|
165
|
-
const run = mastra.getWorkflow("testWorkflow").
|
|
165
|
+
const run = await mastra.getWorkflow("testWorkflow").createRunAsync();
|
|
166
166
|
|
|
167
167
|
const result = await run.start({
|
|
168
168
|
inputData: {
|
|
@@ -172,7 +172,7 @@ const result = await run.start({
|
|
|
172
172
|
|
|
173
173
|
console.log(JSON.stringify(result, null, 2));
|
|
174
174
|
```
|
|
175
|
-
> see [
|
|
175
|
+
> see [createRunAsync](/reference/workflows/create-run-async) and [start](/reference/workflows/start) for more information.
|
|
176
176
|
|
|
177
177
|
To trigger this workflow, run the following:
|
|
178
178
|
|
|
@@ -182,6 +182,74 @@ npx tsx src/test-workflow.ts
|
|
|
182
182
|
|
|
183
183
|
</Steps>
|
|
184
184
|
|
|
185
|
+
#### Run Workflow Results
|
|
186
|
+
|
|
187
|
+
The result of running a workflow using either `start()` or `resume()` will look like one of the following, depending on the outcome.
|
|
188
|
+
|
|
189
|
+
##### Status success
|
|
190
|
+
|
|
191
|
+
```json
|
|
192
|
+
{
|
|
193
|
+
"status": "success",
|
|
194
|
+
"steps": {
|
|
195
|
+
// ...
|
|
196
|
+
"step-1": {
|
|
197
|
+
// ...
|
|
198
|
+
"status": "success",
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
"result": {
|
|
202
|
+
"output": "London + step-1"
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
- **status**: Shows the final state of the workflow execution, either: `success`, `suspended`, or `error`
|
|
208
|
+
- **steps**: Lists each step in the workflow, including inputs and outputs
|
|
209
|
+
- **status**: Shows the outcome of each individual step
|
|
210
|
+
- **result**: Includes the final output of the workflow, typed according to the `outputSchema`
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
##### Status suspended
|
|
214
|
+
|
|
215
|
+
```json
|
|
216
|
+
{
|
|
217
|
+
"status": "suspended",
|
|
218
|
+
"steps": {
|
|
219
|
+
// ...
|
|
220
|
+
"step-1": {
|
|
221
|
+
// ...
|
|
222
|
+
"status": "suspended",
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
"suspended": [
|
|
226
|
+
[
|
|
227
|
+
"step-1"
|
|
228
|
+
]
|
|
229
|
+
]
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
- **suspended**: An optional array listing any steps currently awaiting input before continuing
|
|
234
|
+
|
|
235
|
+
##### Status failed
|
|
236
|
+
|
|
237
|
+
```json
|
|
238
|
+
{
|
|
239
|
+
"status": "failed",
|
|
240
|
+
"steps": {
|
|
241
|
+
// ...
|
|
242
|
+
"step-1": {
|
|
243
|
+
// ...
|
|
244
|
+
"status": "failed",
|
|
245
|
+
"error": "Test error",
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
"error": "Test error"
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
- **error**: An optional field that includes the error message if the workflow fails
|
|
252
|
+
|
|
185
253
|
### Stream Workflow
|
|
186
254
|
|
|
187
255
|
Similar to the run method shown above, workflows can also be streamed:
|
|
@@ -189,7 +257,7 @@ Similar to the run method shown above, workflows can also be streamed:
|
|
|
189
257
|
```typescript {5} filename="src/test-workflow.ts" showLineNumbers copy
|
|
190
258
|
import { mastra } from "./mastra";
|
|
191
259
|
|
|
192
|
-
const run = mastra.getWorkflow("testWorkflow").
|
|
260
|
+
const run = await mastra.getWorkflow("testWorkflow").createRunAsync();
|
|
193
261
|
|
|
194
262
|
const result = await run.stream({
|
|
195
263
|
inputData: {
|
|
@@ -211,7 +279,7 @@ A workflow can also be watched, allowing you to inspect each event that is emitt
|
|
|
211
279
|
```typescript {5} filename="src/test-workflow.ts" showLineNumbers copy
|
|
212
280
|
import { mastra } from "./mastra";
|
|
213
281
|
|
|
214
|
-
const run = mastra.getWorkflow("testWorkflow").
|
|
282
|
+
const run = await mastra.getWorkflow("testWorkflow").createRunAsync();
|
|
215
283
|
|
|
216
284
|
run.watch((event) => {
|
|
217
285
|
console.log(event);
|