-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathsdk-mcp-tool.ts
More file actions
91 lines (83 loc) · 2.38 KB
/
Copy pathsdk-mcp-tool.ts
File metadata and controls
91 lines (83 loc) · 2.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/**
* SDK-defined MCP tool example.
*
* Demonstrates `createSdkMcpServer()` and `tool()`: registers an
* in-process MCP tool, asks the model to call it, and prints the tool
* call, tool result, and final assistant answer. The permission
* handler approves only MCP tool confirmations, cancels everything
* else, and logs each decision.
*
* Usage:
* npx tsx examples/sdk-mcp-tool.ts
*
* Requirements: droid CLI installed and logged in. FACTORY_API_KEY is
* optional; stored CLI credentials are used when it is unset. Set
* DROID_EXEC_PATH to point at a specific droid executable.
*/
import {
DroidMessageType,
ToolConfirmationOutcome,
ToolConfirmationType,
createSession,
createSdkMcpServer,
tool,
} from '@factory/droid-sdk';
import { z } from 'zod';
const execPath = process.env['DROID_EXEC_PATH'] ?? 'droid';
const sdkTools = createSdkMcpServer({
name: 'sdk-tools',
tools: [
tool(
'favorite_number',
'Returns a favorite number for a person',
{ name: z.string() },
({ name }) => `${name}'s favorite number is 42.`
),
],
});
const session = await createSession({
apiKey: process.env.FACTORY_API_KEY!,
execPath,
mcpServers: [sdkTools],
cwd: process.cwd(),
permissionHandler(params) {
const allMcp = params.toolUses.every(
(item) => item.details.type === ToolConfirmationType.McpTool
);
const decision = allMcp ? 'proceed_once' : 'cancel';
for (const item of params.toolUses) {
console.log(`[Permission] ${item.toolUse.name} -> ${decision}`);
}
return allMcp
? ToolConfirmationOutcome.ProceedOnce
: ToolConfirmationOutcome.Cancel;
},
});
try {
for await (const msg of session.stream(
'Use the favorite_number tool for Ada and tell me the answer.'
)) {
switch (msg.type) {
case DroidMessageType.ToolCall:
console.log(`[Tool Call] ${msg.toolUse.name}`);
break;
case DroidMessageType.ToolResult:
console.log(
`[Tool Result] ${msg.toolName}: ${
msg.isError ? 'Error' : JSON.stringify(msg.content)
}`
);
break;
case DroidMessageType.Assistant:
if (msg.text.trim()) {
console.log(`[Assistant] ${msg.text.trim()}`);
}
break;
case DroidMessageType.Result:
console.log('--- Turn complete ---');
break;
}
}
} finally {
await session.close();
}