Skip to content

Commit 49f3a21

Browse files
feat(mcp/ts): load MCP servers from JSON (strands-agents#2947)
1 parent 531d526 commit 49f3a21

13 files changed

Lines changed: 714 additions & 18 deletions

File tree

strands-ts/src/agent/__tests__/agent.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { describe, expect, it, vi } from 'vitest'
22
import { z } from 'zod'
33
import { Agent, type ToolList } from '../agent.js'
4-
import { McpClient } from '../../mcp.js'
4+
import { McpClient } from '../../mcp/index.js'
55
import { McpTool } from '../../tools/mcp-tool.js'
66
import { MockMessageModel } from '../../__fixtures__/mock-message-model.js'
77
import { collectGenerator } from '../../__fixtures__/model-test-helpers.js'

strands-ts/src/agent/agent.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
} from '../types/messages.js'
2626
import { deepCopy } from '../types/json.js'
2727
import type { JSONValue } from '../types/json.js'
28-
import { McpClient } from '../mcp.js'
28+
import { McpClient } from '../mcp/index.js'
2929
import { isValidToolName, type Tool, type ToolContext } from '../tools/tool.js'
3030
import type { ToolChoice, ToolSpec } from '../tools/types.js'
3131
import { cloneSystemPrompt, systemPromptFromData } from '../types/messages.js'

strands-ts/src/index.node.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
// or bundlers will tree-shake the registrations.
55
import { defaultSandbox } from './sandbox/default.js'
66
import { NotASandboxLocalEnvironment } from './sandbox/not-a-sandbox-local-environment.js'
7+
import { mcpServerLoader } from './mcp/config.js'
8+
import { resolveServerConfigs } from './mcp/config.node.js'
79

810
defaultSandbox.set(new NotASandboxLocalEnvironment())
11+
mcpServerLoader.set(resolveServerConfigs)
912

1013
export * from './index.js'

strands-ts/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,8 +282,9 @@ export {
282282
type McpCallToolOptions,
283283
type TasksConfig,
284284
type McpConnectionState,
285+
type McpServerConfig,
285286
McpClient,
286-
} from './mcp.js'
287+
} from './mcp/index.js'
287288
export type { ElicitationCallback, ElicitationContext } from './types/elicitation.js'
288289

289290
// Session management

strands-ts/src/__tests__/mcp.test.ts renamed to strands-ts/src/mcp/__tests__/client.test.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@ import {
99
} from '@modelcontextprotocol/sdk/types.js'
1010
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'
1111
import { ClientCredentialsProvider } from '@modelcontextprotocol/sdk/client/auth-extensions.js'
12-
import { McpClient } from '../mcp.js'
13-
import { McpTool } from '../tools/mcp-tool.js'
14-
import { JsonBlock, type TextBlock, type ToolResultBlock } from '../types/messages.js'
15-
import { ImageBlock } from '../types/media.js'
16-
import type { LocalAgent } from '../types/agent.js'
17-
import type { ToolContext } from '../tools/tool.js'
18-
import type { ElicitationCallback } from '../types/elicitation.js'
12+
import { McpClient } from '../client.js'
13+
import { McpTool } from '../../tools/mcp-tool.js'
14+
import { JsonBlock, type TextBlock, type ToolResultBlock } from '../../types/messages.js'
15+
import { ImageBlock } from '../../types/media.js'
16+
import type { LocalAgent } from '../../types/agent.js'
17+
import type { ToolContext } from '../../tools/tool.js'
18+
import type { ElicitationCallback } from '../../types/elicitation.js'
1919
import { context, propagation, trace, TraceFlags } from '@opentelemetry/api'
2020
import type { SpanContext } from '@opentelemetry/api'
21-
import { logger } from '../logging/index.js'
21+
import { logger } from '../../logging/index.js'
2222
import type { LoggingMessageNotificationParams } from '@modelcontextprotocol/sdk/types.js'
2323

2424
/**
@@ -64,7 +64,7 @@ vi.mock('@modelcontextprotocol/sdk/client/index.js', () => ({
6464
}),
6565
}))
6666

67-
vi.mock('../tools/tool.js', () => ({
67+
vi.mock('../../tools/tool.js', () => ({
6868
Tool: class {},
6969
createErrorResult: (err: unknown, toolUseId: string) => ({
7070
type: 'toolResultBlock',
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { describe, it, expect } from 'vitest'
2+
import { McpClient } from '../client.js'
3+
4+
// The unit-browser project has no setupFiles registering the MCP server loader,
5+
// mirroring a real browser where index.node.ts never loads.
6+
describe('McpClient.loadServers (browser)', () => {
7+
it('throws because no Node loader is registered', async () => {
8+
await expect(McpClient.loadServers({ server: { command: 'node' } })).rejects.toThrow(
9+
'McpClient.loadServers is only available in Node.js'
10+
)
11+
})
12+
})

0 commit comments

Comments
 (0)