agent-framework-js 1.0.1 → 1.1.1
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/CHANGELOG.md +20 -0
- package/README.md +1 -1
- package/dist/{chunk-U3ULJMNH.cjs → chunk-SUTW6P6O.cjs} +34 -4
- package/dist/chunk-SUTW6P6O.cjs.map +1 -0
- package/dist/{chunk-QYG4HLIC.js → chunk-YVFQNJIU.js} +34 -4
- package/dist/chunk-YVFQNJIU.js.map +1 -0
- package/dist/index.cjs +9 -9
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/mcp/index.cjs +3 -3
- package/dist/mcp/index.d.cts +32 -2
- package/dist/mcp/index.d.ts +32 -2
- package/dist/mcp/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-QYG4HLIC.js.map +0 -1
- package/dist/chunk-U3ULJMNH.cjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.1.1] - 2026-06-24
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **Re-release combining the MCP HTTP headers feature (1.1.0) with the token-usage
|
|
15
|
+
fix (1.0.1).** The published 1.1.0 was tagged before the 1.0.1 `GenerateResponse.usage`
|
|
16
|
+
fix was merged, so packages on 1.1.0 lacked real token counts. 1.1.1 ships both. No
|
|
17
|
+
source changes beyond the merge of those two lines of history.
|
|
18
|
+
|
|
19
|
+
## [1.1.0] - 2026-06-24
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- **Custom HTTP headers & secrets for remote MCP servers** (`mcp` module), matching the `mcp.json`
|
|
24
|
+
HTTP server format. The `remote` transport now accepts `headers` (static record or an async
|
|
25
|
+
callback resolved lazily at connect time, so secrets are never persisted) and an optional `type`
|
|
26
|
+
(`"http"` Streamable HTTP — the default — or `"sse"` for legacy Server-Sent Events servers).
|
|
27
|
+
Empty header values are dropped and values are redacted in logs/traces. `stdio` transport gained
|
|
28
|
+
an optional `env` for extra process environment variables.
|
|
29
|
+
|
|
10
30
|
## [1.0.1] - 2026-06-21
|
|
11
31
|
|
|
12
32
|
### Fixed
|
package/README.md
CHANGED
|
@@ -83,7 +83,7 @@ Prefer **deep imports** for the smallest bundle: `agent-framework-js/agents`,
|
|
|
83
83
|
| Agents | `agents` | text + multimodal input, streaming, reasoning field, threads with compaction |
|
|
84
84
|
| Providers | `providers` | Copilot + OpenAI-compatible; caller-injected credentials; retry/backoff |
|
|
85
85
|
| Tools | `tools` | local function tools, JSON-Schema validation, namespacing, enable/disable |
|
|
86
|
-
| MCP | `mcp` | remote (HTTP/SSE) everywhere; stdio in Node only
|
|
86
|
+
| MCP | `mcp` | remote (HTTP/SSE) with custom headers everywhere; stdio in Node only |
|
|
87
87
|
| Skills | `skills` | progressive disclosure; client-side keyword index |
|
|
88
88
|
| Workflows | `workflows` | sequential / concurrent / handoff / group; HITL; checkpoints |
|
|
89
89
|
| Middleware | `middleware` | request/response pipeline |
|
|
@@ -23,17 +23,47 @@ function mcpToolToTool(serverId, def, client) {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
// src/mcp/connection.ts
|
|
26
|
+
async function resolveHeaders(headers) {
|
|
27
|
+
if (!headers) return void 0;
|
|
28
|
+
const resolved = typeof headers === "function" ? await headers() : headers;
|
|
29
|
+
const entries = Object.entries(resolved).filter(
|
|
30
|
+
([, v]) => v != null && v !== ""
|
|
31
|
+
);
|
|
32
|
+
return entries.length ? Object.fromEntries(entries) : void 0;
|
|
33
|
+
}
|
|
34
|
+
function headerEventSourceInit(headers) {
|
|
35
|
+
return {
|
|
36
|
+
fetch: (url, init) => fetch(url, {
|
|
37
|
+
...init,
|
|
38
|
+
headers: { ...init?.headers, ...headers }
|
|
39
|
+
})
|
|
40
|
+
};
|
|
41
|
+
}
|
|
26
42
|
async function createTransport(config) {
|
|
27
43
|
if (config.transport.kind === "stdio") {
|
|
28
44
|
chunkN64ZFATA_cjs.requireCapability("canSpawnProcess", "MCP stdio transport");
|
|
29
45
|
const { StdioClientTransport } = await import('@modelcontextprotocol/sdk/client/stdio.js');
|
|
30
46
|
return new StdioClientTransport({
|
|
31
47
|
command: config.transport.command,
|
|
32
|
-
args: config.transport.args ?? []
|
|
48
|
+
args: config.transport.args ?? [],
|
|
49
|
+
...config.transport.env ? { env: config.transport.env } : {}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
const headers = await resolveHeaders(config.transport.headers);
|
|
53
|
+
const url = new URL(config.transport.url);
|
|
54
|
+
if (config.transport.type === "sse") {
|
|
55
|
+
const { SSEClientTransport } = await import('@modelcontextprotocol/sdk/client/sse.js');
|
|
56
|
+
return new SSEClientTransport(url, {
|
|
57
|
+
...headers ? {
|
|
58
|
+
requestInit: { headers },
|
|
59
|
+
eventSourceInit: headerEventSourceInit(headers)
|
|
60
|
+
} : {}
|
|
33
61
|
});
|
|
34
62
|
}
|
|
35
63
|
const { StreamableHTTPClientTransport } = await import('@modelcontextprotocol/sdk/client/streamableHttp.js');
|
|
36
|
-
return new StreamableHTTPClientTransport(
|
|
64
|
+
return new StreamableHTTPClientTransport(url, {
|
|
65
|
+
...headers ? { requestInit: { headers } } : {}
|
|
66
|
+
});
|
|
37
67
|
}
|
|
38
68
|
async function connectMCP(config) {
|
|
39
69
|
let client;
|
|
@@ -68,5 +98,5 @@ async function connectMCP(config) {
|
|
|
68
98
|
|
|
69
99
|
exports.connectMCP = connectMCP;
|
|
70
100
|
exports.mcpToolToTool = mcpToolToTool;
|
|
71
|
-
//# sourceMappingURL=chunk-
|
|
72
|
-
//# sourceMappingURL=chunk-
|
|
101
|
+
//# sourceMappingURL=chunk-SUTW6P6O.cjs.map
|
|
102
|
+
//# sourceMappingURL=chunk-SUTW6P6O.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/mcp/adapter.ts","../src/mcp/connection.ts"],"names":["MCPError","requireCapability"],"mappings":"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","file":"chunk-SUTW6P6O.cjs","sourcesContent":["/**\n * Adapts MCP-provided tools onto the framework's uniform {@link Tool} contract,\n * namespaced by the connection id so collisions are impossible. (FR-014, FR-014a)\n *\n * @packageDocumentation\n */\n\nimport type { Tool } from \"../tools/tool.js\";\nimport { MCPError } from \"../core/errors.js\";\n\ninterface MCPToolDef {\n\tname: string;\n\tdescription?: string;\n\tinputSchema: Record<string, unknown>;\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * Wrap an MCP tool definition as a framework tool. Invocation calls back through\n * the MCP client; failures surface as typed {@link MCPError}/tool errors.\n */\nexport function mcpToolToTool(serverId: string, def: MCPToolDef, client: any): Tool {\n\treturn {\n\t\tname: def.name,\n\t\tdescription: def.description ?? \"\",\n\t\tinputSchema: def.inputSchema,\n\t\tsource: serverId,\n\t\tenabled: true,\n\t\tasync run(args: unknown): Promise<unknown> {\n\t\t\ttry {\n\t\t\t\tconst result = await client.callTool({ name: def.name, arguments: args });\n\t\t\t\treturn result.content ?? result;\n\t\t\t} catch (e) {\n\t\t\t\tthrow new MCPError(`MCP tool \"${def.name}\" failed: ${(e as Error).message}`, serverId);\n\t\t\t}\n\t\t},\n\t};\n}\n","/**\n * MCP (Model Context Protocol) integration. Connects to MCP servers and exposes\n * their tools through the framework's uniform tool interface.\n *\n * Remote transport (HTTP/SSE) works in all runtimes; stdio (spawning a server\n * process) works only where process spawning is permitted (Node). Requesting\n * stdio elsewhere throws a typed {@link RuntimeUnsupportedError}. (FR-013, FR-013a,\n * FR-013b, FR-030a)\n *\n * The `@modelcontextprotocol/sdk` package is an optional peer dependency and is\n * loaded lazily so browser bundles that do not use MCP pay no cost.\n *\n * @packageDocumentation\n */\n\nimport { MCPError } from \"../core/errors.js\";\nimport { requireCapability } from \"../core/runtime.js\";\nimport type { Tool } from \"../tools/tool.js\";\nimport { mcpToolToTool } from \"./adapter.js\";\n\n/**\n * Custom HTTP headers for a remote MCP connection. Mirrors the `headers` object\n * of an `mcp.json` HTTP server entry and is the standard way to pass secrets\n * such as `Authorization: Bearer …` or `X-API-Key` tokens.\n *\n * It may be a static record or a (possibly async) callback that returns the\n * headers. The callback form keeps the security model intact: secrets are\n * resolved lazily at connect time (e.g. minting a fresh bearer token) and are\n * never persisted on the config object. Empty/`null`/`undefined` values are\n * dropped so blank auth headers are never sent.\n */\nexport type MCPHeaders =\n\t| Record<string, string>\n\t| (() => Record<string, string> | Promise<Record<string, string>>);\n\n/** Transport options for an MCP connection. */\nexport type MCPTransport =\n\t| {\n\t\t\tkind: \"remote\";\n\t\t\turl: string;\n\t\t\t/**\n\t\t\t * Wire transport for the remote endpoint. Defaults to `\"http\"`\n\t\t\t * (Streamable HTTP, the `\"http\"`/`\"streamable-http\"` type in `mcp.json`).\n\t\t\t * Use `\"sse\"` for legacy Server-Sent Events servers. (FR-013a)\n\t\t\t */\n\t\t\ttype?: \"http\" | \"sse\";\n\t\t\t/** Custom request headers (auth tokens, API keys, content versions, …). */\n\t\t\theaders?: MCPHeaders;\n\t }\n\t| {\n\t\t\tkind: \"stdio\";\n\t\t\tcommand: string;\n\t\t\targs?: string[];\n\t\t\t/** Extra environment variables for the spawned server process. */\n\t\t\tenv?: Record<string, string>;\n\t };\n\n/** Configuration for connecting to an MCP server. */\nexport interface MCPConnectionConfig {\n\t/** Connection id; becomes the namespace prefix for discovered tools. (FR-014a) */\n\tid: string;\n\ttransport: MCPTransport;\n\t/** Whether the connection's tools are enabled. Defaults to true. */\n\tenabled?: boolean;\n}\n\n/** A live connection to an MCP server. */\nexport interface MCPConnection {\n\treadonly id: string;\n\tconnect(): Promise<void>;\n\tlistTools(): Promise<Tool[]>;\n\tclose(): Promise<void>;\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\ntype AnyClient = any;\n\n/**\n * Resolve {@link MCPHeaders} into a plain record at connect time, invoking the\n * callback form if provided and stripping empty values so we never transmit a\n * blank `Authorization`/`X-API-Key` header. Returns `undefined` when there are\n * no usable headers so the transport is constructed without a `requestInit`.\n */\nasync function resolveHeaders(\n\theaders?: MCPHeaders,\n): Promise<Record<string, string> | undefined> {\n\tif (!headers) return undefined;\n\tconst resolved = typeof headers === \"function\" ? await headers() : headers;\n\tconst entries = Object.entries(resolved).filter(\n\t\t([, v]) => v != null && v !== \"\",\n\t);\n\treturn entries.length ? Object.fromEntries(entries) : undefined;\n}\n\n/**\n * Build an `EventSourceInit` that injects custom headers onto the initial SSE\n * stream request. The legacy SSE transport only attaches `requestInit` headers\n * to the follow-up POST messages, so without this the auth header would be\n * missing from the GET that opens the stream.\n */\nfunction headerEventSourceInit(headers: Record<string, string>): {\n\tfetch: (url: string | URL, init?: RequestInit) => Promise<Response>;\n} {\n\treturn {\n\t\tfetch: (url, init) =>\n\t\t\tfetch(url, {\n\t\t\t\t...init,\n\t\t\t\theaders: { ...(init?.headers as Record<string, string>), ...headers },\n\t\t\t}),\n\t};\n}\n\nasync function createTransport(config: MCPConnectionConfig): Promise<AnyClient> {\n\tif (config.transport.kind === \"stdio\") {\n\t\t// Gate on runtime capability before attempting to spawn. (FR-013b, FR-030a)\n\t\trequireCapability(\"canSpawnProcess\", \"MCP stdio transport\");\n\t\tconst { StdioClientTransport } = await import(\n\t\t\t\"@modelcontextprotocol/sdk/client/stdio.js\"\n\t\t);\n\t\treturn new StdioClientTransport({\n\t\t\tcommand: config.transport.command,\n\t\t\targs: config.transport.args ?? [],\n\t\t\t...(config.transport.env ? { env: config.transport.env } : {}),\n\t\t});\n\t}\n\n\tconst headers = await resolveHeaders(config.transport.headers);\n\tconst url = new URL(config.transport.url);\n\n\t// Legacy Server-Sent Events transport. (FR-013a)\n\tif (config.transport.type === \"sse\") {\n\t\tconst { SSEClientTransport } = await import(\n\t\t\t\"@modelcontextprotocol/sdk/client/sse.js\"\n\t\t);\n\t\treturn new SSEClientTransport(url, {\n\t\t\t...(headers\n\t\t\t\t? {\n\t\t\t\t\t\trequestInit: { headers },\n\t\t\t\t\t\teventSourceInit: headerEventSourceInit(headers),\n\t\t\t\t }\n\t\t\t\t: {}),\n\t\t});\n\t}\n\n\t// Default: Streamable HTTP (the \"http\"/\"streamable-http\" type in mcp.json).\n\tconst { StreamableHTTPClientTransport } = await import(\n\t\t\"@modelcontextprotocol/sdk/client/streamableHttp.js\"\n\t);\n\treturn new StreamableHTTPClientTransport(url, {\n\t\t...(headers ? { requestInit: { headers } } : {}),\n\t});\n}\n\n/**\n * Connect to an MCP server.\n *\n * @example\n * ```ts\n * // Remote HTTP server with bearer auth (mirrors an mcp.json HTTP entry).\n * const mcp = await connectMCP({\n * id: \"docs\",\n * transport: {\n * kind: \"remote\",\n * url: \"https://api.example.com/mcp\",\n * headers: { Authorization: \"Bearer your-api-token-here\" },\n * },\n * });\n * const tools = await mcp.listTools(); // namespaced as docs.<tool>\n * ```\n */\nexport async function connectMCP(config: MCPConnectionConfig): Promise<MCPConnection> {\n\tlet client: AnyClient | undefined;\n\n\tasync function connect(): Promise<void> {\n\t\ttry {\n\t\t\tconst { Client } = await import(\"@modelcontextprotocol/sdk/client/index.js\");\n\t\t\tconst transport = await createTransport(config);\n\t\t\tclient = new Client({ name: \"agent-framework-js\", version: \"0.1.0\" }, { capabilities: {} });\n\t\t\tawait client.connect(transport);\n\t\t} catch (e) {\n\t\t\t// Preserve typed runtime errors; wrap everything else as an MCP error.\n\t\t\tif ((e as Error).name === \"RuntimeUnsupportedError\") throw e;\n\t\t\tthrow new MCPError(`Failed to connect to MCP server: ${(e as Error).message}`, config.id);\n\t\t}\n\t}\n\n\tasync function listTools(): Promise<Tool[]> {\n\t\tif (!client) throw new MCPError(\"Not connected\", config.id);\n\t\ttry {\n\t\t\tconst result = await client.listTools();\n\t\t\treturn (result.tools ?? []).map((t: { name: string; description?: string; inputSchema: Record<string, unknown> }) =>\n\t\t\t\tmcpToolToTool(config.id, t, client),\n\t\t\t);\n\t\t} catch (e) {\n\t\t\tthrow new MCPError(`Failed to list tools: ${(e as Error).message}`, config.id);\n\t\t}\n\t}\n\n\tasync function close(): Promise<void> {\n\t\tawait client?.close?.();\n\t\tclient = undefined;\n\t}\n\n\treturn { id: config.id, connect, listTools, close };\n}\n"]}
|
|
@@ -21,17 +21,47 @@ function mcpToolToTool(serverId, def, client) {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
// src/mcp/connection.ts
|
|
24
|
+
async function resolveHeaders(headers) {
|
|
25
|
+
if (!headers) return void 0;
|
|
26
|
+
const resolved = typeof headers === "function" ? await headers() : headers;
|
|
27
|
+
const entries = Object.entries(resolved).filter(
|
|
28
|
+
([, v]) => v != null && v !== ""
|
|
29
|
+
);
|
|
30
|
+
return entries.length ? Object.fromEntries(entries) : void 0;
|
|
31
|
+
}
|
|
32
|
+
function headerEventSourceInit(headers) {
|
|
33
|
+
return {
|
|
34
|
+
fetch: (url, init) => fetch(url, {
|
|
35
|
+
...init,
|
|
36
|
+
headers: { ...init?.headers, ...headers }
|
|
37
|
+
})
|
|
38
|
+
};
|
|
39
|
+
}
|
|
24
40
|
async function createTransport(config) {
|
|
25
41
|
if (config.transport.kind === "stdio") {
|
|
26
42
|
requireCapability("canSpawnProcess", "MCP stdio transport");
|
|
27
43
|
const { StdioClientTransport } = await import('@modelcontextprotocol/sdk/client/stdio.js');
|
|
28
44
|
return new StdioClientTransport({
|
|
29
45
|
command: config.transport.command,
|
|
30
|
-
args: config.transport.args ?? []
|
|
46
|
+
args: config.transport.args ?? [],
|
|
47
|
+
...config.transport.env ? { env: config.transport.env } : {}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
const headers = await resolveHeaders(config.transport.headers);
|
|
51
|
+
const url = new URL(config.transport.url);
|
|
52
|
+
if (config.transport.type === "sse") {
|
|
53
|
+
const { SSEClientTransport } = await import('@modelcontextprotocol/sdk/client/sse.js');
|
|
54
|
+
return new SSEClientTransport(url, {
|
|
55
|
+
...headers ? {
|
|
56
|
+
requestInit: { headers },
|
|
57
|
+
eventSourceInit: headerEventSourceInit(headers)
|
|
58
|
+
} : {}
|
|
31
59
|
});
|
|
32
60
|
}
|
|
33
61
|
const { StreamableHTTPClientTransport } = await import('@modelcontextprotocol/sdk/client/streamableHttp.js');
|
|
34
|
-
return new StreamableHTTPClientTransport(
|
|
62
|
+
return new StreamableHTTPClientTransport(url, {
|
|
63
|
+
...headers ? { requestInit: { headers } } : {}
|
|
64
|
+
});
|
|
35
65
|
}
|
|
36
66
|
async function connectMCP(config) {
|
|
37
67
|
let client;
|
|
@@ -65,5 +95,5 @@ async function connectMCP(config) {
|
|
|
65
95
|
}
|
|
66
96
|
|
|
67
97
|
export { connectMCP, mcpToolToTool };
|
|
68
|
-
//# sourceMappingURL=chunk-
|
|
69
|
-
//# sourceMappingURL=chunk-
|
|
98
|
+
//# sourceMappingURL=chunk-YVFQNJIU.js.map
|
|
99
|
+
//# sourceMappingURL=chunk-YVFQNJIU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/mcp/adapter.ts","../src/mcp/connection.ts"],"names":[],"mappings":"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","file":"chunk-YVFQNJIU.js","sourcesContent":["/**\n * Adapts MCP-provided tools onto the framework's uniform {@link Tool} contract,\n * namespaced by the connection id so collisions are impossible. (FR-014, FR-014a)\n *\n * @packageDocumentation\n */\n\nimport type { Tool } from \"../tools/tool.js\";\nimport { MCPError } from \"../core/errors.js\";\n\ninterface MCPToolDef {\n\tname: string;\n\tdescription?: string;\n\tinputSchema: Record<string, unknown>;\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * Wrap an MCP tool definition as a framework tool. Invocation calls back through\n * the MCP client; failures surface as typed {@link MCPError}/tool errors.\n */\nexport function mcpToolToTool(serverId: string, def: MCPToolDef, client: any): Tool {\n\treturn {\n\t\tname: def.name,\n\t\tdescription: def.description ?? \"\",\n\t\tinputSchema: def.inputSchema,\n\t\tsource: serverId,\n\t\tenabled: true,\n\t\tasync run(args: unknown): Promise<unknown> {\n\t\t\ttry {\n\t\t\t\tconst result = await client.callTool({ name: def.name, arguments: args });\n\t\t\t\treturn result.content ?? result;\n\t\t\t} catch (e) {\n\t\t\t\tthrow new MCPError(`MCP tool \"${def.name}\" failed: ${(e as Error).message}`, serverId);\n\t\t\t}\n\t\t},\n\t};\n}\n","/**\n * MCP (Model Context Protocol) integration. Connects to MCP servers and exposes\n * their tools through the framework's uniform tool interface.\n *\n * Remote transport (HTTP/SSE) works in all runtimes; stdio (spawning a server\n * process) works only where process spawning is permitted (Node). Requesting\n * stdio elsewhere throws a typed {@link RuntimeUnsupportedError}. (FR-013, FR-013a,\n * FR-013b, FR-030a)\n *\n * The `@modelcontextprotocol/sdk` package is an optional peer dependency and is\n * loaded lazily so browser bundles that do not use MCP pay no cost.\n *\n * @packageDocumentation\n */\n\nimport { MCPError } from \"../core/errors.js\";\nimport { requireCapability } from \"../core/runtime.js\";\nimport type { Tool } from \"../tools/tool.js\";\nimport { mcpToolToTool } from \"./adapter.js\";\n\n/**\n * Custom HTTP headers for a remote MCP connection. Mirrors the `headers` object\n * of an `mcp.json` HTTP server entry and is the standard way to pass secrets\n * such as `Authorization: Bearer …` or `X-API-Key` tokens.\n *\n * It may be a static record or a (possibly async) callback that returns the\n * headers. The callback form keeps the security model intact: secrets are\n * resolved lazily at connect time (e.g. minting a fresh bearer token) and are\n * never persisted on the config object. Empty/`null`/`undefined` values are\n * dropped so blank auth headers are never sent.\n */\nexport type MCPHeaders =\n\t| Record<string, string>\n\t| (() => Record<string, string> | Promise<Record<string, string>>);\n\n/** Transport options for an MCP connection. */\nexport type MCPTransport =\n\t| {\n\t\t\tkind: \"remote\";\n\t\t\turl: string;\n\t\t\t/**\n\t\t\t * Wire transport for the remote endpoint. Defaults to `\"http\"`\n\t\t\t * (Streamable HTTP, the `\"http\"`/`\"streamable-http\"` type in `mcp.json`).\n\t\t\t * Use `\"sse\"` for legacy Server-Sent Events servers. (FR-013a)\n\t\t\t */\n\t\t\ttype?: \"http\" | \"sse\";\n\t\t\t/** Custom request headers (auth tokens, API keys, content versions, …). */\n\t\t\theaders?: MCPHeaders;\n\t }\n\t| {\n\t\t\tkind: \"stdio\";\n\t\t\tcommand: string;\n\t\t\targs?: string[];\n\t\t\t/** Extra environment variables for the spawned server process. */\n\t\t\tenv?: Record<string, string>;\n\t };\n\n/** Configuration for connecting to an MCP server. */\nexport interface MCPConnectionConfig {\n\t/** Connection id; becomes the namespace prefix for discovered tools. (FR-014a) */\n\tid: string;\n\ttransport: MCPTransport;\n\t/** Whether the connection's tools are enabled. Defaults to true. */\n\tenabled?: boolean;\n}\n\n/** A live connection to an MCP server. */\nexport interface MCPConnection {\n\treadonly id: string;\n\tconnect(): Promise<void>;\n\tlistTools(): Promise<Tool[]>;\n\tclose(): Promise<void>;\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\ntype AnyClient = any;\n\n/**\n * Resolve {@link MCPHeaders} into a plain record at connect time, invoking the\n * callback form if provided and stripping empty values so we never transmit a\n * blank `Authorization`/`X-API-Key` header. Returns `undefined` when there are\n * no usable headers so the transport is constructed without a `requestInit`.\n */\nasync function resolveHeaders(\n\theaders?: MCPHeaders,\n): Promise<Record<string, string> | undefined> {\n\tif (!headers) return undefined;\n\tconst resolved = typeof headers === \"function\" ? await headers() : headers;\n\tconst entries = Object.entries(resolved).filter(\n\t\t([, v]) => v != null && v !== \"\",\n\t);\n\treturn entries.length ? Object.fromEntries(entries) : undefined;\n}\n\n/**\n * Build an `EventSourceInit` that injects custom headers onto the initial SSE\n * stream request. The legacy SSE transport only attaches `requestInit` headers\n * to the follow-up POST messages, so without this the auth header would be\n * missing from the GET that opens the stream.\n */\nfunction headerEventSourceInit(headers: Record<string, string>): {\n\tfetch: (url: string | URL, init?: RequestInit) => Promise<Response>;\n} {\n\treturn {\n\t\tfetch: (url, init) =>\n\t\t\tfetch(url, {\n\t\t\t\t...init,\n\t\t\t\theaders: { ...(init?.headers as Record<string, string>), ...headers },\n\t\t\t}),\n\t};\n}\n\nasync function createTransport(config: MCPConnectionConfig): Promise<AnyClient> {\n\tif (config.transport.kind === \"stdio\") {\n\t\t// Gate on runtime capability before attempting to spawn. (FR-013b, FR-030a)\n\t\trequireCapability(\"canSpawnProcess\", \"MCP stdio transport\");\n\t\tconst { StdioClientTransport } = await import(\n\t\t\t\"@modelcontextprotocol/sdk/client/stdio.js\"\n\t\t);\n\t\treturn new StdioClientTransport({\n\t\t\tcommand: config.transport.command,\n\t\t\targs: config.transport.args ?? [],\n\t\t\t...(config.transport.env ? { env: config.transport.env } : {}),\n\t\t});\n\t}\n\n\tconst headers = await resolveHeaders(config.transport.headers);\n\tconst url = new URL(config.transport.url);\n\n\t// Legacy Server-Sent Events transport. (FR-013a)\n\tif (config.transport.type === \"sse\") {\n\t\tconst { SSEClientTransport } = await import(\n\t\t\t\"@modelcontextprotocol/sdk/client/sse.js\"\n\t\t);\n\t\treturn new SSEClientTransport(url, {\n\t\t\t...(headers\n\t\t\t\t? {\n\t\t\t\t\t\trequestInit: { headers },\n\t\t\t\t\t\teventSourceInit: headerEventSourceInit(headers),\n\t\t\t\t }\n\t\t\t\t: {}),\n\t\t});\n\t}\n\n\t// Default: Streamable HTTP (the \"http\"/\"streamable-http\" type in mcp.json).\n\tconst { StreamableHTTPClientTransport } = await import(\n\t\t\"@modelcontextprotocol/sdk/client/streamableHttp.js\"\n\t);\n\treturn new StreamableHTTPClientTransport(url, {\n\t\t...(headers ? { requestInit: { headers } } : {}),\n\t});\n}\n\n/**\n * Connect to an MCP server.\n *\n * @example\n * ```ts\n * // Remote HTTP server with bearer auth (mirrors an mcp.json HTTP entry).\n * const mcp = await connectMCP({\n * id: \"docs\",\n * transport: {\n * kind: \"remote\",\n * url: \"https://api.example.com/mcp\",\n * headers: { Authorization: \"Bearer your-api-token-here\" },\n * },\n * });\n * const tools = await mcp.listTools(); // namespaced as docs.<tool>\n * ```\n */\nexport async function connectMCP(config: MCPConnectionConfig): Promise<MCPConnection> {\n\tlet client: AnyClient | undefined;\n\n\tasync function connect(): Promise<void> {\n\t\ttry {\n\t\t\tconst { Client } = await import(\"@modelcontextprotocol/sdk/client/index.js\");\n\t\t\tconst transport = await createTransport(config);\n\t\t\tclient = new Client({ name: \"agent-framework-js\", version: \"0.1.0\" }, { capabilities: {} });\n\t\t\tawait client.connect(transport);\n\t\t} catch (e) {\n\t\t\t// Preserve typed runtime errors; wrap everything else as an MCP error.\n\t\t\tif ((e as Error).name === \"RuntimeUnsupportedError\") throw e;\n\t\t\tthrow new MCPError(`Failed to connect to MCP server: ${(e as Error).message}`, config.id);\n\t\t}\n\t}\n\n\tasync function listTools(): Promise<Tool[]> {\n\t\tif (!client) throw new MCPError(\"Not connected\", config.id);\n\t\ttry {\n\t\t\tconst result = await client.listTools();\n\t\t\treturn (result.tools ?? []).map((t: { name: string; description?: string; inputSchema: Record<string, unknown> }) =>\n\t\t\t\tmcpToolToTool(config.id, t, client),\n\t\t\t);\n\t\t} catch (e) {\n\t\t\tthrow new MCPError(`Failed to list tools: ${(e as Error).message}`, config.id);\n\t\t}\n\t}\n\n\tasync function close(): Promise<void> {\n\t\tawait client?.close?.();\n\t\tclient = undefined;\n\t}\n\n\treturn { id: config.id, connect, listTools, close };\n}\n"]}
|
package/dist/index.cjs
CHANGED
|
@@ -7,9 +7,9 @@ var chunkJ2YO7BBV_cjs = require('./chunk-J2YO7BBV.cjs');
|
|
|
7
7
|
var chunkYKSNVWGX_cjs = require('./chunk-YKSNVWGX.cjs');
|
|
8
8
|
var chunkWSMYH2IN_cjs = require('./chunk-WSMYH2IN.cjs');
|
|
9
9
|
var chunkTAMJ5HSR_cjs = require('./chunk-TAMJ5HSR.cjs');
|
|
10
|
-
var chunkU3ULJMNH_cjs = require('./chunk-U3ULJMNH.cjs');
|
|
11
10
|
var chunkKEI3EALJ_cjs = require('./chunk-KEI3EALJ.cjs');
|
|
12
11
|
var chunkFSDMBWQV_cjs = require('./chunk-FSDMBWQV.cjs');
|
|
12
|
+
var chunkSUTW6P6O_cjs = require('./chunk-SUTW6P6O.cjs');
|
|
13
13
|
var chunkV6O6SYAN_cjs = require('./chunk-V6O6SYAN.cjs');
|
|
14
14
|
var chunk5KC6X2T5_cjs = require('./chunk-5KC6X2T5.cjs');
|
|
15
15
|
var chunkI55OVD23_cjs = require('./chunk-I55OVD23.cjs');
|
|
@@ -104,14 +104,6 @@ Object.defineProperty(exports, "validateArgs", {
|
|
|
104
104
|
enumerable: true,
|
|
105
105
|
get: function () { return chunkTAMJ5HSR_cjs.validateArgs; }
|
|
106
106
|
});
|
|
107
|
-
Object.defineProperty(exports, "connectMCP", {
|
|
108
|
-
enumerable: true,
|
|
109
|
-
get: function () { return chunkU3ULJMNH_cjs.connectMCP; }
|
|
110
|
-
});
|
|
111
|
-
Object.defineProperty(exports, "mcpToolToTool", {
|
|
112
|
-
enumerable: true,
|
|
113
|
-
get: function () { return chunkU3ULJMNH_cjs.mcpToolToTool; }
|
|
114
|
-
});
|
|
115
107
|
Object.defineProperty(exports, "useMiddleware", {
|
|
116
108
|
enumerable: true,
|
|
117
109
|
get: function () { return chunkKEI3EALJ_cjs.useMiddleware; }
|
|
@@ -120,6 +112,14 @@ Object.defineProperty(exports, "composeMiddleware", {
|
|
|
120
112
|
enumerable: true,
|
|
121
113
|
get: function () { return chunkFSDMBWQV_cjs.composeMiddleware; }
|
|
122
114
|
});
|
|
115
|
+
Object.defineProperty(exports, "connectMCP", {
|
|
116
|
+
enumerable: true,
|
|
117
|
+
get: function () { return chunkSUTW6P6O_cjs.connectMCP; }
|
|
118
|
+
});
|
|
119
|
+
Object.defineProperty(exports, "mcpToolToTool", {
|
|
120
|
+
enumerable: true,
|
|
121
|
+
get: function () { return chunkSUTW6P6O_cjs.mcpToolToTool; }
|
|
122
|
+
});
|
|
123
123
|
Object.defineProperty(exports, "configureObservability", {
|
|
124
124
|
enumerable: true,
|
|
125
125
|
get: function () { return chunkV6O6SYAN_cjs.configureObservability; }
|
package/dist/index.d.cts
CHANGED
|
@@ -8,7 +8,7 @@ export { validateArgs } from './tools/index.cjs';
|
|
|
8
8
|
export { T as ToolRegistry, a as ToolResult, n as namespacedName } from './registry-BCkSIe0E.cjs';
|
|
9
9
|
export { A as Agent, a as AgentConfig, b as AgentInput, G as GenerateFn, L as LoopOptions, c as LoopResult, M as Middleware, d as MiddlewareContext, N as Next, R as RunChunk, e as RunOptions, f as RunResult, g as RunStatus, h as buildMessages, i as composeMiddleware, j as createAgent, r as runLoop } from './index-b1oTo3Lv.cjs';
|
|
10
10
|
export { T as Thread, a as ThreadOptions, e as estimateTokens } from './thread-BzwE1OnJ.cjs';
|
|
11
|
-
export { MCPConnection, MCPConnectionConfig, MCPTransport, connectMCP, mcpToolToTool } from './mcp/index.cjs';
|
|
11
|
+
export { MCPConnection, MCPConnectionConfig, MCPHeaders, MCPTransport, connectMCP, mcpToolToTool } from './mcp/index.cjs';
|
|
12
12
|
export { SkillIndex } from './skills/index.cjs';
|
|
13
13
|
export { BranchResult, CHECKPOINT_VERSION, Checkpoint, FailurePolicy, PatternHooks, StepResult, Workflow, WorkflowConfig, WorkflowContext, WorkflowEvent, WorkflowPattern, WorkflowState, WorkflowStatus, createCheckpoint, createWorkflow, restoreCheckpoint, runBounded, serializeCheckpoint, stepConcurrent, stepGroup, stepHandoff, stepSequential } from './workflows/index.cjs';
|
|
14
14
|
export { useMiddleware } from './middleware/index.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export { validateArgs } from './tools/index.js';
|
|
|
8
8
|
export { T as ToolRegistry, a as ToolResult, n as namespacedName } from './registry-D-CmT0gk.js';
|
|
9
9
|
export { A as Agent, a as AgentConfig, b as AgentInput, G as GenerateFn, L as LoopOptions, c as LoopResult, M as Middleware, d as MiddlewareContext, N as Next, R as RunChunk, e as RunOptions, f as RunResult, g as RunStatus, h as buildMessages, i as composeMiddleware, j as createAgent, r as runLoop } from './index-C22fqyZQ.js';
|
|
10
10
|
export { T as Thread, a as ThreadOptions, e as estimateTokens } from './thread-COljUAtD.js';
|
|
11
|
-
export { MCPConnection, MCPConnectionConfig, MCPTransport, connectMCP, mcpToolToTool } from './mcp/index.js';
|
|
11
|
+
export { MCPConnection, MCPConnectionConfig, MCPHeaders, MCPTransport, connectMCP, mcpToolToTool } from './mcp/index.js';
|
|
12
12
|
export { SkillIndex } from './skills/index.js';
|
|
13
13
|
export { BranchResult, CHECKPOINT_VERSION, Checkpoint, FailurePolicy, PatternHooks, StepResult, Workflow, WorkflowConfig, WorkflowContext, WorkflowEvent, WorkflowPattern, WorkflowState, WorkflowStatus, createCheckpoint, createWorkflow, restoreCheckpoint, runBounded, serializeCheckpoint, stepConcurrent, stepGroup, stepHandoff, stepSequential } from './workflows/index.js';
|
|
14
14
|
export { useMiddleware } from './middleware/index.js';
|
package/dist/index.js
CHANGED
|
@@ -5,9 +5,9 @@ export { loadAgentDefinition } from './chunk-DZFJ5MIF.js';
|
|
|
5
5
|
export { buildMessages, createAgent, runLoop } from './chunk-IEX6XUZV.js';
|
|
6
6
|
export { SkillIndex, defineSkill, loadSource } from './chunk-YCBDEEAV.js';
|
|
7
7
|
export { ToolRegistry, namespacedName, validateArgs } from './chunk-HGEPXJDG.js';
|
|
8
|
-
export { connectMCP, mcpToolToTool } from './chunk-QYG4HLIC.js';
|
|
9
8
|
export { useMiddleware } from './chunk-IUKD54F7.js';
|
|
10
9
|
export { composeMiddleware } from './chunk-7ZXUIHLH.js';
|
|
10
|
+
export { connectMCP, mcpToolToTool } from './chunk-YVFQNJIU.js';
|
|
11
11
|
export { configureObservability, isObservabilityEnabled, resetObservability, withSpan } from './chunk-5PDJOBTD.js';
|
|
12
12
|
export { ThreadPersistence, createBrowserStore, createMemoryStore } from './chunk-3KU76DCP.js';
|
|
13
13
|
export { Thread, estimateTokens, hasImage, messageText, textMessage } from './chunk-LC54DGGR.js';
|
package/dist/mcp/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkSUTW6P6O_cjs = require('../chunk-SUTW6P6O.cjs');
|
|
4
4
|
require('../chunk-N64ZFATA.cjs');
|
|
5
5
|
require('../chunk-MQ2XTH3S.cjs');
|
|
6
6
|
require('../chunk-IJASUMIQ.cjs');
|
|
@@ -9,11 +9,11 @@ require('../chunk-IJASUMIQ.cjs');
|
|
|
9
9
|
|
|
10
10
|
Object.defineProperty(exports, "connectMCP", {
|
|
11
11
|
enumerable: true,
|
|
12
|
-
get: function () { return
|
|
12
|
+
get: function () { return chunkSUTW6P6O_cjs.connectMCP; }
|
|
13
13
|
});
|
|
14
14
|
Object.defineProperty(exports, "mcpToolToTool", {
|
|
15
15
|
enumerable: true,
|
|
16
|
-
get: function () { return
|
|
16
|
+
get: function () { return chunkSUTW6P6O_cjs.mcpToolToTool; }
|
|
17
17
|
});
|
|
18
18
|
//# sourceMappingURL=index.cjs.map
|
|
19
19
|
//# sourceMappingURL=index.cjs.map
|
package/dist/mcp/index.d.cts
CHANGED
|
@@ -16,14 +16,36 @@ import '../types-AlvjoTyS.cjs';
|
|
|
16
16
|
* @packageDocumentation
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Custom HTTP headers for a remote MCP connection. Mirrors the `headers` object
|
|
21
|
+
* of an `mcp.json` HTTP server entry and is the standard way to pass secrets
|
|
22
|
+
* such as `Authorization: Bearer …` or `X-API-Key` tokens.
|
|
23
|
+
*
|
|
24
|
+
* It may be a static record or a (possibly async) callback that returns the
|
|
25
|
+
* headers. The callback form keeps the security model intact: secrets are
|
|
26
|
+
* resolved lazily at connect time (e.g. minting a fresh bearer token) and are
|
|
27
|
+
* never persisted on the config object. Empty/`null`/`undefined` values are
|
|
28
|
+
* dropped so blank auth headers are never sent.
|
|
29
|
+
*/
|
|
30
|
+
type MCPHeaders = Record<string, string> | (() => Record<string, string> | Promise<Record<string, string>>);
|
|
19
31
|
/** Transport options for an MCP connection. */
|
|
20
32
|
type MCPTransport = {
|
|
21
33
|
kind: "remote";
|
|
22
34
|
url: string;
|
|
35
|
+
/**
|
|
36
|
+
* Wire transport for the remote endpoint. Defaults to `"http"`
|
|
37
|
+
* (Streamable HTTP, the `"http"`/`"streamable-http"` type in `mcp.json`).
|
|
38
|
+
* Use `"sse"` for legacy Server-Sent Events servers. (FR-013a)
|
|
39
|
+
*/
|
|
40
|
+
type?: "http" | "sse";
|
|
41
|
+
/** Custom request headers (auth tokens, API keys, content versions, …). */
|
|
42
|
+
headers?: MCPHeaders;
|
|
23
43
|
} | {
|
|
24
44
|
kind: "stdio";
|
|
25
45
|
command: string;
|
|
26
46
|
args?: string[];
|
|
47
|
+
/** Extra environment variables for the spawned server process. */
|
|
48
|
+
env?: Record<string, string>;
|
|
27
49
|
};
|
|
28
50
|
/** Configuration for connecting to an MCP server. */
|
|
29
51
|
interface MCPConnectionConfig {
|
|
@@ -45,7 +67,15 @@ interface MCPConnection {
|
|
|
45
67
|
*
|
|
46
68
|
* @example
|
|
47
69
|
* ```ts
|
|
48
|
-
*
|
|
70
|
+
* // Remote HTTP server with bearer auth (mirrors an mcp.json HTTP entry).
|
|
71
|
+
* const mcp = await connectMCP({
|
|
72
|
+
* id: "docs",
|
|
73
|
+
* transport: {
|
|
74
|
+
* kind: "remote",
|
|
75
|
+
* url: "https://api.example.com/mcp",
|
|
76
|
+
* headers: { Authorization: "Bearer your-api-token-here" },
|
|
77
|
+
* },
|
|
78
|
+
* });
|
|
49
79
|
* const tools = await mcp.listTools(); // namespaced as docs.<tool>
|
|
50
80
|
* ```
|
|
51
81
|
*/
|
|
@@ -69,4 +99,4 @@ interface MCPToolDef {
|
|
|
69
99
|
*/
|
|
70
100
|
declare function mcpToolToTool(serverId: string, def: MCPToolDef, client: any): Tool;
|
|
71
101
|
|
|
72
|
-
export { type MCPConnection, type MCPConnectionConfig, type MCPTransport, connectMCP, mcpToolToTool };
|
|
102
|
+
export { type MCPConnection, type MCPConnectionConfig, type MCPHeaders, type MCPTransport, connectMCP, mcpToolToTool };
|
package/dist/mcp/index.d.ts
CHANGED
|
@@ -16,14 +16,36 @@ import '../types-AlvjoTyS.js';
|
|
|
16
16
|
* @packageDocumentation
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Custom HTTP headers for a remote MCP connection. Mirrors the `headers` object
|
|
21
|
+
* of an `mcp.json` HTTP server entry and is the standard way to pass secrets
|
|
22
|
+
* such as `Authorization: Bearer …` or `X-API-Key` tokens.
|
|
23
|
+
*
|
|
24
|
+
* It may be a static record or a (possibly async) callback that returns the
|
|
25
|
+
* headers. The callback form keeps the security model intact: secrets are
|
|
26
|
+
* resolved lazily at connect time (e.g. minting a fresh bearer token) and are
|
|
27
|
+
* never persisted on the config object. Empty/`null`/`undefined` values are
|
|
28
|
+
* dropped so blank auth headers are never sent.
|
|
29
|
+
*/
|
|
30
|
+
type MCPHeaders = Record<string, string> | (() => Record<string, string> | Promise<Record<string, string>>);
|
|
19
31
|
/** Transport options for an MCP connection. */
|
|
20
32
|
type MCPTransport = {
|
|
21
33
|
kind: "remote";
|
|
22
34
|
url: string;
|
|
35
|
+
/**
|
|
36
|
+
* Wire transport for the remote endpoint. Defaults to `"http"`
|
|
37
|
+
* (Streamable HTTP, the `"http"`/`"streamable-http"` type in `mcp.json`).
|
|
38
|
+
* Use `"sse"` for legacy Server-Sent Events servers. (FR-013a)
|
|
39
|
+
*/
|
|
40
|
+
type?: "http" | "sse";
|
|
41
|
+
/** Custom request headers (auth tokens, API keys, content versions, …). */
|
|
42
|
+
headers?: MCPHeaders;
|
|
23
43
|
} | {
|
|
24
44
|
kind: "stdio";
|
|
25
45
|
command: string;
|
|
26
46
|
args?: string[];
|
|
47
|
+
/** Extra environment variables for the spawned server process. */
|
|
48
|
+
env?: Record<string, string>;
|
|
27
49
|
};
|
|
28
50
|
/** Configuration for connecting to an MCP server. */
|
|
29
51
|
interface MCPConnectionConfig {
|
|
@@ -45,7 +67,15 @@ interface MCPConnection {
|
|
|
45
67
|
*
|
|
46
68
|
* @example
|
|
47
69
|
* ```ts
|
|
48
|
-
*
|
|
70
|
+
* // Remote HTTP server with bearer auth (mirrors an mcp.json HTTP entry).
|
|
71
|
+
* const mcp = await connectMCP({
|
|
72
|
+
* id: "docs",
|
|
73
|
+
* transport: {
|
|
74
|
+
* kind: "remote",
|
|
75
|
+
* url: "https://api.example.com/mcp",
|
|
76
|
+
* headers: { Authorization: "Bearer your-api-token-here" },
|
|
77
|
+
* },
|
|
78
|
+
* });
|
|
49
79
|
* const tools = await mcp.listTools(); // namespaced as docs.<tool>
|
|
50
80
|
* ```
|
|
51
81
|
*/
|
|
@@ -69,4 +99,4 @@ interface MCPToolDef {
|
|
|
69
99
|
*/
|
|
70
100
|
declare function mcpToolToTool(serverId: string, def: MCPToolDef, client: any): Tool;
|
|
71
101
|
|
|
72
|
-
export { type MCPConnection, type MCPConnectionConfig, type MCPTransport, connectMCP, mcpToolToTool };
|
|
102
|
+
export { type MCPConnection, type MCPConnectionConfig, type MCPHeaders, type MCPTransport, connectMCP, mcpToolToTool };
|
package/dist/mcp/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-framework-js",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Modular, tree-shakeable JavaScript/TypeScript agent framework for no-backend deployments (browser, edge, Node). Agents, tools, MCP, skills, multi-agent workflows, middleware, persistence, and OpenTelemetry observability.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/mcp/adapter.ts","../src/mcp/connection.ts"],"names":[],"mappings":"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","file":"chunk-QYG4HLIC.js","sourcesContent":["/**\n * Adapts MCP-provided tools onto the framework's uniform {@link Tool} contract,\n * namespaced by the connection id so collisions are impossible. (FR-014, FR-014a)\n *\n * @packageDocumentation\n */\n\nimport type { Tool } from \"../tools/tool.js\";\nimport { MCPError } from \"../core/errors.js\";\n\ninterface MCPToolDef {\n\tname: string;\n\tdescription?: string;\n\tinputSchema: Record<string, unknown>;\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * Wrap an MCP tool definition as a framework tool. Invocation calls back through\n * the MCP client; failures surface as typed {@link MCPError}/tool errors.\n */\nexport function mcpToolToTool(serverId: string, def: MCPToolDef, client: any): Tool {\n\treturn {\n\t\tname: def.name,\n\t\tdescription: def.description ?? \"\",\n\t\tinputSchema: def.inputSchema,\n\t\tsource: serverId,\n\t\tenabled: true,\n\t\tasync run(args: unknown): Promise<unknown> {\n\t\t\ttry {\n\t\t\t\tconst result = await client.callTool({ name: def.name, arguments: args });\n\t\t\t\treturn result.content ?? result;\n\t\t\t} catch (e) {\n\t\t\t\tthrow new MCPError(`MCP tool \"${def.name}\" failed: ${(e as Error).message}`, serverId);\n\t\t\t}\n\t\t},\n\t};\n}\n","/**\n * MCP (Model Context Protocol) integration. Connects to MCP servers and exposes\n * their tools through the framework's uniform tool interface.\n *\n * Remote transport (HTTP/SSE) works in all runtimes; stdio (spawning a server\n * process) works only where process spawning is permitted (Node). Requesting\n * stdio elsewhere throws a typed {@link RuntimeUnsupportedError}. (FR-013, FR-013a,\n * FR-013b, FR-030a)\n *\n * The `@modelcontextprotocol/sdk` package is an optional peer dependency and is\n * loaded lazily so browser bundles that do not use MCP pay no cost.\n *\n * @packageDocumentation\n */\n\nimport { MCPError } from \"../core/errors.js\";\nimport { requireCapability } from \"../core/runtime.js\";\nimport type { Tool } from \"../tools/tool.js\";\nimport { mcpToolToTool } from \"./adapter.js\";\n\n/** Transport options for an MCP connection. */\nexport type MCPTransport =\n\t| { kind: \"remote\"; url: string }\n\t| { kind: \"stdio\"; command: string; args?: string[] };\n\n/** Configuration for connecting to an MCP server. */\nexport interface MCPConnectionConfig {\n\t/** Connection id; becomes the namespace prefix for discovered tools. (FR-014a) */\n\tid: string;\n\ttransport: MCPTransport;\n\t/** Whether the connection's tools are enabled. Defaults to true. */\n\tenabled?: boolean;\n}\n\n/** A live connection to an MCP server. */\nexport interface MCPConnection {\n\treadonly id: string;\n\tconnect(): Promise<void>;\n\tlistTools(): Promise<Tool[]>;\n\tclose(): Promise<void>;\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\ntype AnyClient = any;\n\nasync function createTransport(config: MCPConnectionConfig): Promise<AnyClient> {\n\tif (config.transport.kind === \"stdio\") {\n\t\t// Gate on runtime capability before attempting to spawn. (FR-013b, FR-030a)\n\t\trequireCapability(\"canSpawnProcess\", \"MCP stdio transport\");\n\t\tconst { StdioClientTransport } = await import(\n\t\t\t\"@modelcontextprotocol/sdk/client/stdio.js\"\n\t\t);\n\t\treturn new StdioClientTransport({\n\t\t\tcommand: config.transport.command,\n\t\t\targs: config.transport.args ?? [],\n\t\t});\n\t}\n\tconst { StreamableHTTPClientTransport } = await import(\n\t\t\"@modelcontextprotocol/sdk/client/streamableHttp.js\"\n\t);\n\treturn new StreamableHTTPClientTransport(new URL(config.transport.url));\n}\n\n/**\n * Connect to an MCP server.\n *\n * @example\n * ```ts\n * const mcp = await connectMCP({ id: \"docs\", transport: { kind: \"remote\", url: \"https://mcp.example.com\" } });\n * const tools = await mcp.listTools(); // namespaced as docs.<tool>\n * ```\n */\nexport async function connectMCP(config: MCPConnectionConfig): Promise<MCPConnection> {\n\tlet client: AnyClient | undefined;\n\n\tasync function connect(): Promise<void> {\n\t\ttry {\n\t\t\tconst { Client } = await import(\"@modelcontextprotocol/sdk/client/index.js\");\n\t\t\tconst transport = await createTransport(config);\n\t\t\tclient = new Client({ name: \"agent-framework-js\", version: \"0.1.0\" }, { capabilities: {} });\n\t\t\tawait client.connect(transport);\n\t\t} catch (e) {\n\t\t\t// Preserve typed runtime errors; wrap everything else as an MCP error.\n\t\t\tif ((e as Error).name === \"RuntimeUnsupportedError\") throw e;\n\t\t\tthrow new MCPError(`Failed to connect to MCP server: ${(e as Error).message}`, config.id);\n\t\t}\n\t}\n\n\tasync function listTools(): Promise<Tool[]> {\n\t\tif (!client) throw new MCPError(\"Not connected\", config.id);\n\t\ttry {\n\t\t\tconst result = await client.listTools();\n\t\t\treturn (result.tools ?? []).map((t: { name: string; description?: string; inputSchema: Record<string, unknown> }) =>\n\t\t\t\tmcpToolToTool(config.id, t, client),\n\t\t\t);\n\t\t} catch (e) {\n\t\t\tthrow new MCPError(`Failed to list tools: ${(e as Error).message}`, config.id);\n\t\t}\n\t}\n\n\tasync function close(): Promise<void> {\n\t\tawait client?.close?.();\n\t\tclient = undefined;\n\t}\n\n\treturn { id: config.id, connect, listTools, close };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/mcp/adapter.ts","../src/mcp/connection.ts"],"names":["MCPError","requireCapability"],"mappings":"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","file":"chunk-U3ULJMNH.cjs","sourcesContent":["/**\n * Adapts MCP-provided tools onto the framework's uniform {@link Tool} contract,\n * namespaced by the connection id so collisions are impossible. (FR-014, FR-014a)\n *\n * @packageDocumentation\n */\n\nimport type { Tool } from \"../tools/tool.js\";\nimport { MCPError } from \"../core/errors.js\";\n\ninterface MCPToolDef {\n\tname: string;\n\tdescription?: string;\n\tinputSchema: Record<string, unknown>;\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * Wrap an MCP tool definition as a framework tool. Invocation calls back through\n * the MCP client; failures surface as typed {@link MCPError}/tool errors.\n */\nexport function mcpToolToTool(serverId: string, def: MCPToolDef, client: any): Tool {\n\treturn {\n\t\tname: def.name,\n\t\tdescription: def.description ?? \"\",\n\t\tinputSchema: def.inputSchema,\n\t\tsource: serverId,\n\t\tenabled: true,\n\t\tasync run(args: unknown): Promise<unknown> {\n\t\t\ttry {\n\t\t\t\tconst result = await client.callTool({ name: def.name, arguments: args });\n\t\t\t\treturn result.content ?? result;\n\t\t\t} catch (e) {\n\t\t\t\tthrow new MCPError(`MCP tool \"${def.name}\" failed: ${(e as Error).message}`, serverId);\n\t\t\t}\n\t\t},\n\t};\n}\n","/**\n * MCP (Model Context Protocol) integration. Connects to MCP servers and exposes\n * their tools through the framework's uniform tool interface.\n *\n * Remote transport (HTTP/SSE) works in all runtimes; stdio (spawning a server\n * process) works only where process spawning is permitted (Node). Requesting\n * stdio elsewhere throws a typed {@link RuntimeUnsupportedError}. (FR-013, FR-013a,\n * FR-013b, FR-030a)\n *\n * The `@modelcontextprotocol/sdk` package is an optional peer dependency and is\n * loaded lazily so browser bundles that do not use MCP pay no cost.\n *\n * @packageDocumentation\n */\n\nimport { MCPError } from \"../core/errors.js\";\nimport { requireCapability } from \"../core/runtime.js\";\nimport type { Tool } from \"../tools/tool.js\";\nimport { mcpToolToTool } from \"./adapter.js\";\n\n/** Transport options for an MCP connection. */\nexport type MCPTransport =\n\t| { kind: \"remote\"; url: string }\n\t| { kind: \"stdio\"; command: string; args?: string[] };\n\n/** Configuration for connecting to an MCP server. */\nexport interface MCPConnectionConfig {\n\t/** Connection id; becomes the namespace prefix for discovered tools. (FR-014a) */\n\tid: string;\n\ttransport: MCPTransport;\n\t/** Whether the connection's tools are enabled. Defaults to true. */\n\tenabled?: boolean;\n}\n\n/** A live connection to an MCP server. */\nexport interface MCPConnection {\n\treadonly id: string;\n\tconnect(): Promise<void>;\n\tlistTools(): Promise<Tool[]>;\n\tclose(): Promise<void>;\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\ntype AnyClient = any;\n\nasync function createTransport(config: MCPConnectionConfig): Promise<AnyClient> {\n\tif (config.transport.kind === \"stdio\") {\n\t\t// Gate on runtime capability before attempting to spawn. (FR-013b, FR-030a)\n\t\trequireCapability(\"canSpawnProcess\", \"MCP stdio transport\");\n\t\tconst { StdioClientTransport } = await import(\n\t\t\t\"@modelcontextprotocol/sdk/client/stdio.js\"\n\t\t);\n\t\treturn new StdioClientTransport({\n\t\t\tcommand: config.transport.command,\n\t\t\targs: config.transport.args ?? [],\n\t\t});\n\t}\n\tconst { StreamableHTTPClientTransport } = await import(\n\t\t\"@modelcontextprotocol/sdk/client/streamableHttp.js\"\n\t);\n\treturn new StreamableHTTPClientTransport(new URL(config.transport.url));\n}\n\n/**\n * Connect to an MCP server.\n *\n * @example\n * ```ts\n * const mcp = await connectMCP({ id: \"docs\", transport: { kind: \"remote\", url: \"https://mcp.example.com\" } });\n * const tools = await mcp.listTools(); // namespaced as docs.<tool>\n * ```\n */\nexport async function connectMCP(config: MCPConnectionConfig): Promise<MCPConnection> {\n\tlet client: AnyClient | undefined;\n\n\tasync function connect(): Promise<void> {\n\t\ttry {\n\t\t\tconst { Client } = await import(\"@modelcontextprotocol/sdk/client/index.js\");\n\t\t\tconst transport = await createTransport(config);\n\t\t\tclient = new Client({ name: \"agent-framework-js\", version: \"0.1.0\" }, { capabilities: {} });\n\t\t\tawait client.connect(transport);\n\t\t} catch (e) {\n\t\t\t// Preserve typed runtime errors; wrap everything else as an MCP error.\n\t\t\tif ((e as Error).name === \"RuntimeUnsupportedError\") throw e;\n\t\t\tthrow new MCPError(`Failed to connect to MCP server: ${(e as Error).message}`, config.id);\n\t\t}\n\t}\n\n\tasync function listTools(): Promise<Tool[]> {\n\t\tif (!client) throw new MCPError(\"Not connected\", config.id);\n\t\ttry {\n\t\t\tconst result = await client.listTools();\n\t\t\treturn (result.tools ?? []).map((t: { name: string; description?: string; inputSchema: Record<string, unknown> }) =>\n\t\t\t\tmcpToolToTool(config.id, t, client),\n\t\t\t);\n\t\t} catch (e) {\n\t\t\tthrow new MCPError(`Failed to list tools: ${(e as Error).message}`, config.id);\n\t\t}\n\t}\n\n\tasync function close(): Promise<void> {\n\t\tawait client?.close?.();\n\t\tclient = undefined;\n\t}\n\n\treturn { id: config.id, connect, listTools, close };\n}\n"]}
|