agentfootprint 9.80.0 → 9.81.0
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/AGENTS.md +20 -0
- package/CHANGELOG.md +109 -0
- package/CLAUDE.md +2 -0
- package/dist/esm/lib/mcp/connectionRefusals.d.ts +30 -0
- package/dist/esm/lib/mcp/connectionRefusals.js +110 -0
- package/dist/esm/lib/mcp/connectionRefusals.js.map +1 -0
- package/dist/esm/lib/mcp/index.d.ts +3 -2
- package/dist/esm/lib/mcp/index.js +4 -0
- package/dist/esm/lib/mcp/index.js.map +1 -1
- package/dist/esm/lib/mcp/mcpClient.d.ts +18 -5
- package/dist/esm/lib/mcp/mcpClient.js +102 -38
- package/dist/esm/lib/mcp/mcpClient.js.map +1 -1
- package/dist/esm/lib/mcp/mcpServe.js +45 -13
- package/dist/esm/lib/mcp/mcpServe.js.map +1 -1
- package/dist/esm/lib/mcp/sdkLoadFailure.d.ts +60 -0
- package/dist/esm/lib/mcp/sdkLoadFailure.js +74 -0
- package/dist/esm/lib/mcp/sdkLoadFailure.js.map +1 -0
- package/dist/esm/lib/mcp/throttleRetry.d.ts +20 -1
- package/dist/esm/lib/mcp/throttleRetry.js +20 -1
- package/dist/esm/lib/mcp/throttleRetry.js.map +1 -1
- package/dist/esm/lib/mcp/transportUrl.d.ts +30 -0
- package/dist/esm/lib/mcp/transportUrl.js +71 -0
- package/dist/esm/lib/mcp/transportUrl.js.map +1 -0
- package/dist/esm/lib/mcp/types.d.ts +143 -13
- package/dist/esm/tool-providers/index.d.ts +2 -2
- package/dist/esm/tool-providers/index.js +6 -1
- package/dist/esm/tool-providers/index.js.map +1 -1
- package/dist/lib/mcp/connectionRefusals.js +114 -0
- package/dist/lib/mcp/connectionRefusals.js.map +1 -0
- package/dist/lib/mcp/index.js +6 -1
- package/dist/lib/mcp/index.js.map +1 -1
- package/dist/lib/mcp/mcpClient.js +102 -38
- package/dist/lib/mcp/mcpClient.js.map +1 -1
- package/dist/lib/mcp/mcpServe.js +45 -13
- package/dist/lib/mcp/mcpServe.js.map +1 -1
- package/dist/lib/mcp/sdkLoadFailure.js +78 -0
- package/dist/lib/mcp/sdkLoadFailure.js.map +1 -0
- package/dist/lib/mcp/throttleRetry.js +20 -1
- package/dist/lib/mcp/throttleRetry.js.map +1 -1
- package/dist/lib/mcp/transportUrl.js +75 -0
- package/dist/lib/mcp/transportUrl.js.map +1 -0
- package/dist/tool-providers/index.js +6 -1
- package/dist/tool-providers/index.js.map +1 -1
- package/dist/types/lib/mcp/connectionRefusals.d.ts +31 -0
- package/dist/types/lib/mcp/connectionRefusals.d.ts.map +1 -0
- package/dist/types/lib/mcp/index.d.ts +3 -2
- package/dist/types/lib/mcp/index.d.ts.map +1 -1
- package/dist/types/lib/mcp/mcpClient.d.ts +18 -5
- package/dist/types/lib/mcp/mcpClient.d.ts.map +1 -1
- package/dist/types/lib/mcp/mcpServe.d.ts.map +1 -1
- package/dist/types/lib/mcp/sdkLoadFailure.d.ts +61 -0
- package/dist/types/lib/mcp/sdkLoadFailure.d.ts.map +1 -0
- package/dist/types/lib/mcp/throttleRetry.d.ts +20 -1
- package/dist/types/lib/mcp/throttleRetry.d.ts.map +1 -1
- package/dist/types/lib/mcp/transportUrl.d.ts +31 -0
- package/dist/types/lib/mcp/transportUrl.d.ts.map +1 -0
- package/dist/types/lib/mcp/types.d.ts +143 -13
- package/dist/types/lib/mcp/types.d.ts.map +1 -1
- package/dist/types/tool-providers/index.d.ts +2 -2
- package/dist/types/tool-providers/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -199,6 +199,25 @@ export interface McpClientOptions {
|
|
|
199
199
|
* Ignored for `stdio`, which has no HTTP status to read.
|
|
200
200
|
*/
|
|
201
201
|
readonly retryOnThrottle?: RetryOnThrottle;
|
|
202
|
+
/**
|
|
203
|
+
* Pre-resolved SDK modules. Give these and the library never touches its Node
|
|
204
|
+
* `require` loader — which is the whole reason a browser bundle can now speak
|
|
205
|
+
* MCP over `http`.
|
|
206
|
+
*
|
|
207
|
+
* Everything else keeps working, because the library still builds the
|
|
208
|
+
* transport: gateway vending, `retryOnThrottle`, `headers`, your own `fetch`,
|
|
209
|
+
* `_meta` ingestion. Omit it and the loader runs exactly as it always has.
|
|
210
|
+
*
|
|
211
|
+
* Ignored for `transport: 'stdio'`, which spawns a subprocess and therefore
|
|
212
|
+
* cannot run in a browser at all — that branch keeps loading
|
|
213
|
+
* `client/stdio.js` through the Node loader, which is also what keeps the
|
|
214
|
+
* SDK's only Node-bound client module off a browser's module graph.
|
|
215
|
+
*
|
|
216
|
+
* @see McpSdk for the two static imports that produce it.
|
|
217
|
+
*/
|
|
218
|
+
readonly sdk?: McpSdk;
|
|
219
|
+
/** @see McpConnectionOptions — never set on this arm. */
|
|
220
|
+
readonly connection?: undefined;
|
|
202
221
|
/**
|
|
203
222
|
* @internal Pre-built SDK client for tests. Skips SDK import +
|
|
204
223
|
* transport construction. Same convention as `AnthropicProvider._client`.
|
|
@@ -210,6 +229,45 @@ export interface McpClientOptions {
|
|
|
210
229
|
*/
|
|
211
230
|
readonly _client?: McpSdkClient;
|
|
212
231
|
}
|
|
232
|
+
/**
|
|
233
|
+
* The other arm of `mcpClient`: you connected the client, the library adapts it.
|
|
234
|
+
*
|
|
235
|
+
* Reach for this when the library must not construct anything at all — a
|
|
236
|
+
* browser bundle behind a strict CSP, where you need the SDK's own
|
|
237
|
+
* `jsonSchemaValidator` to keep ajv's code generation off the page; or any
|
|
238
|
+
* transport this library has never heard of.
|
|
239
|
+
*
|
|
240
|
+
* The cost is stated rather than hidden: the library builds no transport here,
|
|
241
|
+
* so every option that is consumed INSIDE a transport is refused rather than
|
|
242
|
+
* accepted and ignored. `retryOnThrottle` becomes `retryingFetch` around
|
|
243
|
+
* your own `fetch`; `clientInfo` and `headers` are yours to set when you
|
|
244
|
+
* construct the client. `signal` IS honoured — it rides the SDK's trailing
|
|
245
|
+
* request-options argument, not the transport.
|
|
246
|
+
*/
|
|
247
|
+
export interface McpConnectionOptions {
|
|
248
|
+
/**
|
|
249
|
+
* Logical name for observability + tool-call routing, exactly as on
|
|
250
|
+
* {@link McpClientOptions}. Defaults to `'mcp'`.
|
|
251
|
+
*/
|
|
252
|
+
readonly name?: string;
|
|
253
|
+
/**
|
|
254
|
+
* A connection you already opened. The library never calls `connect()` on it;
|
|
255
|
+
* `close()` on the returned client closes it exactly once.
|
|
256
|
+
*/
|
|
257
|
+
readonly connection: McpConnection;
|
|
258
|
+
/** Abort the list / call paths. Rides the SDK's request options. */
|
|
259
|
+
readonly signal?: AbortSignal;
|
|
260
|
+
/** @see McpClientOptions — never set on this arm. */
|
|
261
|
+
readonly transport?: undefined;
|
|
262
|
+
/** @see McpClientOptions — never set on this arm. */
|
|
263
|
+
readonly sdk?: undefined;
|
|
264
|
+
/** @see McpClientOptions — never set on this arm. */
|
|
265
|
+
readonly clientInfo?: undefined;
|
|
266
|
+
/** @see McpClientOptions — never set on this arm. */
|
|
267
|
+
readonly retryOnThrottle?: undefined;
|
|
268
|
+
/** @internal @see McpClientOptions — never set on this arm. */
|
|
269
|
+
readonly _client?: undefined;
|
|
270
|
+
}
|
|
213
271
|
/**
|
|
214
272
|
* What `mcpClient(opts)` returns. Connect once; call `.tools()` to
|
|
215
273
|
* snapshot the tool list, `.refresh()` to re-list after the server's
|
|
@@ -235,23 +293,30 @@ export interface McpClient {
|
|
|
235
293
|
close(): Promise<void>;
|
|
236
294
|
}
|
|
237
295
|
/**
|
|
238
|
-
*
|
|
239
|
-
* we touch. Defined locally so we can:
|
|
240
|
-
* 1. Inject a mock for tests (`McpClientOptions._client`)
|
|
241
|
-
* 2. Avoid a hard import on `@modelcontextprotocol/sdk` (which is
|
|
242
|
-
* a lazy peer-dep)
|
|
296
|
+
* A live MCP connection you opened and connected yourself.
|
|
243
297
|
*
|
|
244
|
-
*
|
|
298
|
+
* This is the whole contract this library needs from an MCP client: three
|
|
299
|
+
* methods over JSON-RPC. Nothing in it names a vendor, so an SDK `Client`, a
|
|
300
|
+
* hand-written fake, or a future fetch-only transport all satisfy it.
|
|
301
|
+
*
|
|
302
|
+
* Pass one as `mcpClient({ connection })` when the library must not load the
|
|
303
|
+
* SDK itself — a browser bundle, where the Node `require` loader does not
|
|
304
|
+
* exist. You own construction, so you also own the transport's `fetch`, its
|
|
305
|
+
* headers, its auth, and (SDK-specific) its `jsonSchemaValidator`, which is the
|
|
306
|
+
* one way to keep ajv's `new Function` off a page with a strict CSP.
|
|
307
|
+
*
|
|
308
|
+
* What you give up by owning it: this library builds no transport on that arm,
|
|
309
|
+
* so `retryOnThrottle` has nothing to wrap. Wrap your own fetch with
|
|
310
|
+
* `retryingFetch` and the 429 handling comes back.
|
|
245
311
|
*
|
|
246
312
|
* Argument POSITION matters here and is easy to get wrong: the SDK keeps
|
|
247
|
-
* per-request options (`signal`, `timeout`) in a SEPARATE trailing
|
|
248
|
-
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
313
|
+
* per-request options (`signal`, `timeout`) in a SEPARATE trailing argument,
|
|
314
|
+
* never inside the JSON-RPC params. A `signal` smuggled into the params object
|
|
315
|
+
* is serialized onto the wire as `{}` and silently fails to cancel anything, so
|
|
316
|
+
* these signatures mirror the SDK's own shape rather than a flattened
|
|
317
|
+
* convenience version of it.
|
|
252
318
|
*/
|
|
253
|
-
export interface
|
|
254
|
-
connect(transport: unknown, options?: McpRequestOptions): Promise<void>;
|
|
319
|
+
export interface McpConnection {
|
|
255
320
|
listTools(params?: undefined, options?: McpRequestOptions): Promise<{
|
|
256
321
|
readonly tools: ReadonlyArray<McpListedTool>;
|
|
257
322
|
}>;
|
|
@@ -263,6 +328,71 @@ export interface McpSdkClient {
|
|
|
263
328
|
resultSchema?: undefined, options?: McpRequestOptions): Promise<McpCallToolResult>;
|
|
264
329
|
close(): Promise<void>;
|
|
265
330
|
}
|
|
331
|
+
/**
|
|
332
|
+
* Minimal structural type capturing the parts of the MCP SDK client
|
|
333
|
+
* we touch. Defined locally so we can:
|
|
334
|
+
* 1. Inject a mock for tests (`McpClientOptions._client`)
|
|
335
|
+
* 2. Avoid a hard import on `@modelcontextprotocol/sdk` (which is
|
|
336
|
+
* a lazy peer-dep)
|
|
337
|
+
*
|
|
338
|
+
* The real SDK exports a richer surface; we narrow to what's needed.
|
|
339
|
+
*
|
|
340
|
+
* Member set unchanged since it was introduced: {@link McpConnection} plus the
|
|
341
|
+
* one method the library calls when it opens the connection ITSELF. The split
|
|
342
|
+
* is what lets a caller hand over a client that is already connected without
|
|
343
|
+
* also promising a `connect` this library must never call on it.
|
|
344
|
+
*/
|
|
345
|
+
export interface McpSdkClient extends McpConnection {
|
|
346
|
+
connect(transport: unknown, options?: McpRequestOptions): Promise<void>;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* The two `@modelcontextprotocol/sdk` module exports the Streamable HTTP path
|
|
350
|
+
* needs, typed STRUCTURALLY so this declaration never references the optional
|
|
351
|
+
* peer — a consumer without the SDK installed still typechecks.
|
|
352
|
+
*
|
|
353
|
+
* Hand these to `mcpClient({ sdk })` and the library never touches its Node
|
|
354
|
+
* `require` loader, which is what lets a browser bundle speak MCP over `http`.
|
|
355
|
+
* Everything else keeps working, because the library still builds the
|
|
356
|
+
* transport: gateway vending, `retryOnThrottle`, `headers`, your own `fetch`,
|
|
357
|
+
* `_meta` ingestion.
|
|
358
|
+
*
|
|
359
|
+
* Load them yourself with two static imports. The subpaths matter: the SDK's
|
|
360
|
+
* root export `"."` does not resolve (it declares no `dist/esm/index.js`), and
|
|
361
|
+
* `client/stdio.js` is the one client module that imports `node:process` and
|
|
362
|
+
* `node:stream` — importing it is what would drag Node into a browser graph.
|
|
363
|
+
*
|
|
364
|
+
* ```ts
|
|
365
|
+
* import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
366
|
+
* import { StreamableHTTPClientTransport }
|
|
367
|
+
* from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
368
|
+
*
|
|
369
|
+
* const client = await mcpClient({
|
|
370
|
+
* name: 'sidecar',
|
|
371
|
+
* sdk: { Client, StreamableHTTPClientTransport },
|
|
372
|
+
* transport: { transport: 'http', url: '/py/mcp' },
|
|
373
|
+
* });
|
|
374
|
+
* ```
|
|
375
|
+
*/
|
|
376
|
+
export interface McpSdk {
|
|
377
|
+
readonly Client: new (info: {
|
|
378
|
+
name: string;
|
|
379
|
+
version: string;
|
|
380
|
+
}, options: {
|
|
381
|
+
capabilities: Record<string, unknown>;
|
|
382
|
+
}) => McpSdkClient;
|
|
383
|
+
readonly StreamableHTTPClientTransport: new (url: URL, options?: {
|
|
384
|
+
requestInit?: {
|
|
385
|
+
headers: Record<string, string>;
|
|
386
|
+
};
|
|
387
|
+
/**
|
|
388
|
+
* The SDK's hook for a custom fetch — how per-request vending AND
|
|
389
|
+
* caller-supplied signing both get in. Typed exactly as the SDK types it,
|
|
390
|
+
* so a function this shim accepts is a function the real transport
|
|
391
|
+
* accepts.
|
|
392
|
+
*/
|
|
393
|
+
fetch?: (url: string | URL, init?: RequestInit) => Promise<Response>;
|
|
394
|
+
}) => unknown;
|
|
395
|
+
}
|
|
266
396
|
/**
|
|
267
397
|
* One entry of a `tools/list` answer, narrowed to what this client reads.
|
|
268
398
|
*
|
|
@@ -51,7 +51,7 @@ export { staticTools } from './staticTools.js';
|
|
|
51
51
|
export { gatedTools } from './gatedTools.js';
|
|
52
52
|
export { skillScopedTools, skillScopedToolsTarget, SKILL_SCOPED_TOOLS_ID_PREFIX, } from './skillScopedTools.js';
|
|
53
53
|
export type { ToolProvider, ToolDispatchContext, ToolGatePredicate } from './types.js';
|
|
54
|
-
export { mcpClient, mcpServe, mockMcpClient, gatewayTransport, GatewayAuthorizationRequiredError, MCP_TOOL_EXTRAS_KEY, } from '../lib/mcp/index.js';
|
|
54
|
+
export { mcpClient, mcpServe, mockMcpClient, gatewayTransport, GatewayAuthorizationRequiredError, MCP_TOOL_EXTRAS_KEY, retryingFetch, } from '../lib/mcp/index.js';
|
|
55
55
|
export { agentCoreGatewayTransport, agentCoreGatewayUrl, gatewaySearchTool, hasGatewaySearch, AGENTCORE_GATEWAY_SEARCH_TOOL, AGENTCORE_POLICY_SESSION_HEADER, AGENTCORE_SIGV4_SERVICE, } from '../adapters/mcp/agentcore.js';
|
|
56
56
|
export type { AgentCoreGatewayTransportOptions, AgentCoreGatewayUrlOptions, } from '../adapters/mcp/agentcore.js';
|
|
57
|
-
export type { GatewayTransportOptions, McpCallToolResult, McpClient, McpClientOptions, McpSdkClient, McpTransport, McpStdioTransport, McpHttpTransport, McpGatewayTransport, MockMcpClientOptions, MockMcpTool, McpServeOptions, McpServeHandle, McpServeTransport, McpStdioServeTransport, McpHttpServeTransport, McpSdkServer, McpToolExtras, } from '../lib/mcp/index.js';
|
|
57
|
+
export type { GatewayTransportOptions, McpCallToolResult, McpClient, McpClientOptions, McpConnection, McpConnectionOptions, McpSdk, McpSdkClient, ThrottleFetch, McpTransport, McpStdioTransport, McpHttpTransport, McpGatewayTransport, MockMcpClientOptions, MockMcpTool, McpServeOptions, McpServeHandle, McpServeTransport, McpStdioServeTransport, McpHttpServeTransport, McpSdkServer, McpToolExtras, } from '../lib/mcp/index.js';
|
|
@@ -60,7 +60,12 @@ export { mcpClient, mcpServe, mockMcpClient, gatewayTransport, GatewayAuthorizat
|
|
|
60
60
|
// The `_meta` key agentfootprint's tool declarations travel under, in both
|
|
61
61
|
// directions (9.71.0). Public so a server this library did not write can
|
|
62
62
|
// speak it, and so a client can read a bag it received.
|
|
63
|
-
MCP_TOOL_EXTRAS_KEY,
|
|
63
|
+
MCP_TOOL_EXTRAS_KEY,
|
|
64
|
+
// The 429 retry `mcpClient({ transport })` applies for you (9.81.0). Public
|
|
65
|
+
// so `mcpClient({ connection })` — the arm a browser takes, where the library
|
|
66
|
+
// builds no transport — can wrap its own `fetch` with the same code rather
|
|
67
|
+
// than quietly doing without it.
|
|
68
|
+
retryingFetch, } from '../lib/mcp/index.js';
|
|
64
69
|
// Reaching an AWS Bedrock AgentCore Gateway (9.66.0). A configuration of
|
|
65
70
|
// `gatewayTransport` plus the four facts that are AgentCore's alone — kept in
|
|
66
71
|
// the vendor's own file so the transport above stays able to say, truthfully,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tool-providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EACL,gBAAgB;AAChB,kFAAkF;AAClF,kFAAkF;AAClF,sBAAsB,EACtB,4BAA4B,GAC7B,MAAM,uBAAuB,CAAC;AAG/B,uEAAuE;AACvE,wEAAwE;AACxE,0CAA0C;AAC1C,OAAO,EACL,SAAS,EACT,QAAQ,EACR,aAAa,EACb,gBAAgB,EAChB,iCAAiC;AACjC,2EAA2E;AAC3E,yEAAyE;AACzE,wDAAwD;AACxD,mBAAmB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tool-providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EACL,gBAAgB;AAChB,kFAAkF;AAClF,kFAAkF;AAClF,sBAAsB,EACtB,4BAA4B,GAC7B,MAAM,uBAAuB,CAAC;AAG/B,uEAAuE;AACvE,wEAAwE;AACxE,0CAA0C;AAC1C,OAAO,EACL,SAAS,EACT,QAAQ,EACR,aAAa,EACb,gBAAgB,EAChB,iCAAiC;AACjC,2EAA2E;AAC3E,yEAAyE;AACzE,wDAAwD;AACxD,mBAAmB;AACnB,4EAA4E;AAC5E,8EAA8E;AAC9E,2EAA2E;AAC3E,iCAAiC;AACjC,aAAa,GACd,MAAM,qBAAqB,CAAC;AAC7B,yEAAyE;AACzE,8EAA8E;AAC9E,8EAA8E;AAC9E,yCAAyC;AACzC,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,6BAA6B,EAC7B,+BAA+B,EAC/B,uBAAuB,GACxB,MAAM,8BAA8B,CAAC"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* connectionRefusals — the two arms of `mcpClient` refuse to be mixed, at
|
|
4
|
+
* CONSTRUCTION, in words that name where the behaviour went.
|
|
5
|
+
*
|
|
6
|
+
* ── Why refuse rather than ignore ────────────────────────────────────────────
|
|
7
|
+
* `mcpClient({ connection })` hands over a client somebody else built, so this
|
|
8
|
+
* library builds no transport on that arm — and every option consumed INSIDE a
|
|
9
|
+
* transport therefore has nothing to act on. `retryOnThrottle` is the sharp
|
|
10
|
+
* one: it is ON by default, it is consumed by `retryingFetch` around the
|
|
11
|
+
* transport's `fetch`, and accepting it here would leave a caller holding an
|
|
12
|
+
* option that NAMES a behaviour which no longer happens. A knob that lies about
|
|
13
|
+
* what it does is worse than one that is absent, so these throw.
|
|
14
|
+
*
|
|
15
|
+
* The type union refuses the same combinations at compile time
|
|
16
|
+
* (`McpConnectionOptions` declares each of them `?: undefined`). This is the
|
|
17
|
+
* runtime half, and it is not redundant: excess-property checking does not
|
|
18
|
+
* survive a spread, and JavaScript callers have no compiler at all.
|
|
19
|
+
*
|
|
20
|
+
* Pattern: pure guard. Role: Layer-3 tool integration.
|
|
21
|
+
*/
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.refuseConflictingOptions = void 0;
|
|
24
|
+
/** The three methods this library calls on a connection. Nothing else. */
|
|
25
|
+
const CONNECTION_METHODS = ['listTools', 'callTool', 'close'];
|
|
26
|
+
/**
|
|
27
|
+
* Refuse a mixed or malformed options object before anything connects.
|
|
28
|
+
*
|
|
29
|
+
* @param opts what the caller passed, before any defaulting
|
|
30
|
+
* @param name the client's logical name, so a multi-server app knows which one
|
|
31
|
+
* @throws naming the two options that cannot travel together, or the member the
|
|
32
|
+
* connection is missing
|
|
33
|
+
*/
|
|
34
|
+
function refuseConflictingOptions(opts, name) {
|
|
35
|
+
const at = `mcpClient[${name}]`;
|
|
36
|
+
// Read through a permissive view on purpose. The union already narrows these
|
|
37
|
+
// combinations away at compile time, so narrowing here would leave the guard
|
|
38
|
+
// reasoning about a shape it exists precisely to disbelieve — an object built
|
|
39
|
+
// by a spread, or by JavaScript.
|
|
40
|
+
const given = opts;
|
|
41
|
+
if (given['connection'] === undefined) {
|
|
42
|
+
if (given['transport'] === undefined && given['_client'] === undefined) {
|
|
43
|
+
throw new Error(`${at}: nothing to connect to. Pass \`transport\` (the library builds the connection) ` +
|
|
44
|
+
'or `connection` (a client you connected yourself).');
|
|
45
|
+
}
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
// From here on the caller chose the `connection` arm.
|
|
49
|
+
for (const [option, moved] of BUILT_BY_THE_TRANSPORT) {
|
|
50
|
+
if (given[option] !== undefined) {
|
|
51
|
+
throw new Error(`${at}: \`connection\` and \`${option}\` cannot travel together. ` +
|
|
52
|
+
`A connection you built yourself carries its own transport, and \`${option}\` is ` +
|
|
53
|
+
`consumed inside the transport this library did not build. ${moved}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
assertConnection(given['connection'], at);
|
|
57
|
+
}
|
|
58
|
+
exports.refuseConflictingOptions = refuseConflictingOptions;
|
|
59
|
+
/**
|
|
60
|
+
* The options that only exist because the library builds the transport, each
|
|
61
|
+
* paired with the sentence naming where that behaviour moved to. Ordered so the
|
|
62
|
+
* most surprising loss — throttle retry, which is ON by default — is named
|
|
63
|
+
* first when a caller passes several.
|
|
64
|
+
*/
|
|
65
|
+
const BUILT_BY_THE_TRANSPORT = [
|
|
66
|
+
[
|
|
67
|
+
'retryOnThrottle',
|
|
68
|
+
'Wrap your own `fetch` with `retryingFetch(yourFetch, options)` (exported from ' +
|
|
69
|
+
'`agentfootprint/providers`) and hand THAT to your transport — it is the same ' +
|
|
70
|
+
'implementation, applied where you build it.',
|
|
71
|
+
],
|
|
72
|
+
[
|
|
73
|
+
'clientInfo',
|
|
74
|
+
'Pass it to the SDK `Client` constructor instead: `new Client(clientInfo, { capabilities: {} })`.',
|
|
75
|
+
],
|
|
76
|
+
[
|
|
77
|
+
'transport',
|
|
78
|
+
'Drop one of the two: `transport` asks the library to connect, `connection` says it already is.',
|
|
79
|
+
],
|
|
80
|
+
[
|
|
81
|
+
'sdk',
|
|
82
|
+
'`sdk` exists so the library can build the transport without its Node loader; ' +
|
|
83
|
+
'on this arm you have already built it.',
|
|
84
|
+
],
|
|
85
|
+
[
|
|
86
|
+
'_client',
|
|
87
|
+
'`_client` is the same idea as `connection` and predates it — pass `connection` alone.',
|
|
88
|
+
],
|
|
89
|
+
];
|
|
90
|
+
/**
|
|
91
|
+
* A connection is only a connection if it can be called.
|
|
92
|
+
*
|
|
93
|
+
* This catches the near-miss people actually make: handing over the TRANSPORT
|
|
94
|
+
* rather than the client. A transport has none of these three methods, and
|
|
95
|
+
* without this check it fails on the first `tools()`, one stack frame deep
|
|
96
|
+
* inside the SDK.
|
|
97
|
+
*
|
|
98
|
+
* The OTHER near-miss — a `Client` that was constructed but never `connect()`ed
|
|
99
|
+
* — cannot be caught here, because it has all three methods. It is named in the
|
|
100
|
+
* message anyway, since it produces the same "my connection does not work" and
|
|
101
|
+
* the SDK's own "Not connected" is the thing to look for.
|
|
102
|
+
*/
|
|
103
|
+
function assertConnection(connection, at) {
|
|
104
|
+
const members = (connection ?? {});
|
|
105
|
+
for (const method of CONNECTION_METHODS) {
|
|
106
|
+
if (typeof members[method] !== 'function') {
|
|
107
|
+
throw new Error(`${at}: \`connection\` has no \`${method}()\`. It must be an MCP client that is ` +
|
|
108
|
+
'already connected, and the likely mistake is passing the TRANSPORT instead of the ' +
|
|
109
|
+
'client. (A `new Client(...)` you never awaited `connect()` on passes this check ' +
|
|
110
|
+
'and fails later with the SDK\'s own "Not connected".)');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=connectionRefusals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connectionRefusals.js","sourceRoot":"","sources":["../../../src/lib/mcp/connectionRefusals.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;;AAIH,0EAA0E;AAC1E,MAAM,kBAAkB,GAAG,CAAC,WAAW,EAAE,UAAU,EAAE,OAAO,CAAU,CAAC;AAEvE;;;;;;;GAOG;AACH,SAAgB,wBAAwB,CACtC,IAA6C,EAC7C,IAAY;IAEZ,MAAM,EAAE,GAAG,aAAa,IAAI,GAAG,CAAC;IAChC,6EAA6E;IAC7E,6EAA6E;IAC7E,8EAA8E;IAC9E,iCAAiC;IACjC,MAAM,KAAK,GAAG,IAAoD,CAAC;IAEnE,IAAI,KAAK,CAAC,YAAY,CAAC,KAAK,SAAS,EAAE,CAAC;QACtC,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,SAAS,IAAI,KAAK,CAAC,SAAS,CAAC,KAAK,SAAS,EAAE,CAAC;YACvE,MAAM,IAAI,KAAK,CACb,GAAG,EAAE,kFAAkF;gBACrF,oDAAoD,CACvD,CAAC;QACJ,CAAC;QACD,OAAO;IACT,CAAC;IAED,sDAAsD;IACtD,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,sBAAsB,EAAE,CAAC;QACrD,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CACb,GAAG,EAAE,0BAA0B,MAAM,6BAA6B;gBAChE,oEAAoE,MAAM,QAAQ;gBAClF,6DAA6D,KAAK,EAAE,CACvE,CAAC;QACJ,CAAC;IACH,CAAC;IACD,gBAAgB,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC,CAAC;AAC5C,CAAC;AAhCD,4DAgCC;AAED;;;;;GAKG;AACH,MAAM,sBAAsB,GAExB;IACF;QACE,iBAAiB;QACjB,gFAAgF;YAC9E,+EAA+E;YAC/E,6CAA6C;KAChD;IACD;QACE,YAAY;QACZ,kGAAkG;KACnG;IACD;QACE,WAAW;QACX,gGAAgG;KACjG;IACD;QACE,KAAK;QACL,+EAA+E;YAC7E,wCAAwC;KAC3C;IACD;QACE,SAAS;QACT,uFAAuF;KACxF;CACF,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,SAAS,gBAAgB,CAAC,UAAmB,EAAE,EAAU;IACvD,MAAM,OAAO,GAAG,CAAC,UAAU,IAAI,EAAE,CAAsC,CAAC;IACxE,KAAK,MAAM,MAAM,IAAI,kBAAkB,EAAE,CAAC;QACxC,IAAI,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,UAAU,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CACb,GAAG,EAAE,6BAA6B,MAAM,yCAAyC;gBAC/E,oFAAoF;gBACpF,kFAAkF;gBAClF,uDAAuD,CAC1D,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC"}
|
package/dist/lib/mcp/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.GatewayAuthorizationRequiredError = exports.gatewayTransport = exports.mockMcpClient = exports.MCP_TOOL_EXTRAS_KEY = exports.mcpServe = exports.mcpClient = void 0;
|
|
3
|
+
exports.retryingFetch = exports.GatewayAuthorizationRequiredError = exports.gatewayTransport = exports.mockMcpClient = exports.MCP_TOOL_EXTRAS_KEY = exports.mcpServe = exports.mcpClient = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* MCP — Model Context Protocol, both directions. `mcpClient` connects to
|
|
6
6
|
* someone else's MCP server and registers its tools on your Agent;
|
|
@@ -20,4 +20,9 @@ Object.defineProperty(exports, "mockMcpClient", { enumerable: true, get: functio
|
|
|
20
20
|
var gatewayTransport_js_1 = require("./gatewayTransport.js");
|
|
21
21
|
Object.defineProperty(exports, "gatewayTransport", { enumerable: true, get: function () { return gatewayTransport_js_1.gatewayTransport; } });
|
|
22
22
|
Object.defineProperty(exports, "GatewayAuthorizationRequiredError", { enumerable: true, get: function () { return gatewayTransport_js_1.GatewayAuthorizationRequiredError; } });
|
|
23
|
+
// The 429 handling `mcpClient({ transport })` applies for you — public since
|
|
24
|
+
// 9.81.0 so the `connection` arm, which builds no transport of its own, can
|
|
25
|
+
// apply the SAME implementation instead of silently going without it.
|
|
26
|
+
var throttleRetry_js_1 = require("./throttleRetry.js");
|
|
27
|
+
Object.defineProperty(exports, "retryingFetch", { enumerable: true, get: function () { return throttleRetry_js_1.retryingFetch; } });
|
|
23
28
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/mcp/index.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACH,+CAA2C;AAAlC,yGAAA,SAAS,OAAA;AAClB,6CAAyC;AAAhC,uGAAA,QAAQ,OAAA;AACjB,8EAA8E;AAC9E,0EAA0E;AAC1E,iDAA0E;AAAjE,oHAAA,mBAAmB,OAAA;AAC5B,uDAAgG;AAAvF,iHAAA,aAAa,OAAA;AACtB,6DAI+B;AAH7B,uHAAA,gBAAgB,OAAA;AAChB,wIAAA,iCAAiC,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/mcp/index.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACH,+CAA2C;AAAlC,yGAAA,SAAS,OAAA;AAClB,6CAAyC;AAAhC,uGAAA,QAAQ,OAAA;AACjB,8EAA8E;AAC9E,0EAA0E;AAC1E,iDAA0E;AAAjE,oHAAA,mBAAmB,OAAA;AAC5B,uDAAgG;AAAvF,iHAAA,aAAa,OAAA;AACtB,6DAI+B;AAH7B,uHAAA,gBAAgB,OAAA;AAChB,wIAAA,iCAAiC,OAAA;AAGnC,6EAA6E;AAC7E,4EAA4E;AAC5E,sEAAsE;AACtE,uDAAmD;AAA1C,iHAAA,aAAa,OAAA"}
|
|
@@ -45,6 +45,9 @@ exports.mcpClient = void 0;
|
|
|
45
45
|
const toolExtras_js_1 = require("./toolExtras.js");
|
|
46
46
|
const gatewayTransport_js_1 = require("./gatewayTransport.js");
|
|
47
47
|
const throttleRetry_js_1 = require("./throttleRetry.js");
|
|
48
|
+
const connectionRefusals_js_1 = require("./connectionRefusals.js");
|
|
49
|
+
const sdkLoadFailure_js_1 = require("./sdkLoadFailure.js");
|
|
50
|
+
const transportUrl_js_1 = require("./transportUrl.js");
|
|
48
51
|
const lazyRequire_js_1 = require("../lazyRequire.js");
|
|
49
52
|
// Version-less identity. The MCP `clientInfo` field is informational
|
|
50
53
|
// (server logs it); a hardcoded number drifts every release. Consumers
|
|
@@ -58,14 +61,29 @@ const DEFAULT_CLIENT_INFO = {
|
|
|
58
61
|
* server's tools as agentfootprint `Tool[]` and a `close()` to tear
|
|
59
62
|
* down the transport.
|
|
60
63
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
+
* Three ways to get a connection, and they are three because a browser can
|
|
65
|
+
* only take the last two:
|
|
66
|
+
*
|
|
67
|
+
* - `{ transport }` — the library loads the SDK through its Node loader and
|
|
68
|
+
* builds everything. The default, and what every Node consumer already
|
|
69
|
+
* does.
|
|
70
|
+
* - `{ transport, sdk }` — you supply the two SDK modules with static
|
|
71
|
+
* imports; the library still builds the transport, so gateway vending,
|
|
72
|
+
* `retryOnThrottle`, `headers` and your own `fetch` all keep working.
|
|
73
|
+
* - `{ connection }` — you built and connected the client yourself; the
|
|
74
|
+
* library only adapts its tools.
|
|
75
|
+
*
|
|
76
|
+
* @throws when the two arms are mixed, when a `connection` is not one, or when
|
|
77
|
+
* `@modelcontextprotocol/sdk` cannot be loaded (the message says which of
|
|
78
|
+
* "not installed" and "no Node loader here" actually happened), or when the
|
|
79
|
+
* transport fails to connect.
|
|
64
80
|
*/
|
|
65
81
|
async function mcpClient(opts) {
|
|
66
82
|
const name = opts.name ?? 'mcp';
|
|
67
|
-
|
|
68
|
-
|
|
83
|
+
// Before anything connects: an option that names a behaviour which cannot
|
|
84
|
+
// happen on the chosen arm is a defect, not a preference.
|
|
85
|
+
(0, connectionRefusals_js_1.refuseConflictingOptions)(opts, name);
|
|
86
|
+
const connection = await openConnection(opts);
|
|
69
87
|
// Tool cache so consumers calling `.tools()` more than once don't
|
|
70
88
|
// hammer the server. `.refresh()` invalidates it.
|
|
71
89
|
let cache = null;
|
|
@@ -79,9 +97,9 @@ async function mcpClient(opts) {
|
|
|
79
97
|
// `signal` rides in the SDK's THIRD argument (RequestOptions), not in
|
|
80
98
|
// the request params — see `wrapMcpTool`.
|
|
81
99
|
const listed = opts.signal
|
|
82
|
-
? await
|
|
83
|
-
: await
|
|
84
|
-
return listed.tools.map((t) => wrapMcpTool(name,
|
|
100
|
+
? await connection.listTools(undefined, { signal: opts.signal })
|
|
101
|
+
: await connection.listTools();
|
|
102
|
+
return listed.tools.map((t) => wrapMcpTool(name, connection, t, opts.signal));
|
|
85
103
|
};
|
|
86
104
|
return {
|
|
87
105
|
name,
|
|
@@ -101,26 +119,36 @@ async function mcpClient(opts) {
|
|
|
101
119
|
return;
|
|
102
120
|
closed = true;
|
|
103
121
|
cache = null;
|
|
104
|
-
await
|
|
122
|
+
await connection.close();
|
|
105
123
|
},
|
|
106
124
|
};
|
|
107
125
|
}
|
|
108
126
|
exports.mcpClient = mcpClient;
|
|
109
|
-
// ───
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
127
|
+
// ─── Getting a connection ──────────────────────────────────────────
|
|
128
|
+
/**
|
|
129
|
+
* The one funnel every arm passes through, in precedence order: a connection
|
|
130
|
+
* you handed over, the internal test seam, then the library building one.
|
|
131
|
+
*
|
|
132
|
+
* A call with neither `connection` nor `sdk` reaches `resolveClient` with two
|
|
133
|
+
* `undefined` arguments and takes the identical path it always took.
|
|
134
|
+
*/
|
|
135
|
+
async function openConnection(opts) {
|
|
136
|
+
if (opts.connection !== undefined)
|
|
137
|
+
return opts.connection;
|
|
138
|
+
if (opts._client !== undefined)
|
|
139
|
+
return opts._client;
|
|
140
|
+
// `refuseConflictingOptions` has already refused the case where this is
|
|
141
|
+
// absent, so the assertion documents that guarantee rather than assuming it.
|
|
142
|
+
const transport = opts.transport;
|
|
143
|
+
return resolveClient(transport, opts.clientInfo, opts.signal, opts.retryOnThrottle, opts.sdk);
|
|
144
|
+
}
|
|
145
|
+
// ─── SDK construction (lazy require, unless the caller supplied it) ─
|
|
146
|
+
async function resolveClient(transport, clientInfo, signal, retryOnThrottle, sdk) {
|
|
147
|
+
const mod = sdk ?? loadClientModule();
|
|
120
148
|
const client = new mod.Client(clientInfo ?? DEFAULT_CLIENT_INFO, {
|
|
121
149
|
capabilities: {},
|
|
122
150
|
});
|
|
123
|
-
const transportImpl = await buildTransport(transport, retryOnThrottle);
|
|
151
|
+
const transportImpl = await buildTransport(transport, retryOnThrottle, sdk);
|
|
124
152
|
// Same rule as callTool: options ride beside the transport, never inside it.
|
|
125
153
|
if (signal)
|
|
126
154
|
await client.connect(transportImpl, { signal });
|
|
@@ -128,15 +156,42 @@ async function resolveClient(transport, clientInfo, signal, retryOnThrottle) {
|
|
|
128
156
|
await client.connect(transportImpl);
|
|
129
157
|
return client;
|
|
130
158
|
}
|
|
131
|
-
|
|
159
|
+
/** The Node loader path, unchanged — reached only when no `sdk` was supplied. */
|
|
160
|
+
function loadClientModule() {
|
|
161
|
+
try {
|
|
162
|
+
return (0, lazyRequire_js_1.lazyRequire)('@modelcontextprotocol/sdk/client/index.js');
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
throw new Error((0, sdkLoadFailure_js_1.sdkLoadFailure)(err, {
|
|
166
|
+
notInstalled: 'mcpClient requires @modelcontextprotocol/sdk.\n' +
|
|
167
|
+
' Install: npm install @modelcontextprotocol/sdk\n' +
|
|
168
|
+
' Or pass `_client` for test injection.',
|
|
169
|
+
caller: 'mcpClient',
|
|
170
|
+
specifier: '@modelcontextprotocol/sdk/client/index.js',
|
|
171
|
+
instead: 'Pass `sdk` (the two SDK modules, imported statically) or `connection` ' +
|
|
172
|
+
'(a client you connected yourself).',
|
|
173
|
+
}));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
async function buildTransport(t, retryOnThrottle, sdk) {
|
|
132
177
|
if (t.transport === 'stdio') {
|
|
178
|
+
// Deliberately NOT served by `sdk`: stdio spawns a subprocess, so it can
|
|
179
|
+
// never run in a browser, and `client/stdio.js` is the SDK's one client
|
|
180
|
+
// module that imports `node:process`/`node:stream`. Keeping it behind the
|
|
181
|
+
// loader is what keeps it off every browser module graph.
|
|
133
182
|
let stdioMod;
|
|
134
183
|
try {
|
|
135
184
|
stdioMod = (0, lazyRequire_js_1.lazyRequire)('@modelcontextprotocol/sdk/client/stdio.js');
|
|
136
185
|
}
|
|
137
|
-
catch {
|
|
138
|
-
throw new Error(
|
|
139
|
-
'
|
|
186
|
+
catch (err) {
|
|
187
|
+
throw new Error((0, sdkLoadFailure_js_1.sdkLoadFailure)(err, {
|
|
188
|
+
notInstalled: 'mcpClient(stdio) requires @modelcontextprotocol/sdk/client/stdio.js — ' +
|
|
189
|
+
'check that @modelcontextprotocol/sdk is installed at the latest version.',
|
|
190
|
+
caller: 'mcpClient(stdio)',
|
|
191
|
+
specifier: '@modelcontextprotocol/sdk/client/stdio.js',
|
|
192
|
+
instead: 'stdio spawns a subprocess, so it cannot run in a browser at all — ' +
|
|
193
|
+
"reach the server over `transport: { transport: 'http', url }` instead.",
|
|
194
|
+
}));
|
|
140
195
|
}
|
|
141
196
|
return new stdioMod.StdioClientTransport({
|
|
142
197
|
command: t.command,
|
|
@@ -148,14 +203,7 @@ async function buildTransport(t, retryOnThrottle) {
|
|
|
148
203
|
// http + gateway transports both ride Streamable HTTP. They differ only in
|
|
149
204
|
// WHEN the auth headers are decided: `http` fixes them at construction,
|
|
150
205
|
// `gateway` vends them inside every request (see gatewayTransport.ts).
|
|
151
|
-
|
|
152
|
-
try {
|
|
153
|
-
httpMod = (0, lazyRequire_js_1.lazyRequire)('@modelcontextprotocol/sdk/client/streamableHttp.js');
|
|
154
|
-
}
|
|
155
|
-
catch {
|
|
156
|
-
throw new Error(`mcpClient(${t.transport}) requires @modelcontextprotocol/sdk/client/streamableHttp.js — ` +
|
|
157
|
-
'check that @modelcontextprotocol/sdk is installed at the latest version.');
|
|
158
|
-
}
|
|
206
|
+
const httpMod = sdk ?? loadHttpModule(t.transport);
|
|
159
207
|
// Throttle retry wraps the OUTERMOST fetch, so every attempt is re-signed
|
|
160
208
|
// and re-vended: signatures expire, and a token that would have died during
|
|
161
209
|
// the wait is simply never the one reused. `retryingFetch` returns its input
|
|
@@ -170,7 +218,7 @@ async function buildTransport(t, retryOnThrottle) {
|
|
|
170
218
|
// credential is still vended per request. Passing `undefined` is the
|
|
171
219
|
// default global `fetch`, which is byte-identical to every release before
|
|
172
220
|
// the seam existed.
|
|
173
|
-
return new httpMod.StreamableHTTPClientTransport(
|
|
221
|
+
return new httpMod.StreamableHTTPClientTransport((0, transportUrl_js_1.transportUrl)(t.url, 'mcpClient'), {
|
|
174
222
|
fetch: (0, throttleRetry_js_1.retryingFetch)((0, gatewayTransport_js_1.createVendingFetch)(t, t.fetch), retryOnThrottle),
|
|
175
223
|
});
|
|
176
224
|
}
|
|
@@ -179,13 +227,29 @@ async function buildTransport(t, retryOnThrottle) {
|
|
|
179
227
|
// hands the custom fetch, so a signer sees the static headers and has the
|
|
180
228
|
// final word over the bytes — see `McpHttpTransport.fetch`.
|
|
181
229
|
const httpFetch = (0, throttleRetry_js_1.retryingFetch)(t.fetch, retryOnThrottle);
|
|
182
|
-
return new httpMod.StreamableHTTPClientTransport(
|
|
230
|
+
return new httpMod.StreamableHTTPClientTransport((0, transportUrl_js_1.transportUrl)(t.url, 'mcpClient'), {
|
|
183
231
|
...(t.headers && { requestInit: { headers: { ...t.headers } } }),
|
|
184
232
|
...(httpFetch && { fetch: httpFetch }),
|
|
185
233
|
});
|
|
186
234
|
}
|
|
235
|
+
/** The Node loader path for Streamable HTTP — reached only with no `sdk`. */
|
|
236
|
+
function loadHttpModule(transport) {
|
|
237
|
+
try {
|
|
238
|
+
return (0, lazyRequire_js_1.lazyRequire)('@modelcontextprotocol/sdk/client/streamableHttp.js');
|
|
239
|
+
}
|
|
240
|
+
catch (err) {
|
|
241
|
+
throw new Error((0, sdkLoadFailure_js_1.sdkLoadFailure)(err, {
|
|
242
|
+
notInstalled: `mcpClient(${transport}) requires @modelcontextprotocol/sdk/client/streamableHttp.js — ` +
|
|
243
|
+
'check that @modelcontextprotocol/sdk is installed at the latest version.',
|
|
244
|
+
caller: `mcpClient(${transport})`,
|
|
245
|
+
specifier: '@modelcontextprotocol/sdk/client/streamableHttp.js',
|
|
246
|
+
instead: 'Pass `sdk` (the two SDK modules, imported statically) or `connection` ' +
|
|
247
|
+
'(a client you connected yourself).',
|
|
248
|
+
}));
|
|
249
|
+
}
|
|
250
|
+
}
|
|
187
251
|
// ─── Tool wrapping ─────────────────────────────────────────────────
|
|
188
|
-
function wrapMcpTool(serverName,
|
|
252
|
+
function wrapMcpTool(serverName, connection, mcp, signal) {
|
|
189
253
|
const tool = {
|
|
190
254
|
schema: {
|
|
191
255
|
name: mcp.name,
|
|
@@ -217,8 +281,8 @@ function wrapMcpTool(serverName, sdk, mcp, signal) {
|
|
|
217
281
|
// `resultSchema` (2nd arg) is left to the SDK's own default.
|
|
218
282
|
const params = { name: mcp.name, arguments: argsObj };
|
|
219
283
|
const result = signal
|
|
220
|
-
? await
|
|
221
|
-
: await
|
|
284
|
+
? await connection.callTool(params, undefined, { signal })
|
|
285
|
+
: await connection.callTool(params);
|
|
222
286
|
return readToolResult(result, mcp.name, serverName);
|
|
223
287
|
},
|
|
224
288
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcpClient.js","sourceRoot":"","sources":["../../../src/lib/mcp/mcpClient.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;;;
|
|
1
|
+
{"version":3,"file":"mcpClient.js","sourceRoot":"","sources":["../../../src/lib/mcp/mcpClient.ts"],"names":[],"mappings":"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"}
|