@strav/brain 0.4.27 → 0.4.28
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/package.json +7 -3
- package/src/index.ts +2 -0
- package/src/mcp_toolbox.ts +62 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@strav/brain",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.28",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AI module for the Strav framework",
|
|
6
6
|
"license": "MIT",
|
|
@@ -15,12 +15,16 @@
|
|
|
15
15
|
"CHANGELOG.md"
|
|
16
16
|
],
|
|
17
17
|
"peerDependencies": {
|
|
18
|
-
"@strav/kernel": "0.4.
|
|
18
|
+
"@strav/kernel": "0.4.28"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@strav/
|
|
21
|
+
"@strav/mcp": "0.4.28",
|
|
22
|
+
"@strav/workflow": "0.4.28",
|
|
22
23
|
"zod": "^3.25 || ^4.0"
|
|
23
24
|
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@strav/http": "0.4.28"
|
|
27
|
+
},
|
|
24
28
|
"scripts": {
|
|
25
29
|
"test": "bun test tests/",
|
|
26
30
|
"typecheck": "tsc --noEmit"
|
package/src/index.ts
CHANGED
|
@@ -5,6 +5,8 @@ export { default as BrainProvider } from './brain_provider.ts'
|
|
|
5
5
|
export { brain, AgentRunner, Thread } from './helpers.ts'
|
|
6
6
|
export { Agent } from './agent.ts'
|
|
7
7
|
export { defineTool, defineToolbox } from './tool.ts'
|
|
8
|
+
export { defineMcpToolbox } from './mcp_toolbox.ts'
|
|
9
|
+
export type { McpToolboxOptions } from './mcp_toolbox.ts'
|
|
8
10
|
export { Workflow } from './workflow.ts'
|
|
9
11
|
export { AnthropicProvider } from './providers/anthropic_provider.ts'
|
|
10
12
|
export { GoogleProvider } from './providers/google_provider.ts'
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { McpClient } from '@strav/mcp'
|
|
2
|
+
import type { McpClientOptions } from '@strav/mcp'
|
|
3
|
+
import type { ToolDefinition, JsonSchema } from './types.ts'
|
|
4
|
+
|
|
5
|
+
/** Options for {@link defineMcpToolbox}. */
|
|
6
|
+
export interface McpToolboxOptions extends McpClientOptions {
|
|
7
|
+
/** Restrict the toolbox to these tool names. Default: every remote tool. */
|
|
8
|
+
only?: string[]
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Build a brain toolbox backed by a remote MCP server.
|
|
13
|
+
*
|
|
14
|
+
* Connects an {@link McpClient}, lists the server's tools, and maps each one
|
|
15
|
+
* to a brain `ToolDefinition` whose `execute` performs the remote call — so a
|
|
16
|
+
* `brain` `Agent` calls remote MCP tools exactly as it calls native ones.
|
|
17
|
+
*
|
|
18
|
+
* This is async (it must `listTools()` first), so await it at setup time:
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* const gateway = await defineMcpToolbox('gateway', {
|
|
22
|
+
* url: 'https://gateway/mcp',
|
|
23
|
+
* bearerToken: projectToken,
|
|
24
|
+
* })
|
|
25
|
+
*
|
|
26
|
+
* class BuilderAgent extends Agent {
|
|
27
|
+
* tools = gateway
|
|
28
|
+
* }
|
|
29
|
+
*/
|
|
30
|
+
export async function defineMcpToolbox(
|
|
31
|
+
name: string,
|
|
32
|
+
options: McpToolboxOptions
|
|
33
|
+
): Promise<ToolDefinition[]> {
|
|
34
|
+
const { only, ...clientOptions } = options
|
|
35
|
+
|
|
36
|
+
const client = new McpClient({
|
|
37
|
+
clientInfo: { name: `strav-brain:${name}`, version: '1.0.0' },
|
|
38
|
+
...clientOptions,
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
const tools = await client.listTools()
|
|
42
|
+
const selected = only ? tools.filter(tool => only.includes(tool.name)) : tools
|
|
43
|
+
|
|
44
|
+
return selected.map(tool => ({
|
|
45
|
+
name: tool.name,
|
|
46
|
+
description: tool.description ?? '',
|
|
47
|
+
parameters: tool.inputSchema as JsonSchema,
|
|
48
|
+
execute: async (args: Record<string, unknown>) => {
|
|
49
|
+
const result = await client.callTool(tool.name, args)
|
|
50
|
+
|
|
51
|
+
// Prefer structured output; otherwise join the text content blocks.
|
|
52
|
+
if (result.structuredContent !== undefined) {
|
|
53
|
+
return result.isError ? { error: result.structuredContent } : result.structuredContent
|
|
54
|
+
}
|
|
55
|
+
const text = (result.content ?? [])
|
|
56
|
+
.map((block: any) => (block?.type === 'text' ? String(block.text ?? '') : ''))
|
|
57
|
+
.filter(Boolean)
|
|
58
|
+
.join('\n')
|
|
59
|
+
return result.isError ? { error: text } : text
|
|
60
|
+
},
|
|
61
|
+
}))
|
|
62
|
+
}
|