@better-agent/core 0.1.0-beta.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/README.md +3 -0
- package/dist/agent/constants.mjs +6 -0
- package/dist/agent/constants.mjs.map +1 -0
- package/dist/agent/define-agent.d.mts +29 -0
- package/dist/agent/define-agent.d.mts.map +1 -0
- package/dist/agent/define-agent.mjs +27 -0
- package/dist/agent/define-agent.mjs.map +1 -0
- package/dist/agent/index.d.mts +2 -0
- package/dist/agent/types.d.mts +216 -0
- package/dist/agent/types.d.mts.map +1 -0
- package/dist/agent/validation.mjs +64 -0
- package/dist/agent/validation.mjs.map +1 -0
- package/dist/api.d.mts +8 -0
- package/dist/api.d.mts.map +1 -0
- package/dist/api.mjs +63 -0
- package/dist/api.mjs.map +1 -0
- package/dist/app/config.mjs +43 -0
- package/dist/app/config.mjs.map +1 -0
- package/dist/app/create-app.d.mts +36 -0
- package/dist/app/create-app.d.mts.map +1 -0
- package/dist/app/create-app.mjs +132 -0
- package/dist/app/create-app.mjs.map +1 -0
- package/dist/app/registry.mjs +43 -0
- package/dist/app/registry.mjs.map +1 -0
- package/dist/app/types.d.mts +142 -0
- package/dist/app/types.d.mts.map +1 -0
- package/dist/events/constants.d.mts +49 -0
- package/dist/events/constants.d.mts.map +1 -0
- package/dist/events/constants.mjs +46 -0
- package/dist/events/constants.mjs.map +1 -0
- package/dist/events/index.d.mts +4 -0
- package/dist/events/index.mjs +3 -0
- package/dist/events/types.d.mts +289 -0
- package/dist/events/types.d.mts.map +1 -0
- package/dist/index.d.mts +23 -0
- package/dist/index.mjs +14 -0
- package/dist/internal/id.mjs +21 -0
- package/dist/internal/id.mjs.map +1 -0
- package/dist/internal/types.d.mts +11 -0
- package/dist/internal/types.d.mts.map +1 -0
- package/dist/mcp/error/mcp-client-error.d.mts +36 -0
- package/dist/mcp/error/mcp-client-error.d.mts.map +1 -0
- package/dist/mcp/error/mcp-client-error.mjs +33 -0
- package/dist/mcp/error/mcp-client-error.mjs.map +1 -0
- package/dist/mcp/index.d.mts +8 -0
- package/dist/mcp/index.mjs +9 -0
- package/dist/mcp/tool/json-rpc-message.d.mts +50 -0
- package/dist/mcp/tool/json-rpc-message.d.mts.map +1 -0
- package/dist/mcp/tool/json-rpc-message.mjs +84 -0
- package/dist/mcp/tool/json-rpc-message.mjs.map +1 -0
- package/dist/mcp/tool/mcp-client.d.mts +71 -0
- package/dist/mcp/tool/mcp-client.d.mts.map +1 -0
- package/dist/mcp/tool/mcp-client.mjs +304 -0
- package/dist/mcp/tool/mcp-client.mjs.map +1 -0
- package/dist/mcp/tool/mcp-http-transport.d.mts +62 -0
- package/dist/mcp/tool/mcp-http-transport.d.mts.map +1 -0
- package/dist/mcp/tool/mcp-http-transport.mjs +307 -0
- package/dist/mcp/tool/mcp-http-transport.mjs.map +1 -0
- package/dist/mcp/tool/mcp-tools.d.mts +20 -0
- package/dist/mcp/tool/mcp-tools.d.mts.map +1 -0
- package/dist/mcp/tool/mcp-tools.mjs +73 -0
- package/dist/mcp/tool/mcp-tools.mjs.map +1 -0
- package/dist/mcp/tool/mcp-transport.d.mts +81 -0
- package/dist/mcp/tool/mcp-transport.d.mts.map +1 -0
- package/dist/mcp/tool/mcp-transport.mjs +11 -0
- package/dist/mcp/tool/mcp-transport.mjs.map +1 -0
- package/dist/mcp/tool/types.d.mts +230 -0
- package/dist/mcp/tool/types.d.mts.map +1 -0
- package/dist/mcp/tool/types.mjs +19 -0
- package/dist/mcp/tool/types.mjs.map +1 -0
- package/dist/persistence/index.d.mts +3 -0
- package/dist/persistence/index.mjs +3 -0
- package/dist/persistence/memory.d.mts +21 -0
- package/dist/persistence/memory.d.mts.map +1 -0
- package/dist/persistence/memory.mjs +107 -0
- package/dist/persistence/memory.mjs.map +1 -0
- package/dist/persistence/types.d.mts +124 -0
- package/dist/persistence/types.d.mts.map +1 -0
- package/dist/plugins/index.d.mts +2 -0
- package/dist/plugins/runtime.d.mts +17 -0
- package/dist/plugins/runtime.d.mts.map +1 -0
- package/dist/plugins/runtime.mjs +456 -0
- package/dist/plugins/runtime.mjs.map +1 -0
- package/dist/plugins/types.d.mts +344 -0
- package/dist/plugins/types.d.mts.map +1 -0
- package/dist/providers/index.d.mts +9 -0
- package/dist/providers/index.mjs +0 -0
- package/dist/providers/types/capabilities.d.mts +153 -0
- package/dist/providers/types/capabilities.d.mts.map +1 -0
- package/dist/providers/types/content.d.mts +125 -0
- package/dist/providers/types/content.d.mts.map +1 -0
- package/dist/providers/types/conversation.d.mts +32 -0
- package/dist/providers/types/conversation.d.mts.map +1 -0
- package/dist/providers/types/index.d.mts +8 -0
- package/dist/providers/types/input.d.mts +74 -0
- package/dist/providers/types/input.d.mts.map +1 -0
- package/dist/providers/types/model.d.mts +68 -0
- package/dist/providers/types/model.d.mts.map +1 -0
- package/dist/providers/types/output.d.mts +29 -0
- package/dist/providers/types/output.d.mts.map +1 -0
- package/dist/providers/types/response.d.mts +35 -0
- package/dist/providers/types/response.d.mts.map +1 -0
- package/dist/providers/types/tool-calls.d.mts +51 -0
- package/dist/providers/types/tool-calls.d.mts.map +1 -0
- package/dist/run/agent-loop.mjs +231 -0
- package/dist/run/agent-loop.mjs.map +1 -0
- package/dist/run/event-queue.mjs +67 -0
- package/dist/run/event-queue.mjs.map +1 -0
- package/dist/run/execute-tool-calls.mjs +550 -0
- package/dist/run/execute-tool-calls.mjs.map +1 -0
- package/dist/run/execution.mjs +93 -0
- package/dist/run/execution.mjs.map +1 -0
- package/dist/run/helpers.mjs +466 -0
- package/dist/run/helpers.mjs.map +1 -0
- package/dist/run/hooks.mjs +124 -0
- package/dist/run/hooks.mjs.map +1 -0
- package/dist/run/index.d.mts +4 -0
- package/dist/run/messages.d.mts +8 -0
- package/dist/run/messages.d.mts.map +1 -0
- package/dist/run/messages.mjs +83 -0
- package/dist/run/messages.mjs.map +1 -0
- package/dist/run/model-strategy.mjs +105 -0
- package/dist/run/model-strategy.mjs.map +1 -0
- package/dist/run/output-errors.d.mts +75 -0
- package/dist/run/output-errors.d.mts.map +1 -0
- package/dist/run/pending-tools.d.mts +1 -0
- package/dist/run/pending-tools.mjs +185 -0
- package/dist/run/pending-tools.mjs.map +1 -0
- package/dist/run/registry.mjs +22 -0
- package/dist/run/registry.mjs.map +1 -0
- package/dist/run/runtime.d.mts +19 -0
- package/dist/run/runtime.d.mts.map +1 -0
- package/dist/run/runtime.mjs +491 -0
- package/dist/run/runtime.mjs.map +1 -0
- package/dist/run/stop-conditions.mjs +41 -0
- package/dist/run/stop-conditions.mjs.map +1 -0
- package/dist/run/types.d.mts +348 -0
- package/dist/run/types.d.mts.map +1 -0
- package/dist/schema/index.d.mts +2 -0
- package/dist/schema/resolve-json-schema.d.mts +12 -0
- package/dist/schema/resolve-json-schema.d.mts.map +1 -0
- package/dist/schema/resolve-json-schema.mjs +167 -0
- package/dist/schema/resolve-json-schema.mjs.map +1 -0
- package/dist/schema/types.d.mts +27 -0
- package/dist/schema/types.d.mts.map +1 -0
- package/dist/server/create-server.d.mts +21 -0
- package/dist/server/create-server.d.mts.map +1 -0
- package/dist/server/create-server.mjs +107 -0
- package/dist/server/create-server.mjs.map +1 -0
- package/dist/server/http.mjs +182 -0
- package/dist/server/http.mjs.map +1 -0
- package/dist/server/index.d.mts +3 -0
- package/dist/server/index.mjs +3 -0
- package/dist/server/routes.mjs +399 -0
- package/dist/server/routes.mjs.map +1 -0
- package/dist/server/types.d.mts +31 -0
- package/dist/server/types.d.mts.map +1 -0
- package/dist/tools/constants.d.mts +12 -0
- package/dist/tools/constants.d.mts.map +1 -0
- package/dist/tools/constants.mjs +13 -0
- package/dist/tools/constants.mjs.map +1 -0
- package/dist/tools/define-tool.d.mts +25 -0
- package/dist/tools/define-tool.d.mts.map +1 -0
- package/dist/tools/define-tool.mjs +76 -0
- package/dist/tools/define-tool.mjs.map +1 -0
- package/dist/tools/index.d.mts +5 -0
- package/dist/tools/lazy-tools.d.mts +49 -0
- package/dist/tools/lazy-tools.d.mts.map +1 -0
- package/dist/tools/lazy-tools.mjs +87 -0
- package/dist/tools/lazy-tools.mjs.map +1 -0
- package/dist/tools/resolve-tools.d.mts +12 -0
- package/dist/tools/resolve-tools.d.mts.map +1 -0
- package/dist/tools/resolve-tools.mjs +86 -0
- package/dist/tools/resolve-tools.mjs.map +1 -0
- package/dist/tools/types.d.mts +318 -0
- package/dist/tools/types.d.mts.map +1 -0
- package/dist/tools/validation.mjs +23 -0
- package/dist/tools/validation.mjs.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { MCPClientError } from "../error/mcp-client-error.mjs";
|
|
2
|
+
import { MCPTransport, MCPTransportConfig } from "./mcp-transport.mjs";
|
|
3
|
+
import { ClientCapabilities, ListPromptsResult, ListResourceTemplatesResult, ListResourcesResult, ListToolsResult, MCPCallToolParams, MCPCallToolResult, MCPGetPromptParams, MCPGetPromptResult, MCPReadResourceParams, MCPReadResourceResult, PaginatedRequest, RequestOptions } from "./types.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/mcp/tool/mcp-client.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* MCP client configuration.
|
|
8
|
+
*/
|
|
9
|
+
interface MCPClientConfig {
|
|
10
|
+
/** Transport config or a custom transport instance. */
|
|
11
|
+
transport: MCPTransportConfig | MCPTransport;
|
|
12
|
+
/** Optional client name. Defaults to `"better-agent-mcp-client"`. */
|
|
13
|
+
name?: string;
|
|
14
|
+
/** Optional client version. Defaults to `"1.0.0"`. */
|
|
15
|
+
version?: string;
|
|
16
|
+
/** Optional callback for uncaught errors. */
|
|
17
|
+
onUncaughtError?: (error: MCPClientError) => void;
|
|
18
|
+
/** Optional client capabilities to advertise. */
|
|
19
|
+
capabilities?: ClientCapabilities;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* MCP client interface.
|
|
23
|
+
*/
|
|
24
|
+
interface MCPClient {
|
|
25
|
+
/** Lists available tools from the server. */
|
|
26
|
+
listTools(options?: {
|
|
27
|
+
params?: PaginatedRequest;
|
|
28
|
+
options?: RequestOptions;
|
|
29
|
+
}): Promise<ListToolsResult>;
|
|
30
|
+
/** Calls a tool on the server. */
|
|
31
|
+
callTool(params: MCPCallToolParams, options?: RequestOptions): Promise<MCPCallToolResult>;
|
|
32
|
+
/** Lists available resources. */
|
|
33
|
+
listResources(options?: {
|
|
34
|
+
params?: PaginatedRequest;
|
|
35
|
+
options?: RequestOptions;
|
|
36
|
+
}): Promise<ListResourcesResult>;
|
|
37
|
+
/** Lists resource templates. */
|
|
38
|
+
listResourceTemplates(options?: {
|
|
39
|
+
options?: RequestOptions;
|
|
40
|
+
}): Promise<ListResourceTemplatesResult>;
|
|
41
|
+
/** Reads a resource. */
|
|
42
|
+
readResource(params: MCPReadResourceParams, options?: RequestOptions): Promise<MCPReadResourceResult>;
|
|
43
|
+
/** Lists available prompts. */
|
|
44
|
+
listPrompts(options?: {
|
|
45
|
+
params?: PaginatedRequest;
|
|
46
|
+
options?: RequestOptions;
|
|
47
|
+
}): Promise<ListPromptsResult>;
|
|
48
|
+
/** Gets a prompt. */
|
|
49
|
+
getPrompt(params: MCPGetPromptParams, options?: RequestOptions): Promise<MCPGetPromptResult>;
|
|
50
|
+
/** Closes the connection. */
|
|
51
|
+
close(): Promise<void>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Creates and initializes an MCP client.
|
|
55
|
+
*
|
|
56
|
+
* @param config MCP client configuration.
|
|
57
|
+
* @returns An initialized MCP client.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* const client = await createMCPClient({
|
|
62
|
+
* transport: { type: "http", url: "http://localhost:3000/mcp" },
|
|
63
|
+
* });
|
|
64
|
+
*
|
|
65
|
+
* const tools = await client.listTools();
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
declare function createMCPClient(config: MCPClientConfig): Promise<MCPClient>;
|
|
69
|
+
//#endregion
|
|
70
|
+
export { MCPClient, MCPClientConfig, createMCPClient };
|
|
71
|
+
//# sourceMappingURL=mcp-client.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-client.d.mts","names":[],"sources":["../../../src/mcp/tool/mcp-client.ts"],"mappings":";;;;;;;AAmCA;UAAiB,eAAA;;EAEb,SAAA,EAAW,kBAAA,GAAqB,YAAA;EAAA;EAGhC,IAAA;EASe;EANf,OAAA;EAMiC;EAHjC,eAAA,IAAmB,KAAA,EAAO,cAAA;EATf;EAYX,YAAA,GAAe,kBAAA;AAAA;;;;UAMF,SAAA;EANb;EAQA,SAAA,CAAU,OAAA;IACN,MAAA,GAAS,gBAAA;IACT,OAAA,GAAU,cAAA;EAAA,IACV,OAAA,CAAQ,eAAA;EALU;EAQtB,QAAA,CAAS,MAAA,EAAQ,iBAAA,EAAmB,OAAA,GAAU,cAAA,GAAiB,OAAA,CAAQ,iBAAA;EAL1D;EAQb,aAAA,CAAc,OAAA;IACV,MAAA,GAAS,gBAAA;IACT,OAAA,GAAU,cAAA;EAAA,IACV,OAAA,CAAQ,mBAAA;EANkC;EAS9C,qBAAA,CAAsB,OAAA;IAClB,OAAA,GAAU,cAAA;EAAA,IACV,OAAA,CAAQ,2BAAA;EANE;EASd,YAAA,CACI,MAAA,EAAQ,qBAAA,EACR,OAAA,GAAU,cAAA,GACX,OAAA,CAAQ,qBAAA;EAXP;EAcJ,WAAA,CAAY,OAAA;IACR,MAAA,GAAS,gBAAA;IACT,OAAA,GAAU,cAAA;EAAA,IACV,OAAA,CAAQ,iBAAA;EAPE;EAUd,SAAA,CAAU,MAAA,EAAQ,kBAAA,EAAoB,OAAA,GAAU,cAAA,GAAiB,OAAA,CAAQ,kBAAA;EATtE;EAYH,KAAA,IAAS,OAAA;AAAA;;;;;;;;;;;;;;;;iBAkBS,eAAA,CAAgB,MAAA,EAAQ,eAAA,GAAkB,OAAA,CAAQ,SAAA"}
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import { MCPClientError } from "../error/mcp-client-error.mjs";
|
|
2
|
+
import { isJSONRPCError, isJSONRPCResponse } from "./json-rpc-message.mjs";
|
|
3
|
+
import { LATEST_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS } from "./types.mjs";
|
|
4
|
+
import { HttpMCPTransport } from "./mcp-http-transport.mjs";
|
|
5
|
+
import { isCustomMCPTransport } from "./mcp-transport.mjs";
|
|
6
|
+
|
|
7
|
+
//#region src/mcp/tool/mcp-client.ts
|
|
8
|
+
/**
|
|
9
|
+
* Creates and initializes an MCP client.
|
|
10
|
+
*
|
|
11
|
+
* @param config MCP client configuration.
|
|
12
|
+
* @returns An initialized MCP client.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* const client = await createMCPClient({
|
|
17
|
+
* transport: { type: "http", url: "http://localhost:3000/mcp" },
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* const tools = await client.listTools();
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
async function createMCPClient(config) {
|
|
24
|
+
const client = new DefaultMCPClient(config);
|
|
25
|
+
await client.init();
|
|
26
|
+
return client;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Default MCP client implementation.
|
|
30
|
+
*/
|
|
31
|
+
var DefaultMCPClient = class {
|
|
32
|
+
transport;
|
|
33
|
+
onUncaughtError;
|
|
34
|
+
clientInfo;
|
|
35
|
+
clientCapabilities;
|
|
36
|
+
requestMessageId = 0;
|
|
37
|
+
responseHandlers = /* @__PURE__ */ new Map();
|
|
38
|
+
serverCapabilities = {};
|
|
39
|
+
isClosed = true;
|
|
40
|
+
constructor({ transport: transportConfig, name = "better-agent-mcp-client", version = "1.0.0", onUncaughtError, capabilities }) {
|
|
41
|
+
this.onUncaughtError = onUncaughtError;
|
|
42
|
+
this.clientCapabilities = capabilities ?? {};
|
|
43
|
+
if (isCustomMCPTransport(transportConfig)) this.transport = transportConfig;
|
|
44
|
+
else this.transport = this.createTransport(transportConfig);
|
|
45
|
+
this.transport.onclose = () => this.onClose();
|
|
46
|
+
this.transport.onerror = (error) => this.onError(error);
|
|
47
|
+
this.transport.onmessage = (message) => {
|
|
48
|
+
if ("id" in message) if ("error" in message || "result" in message) this.onResponse(message);
|
|
49
|
+
else this.onError(/* @__PURE__ */ new Error("Server requests not supported"));
|
|
50
|
+
};
|
|
51
|
+
this.clientInfo = {
|
|
52
|
+
name,
|
|
53
|
+
version
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Creates a transport from config.
|
|
58
|
+
*/
|
|
59
|
+
createTransport(config) {
|
|
60
|
+
switch (config.type) {
|
|
61
|
+
case "http": return new HttpMCPTransport({
|
|
62
|
+
url: config.url,
|
|
63
|
+
headers: config.headers,
|
|
64
|
+
redirect: config.redirect,
|
|
65
|
+
sessionId: config.sessionId,
|
|
66
|
+
advanced: config.advanced
|
|
67
|
+
});
|
|
68
|
+
case "sse": return new HttpMCPTransport({
|
|
69
|
+
url: config.url,
|
|
70
|
+
headers: config.headers,
|
|
71
|
+
redirect: config.redirect,
|
|
72
|
+
sessionId: void 0,
|
|
73
|
+
advanced: config.advanced
|
|
74
|
+
});
|
|
75
|
+
default: throw new Error(`Unsupported transport type: ${config.type}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Initializes the client and completes the MCP handshake.
|
|
80
|
+
*/
|
|
81
|
+
async init() {
|
|
82
|
+
try {
|
|
83
|
+
await this.transport.start();
|
|
84
|
+
this.isClosed = false;
|
|
85
|
+
const result = await this.request({
|
|
86
|
+
method: "initialize",
|
|
87
|
+
params: {
|
|
88
|
+
protocolVersion: LATEST_PROTOCOL_VERSION,
|
|
89
|
+
capabilities: this.clientCapabilities,
|
|
90
|
+
clientInfo: this.clientInfo
|
|
91
|
+
},
|
|
92
|
+
options: void 0
|
|
93
|
+
});
|
|
94
|
+
if (!SUPPORTED_PROTOCOL_VERSIONS.includes(result.protocolVersion)) throw new Error(`Server's protocol version is not supported: ${result.protocolVersion}`);
|
|
95
|
+
this.serverCapabilities = result.capabilities;
|
|
96
|
+
await this.notification({ method: "notifications/initialized" });
|
|
97
|
+
return this;
|
|
98
|
+
} catch (error) {
|
|
99
|
+
await this.close();
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Closes the connection and cleans up.
|
|
105
|
+
*/
|
|
106
|
+
async close() {
|
|
107
|
+
if (this.isClosed) return;
|
|
108
|
+
await this.transport.close();
|
|
109
|
+
this.onClose();
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Checks whether the server supports a capability.
|
|
113
|
+
*/
|
|
114
|
+
assertCapability(method) {
|
|
115
|
+
switch (method) {
|
|
116
|
+
case "initialize": break;
|
|
117
|
+
case "tools/list":
|
|
118
|
+
case "tools/call":
|
|
119
|
+
if (!this.serverCapabilities.tools) throw new Error("Server does not support tools");
|
|
120
|
+
break;
|
|
121
|
+
case "resources/list":
|
|
122
|
+
case "resources/read":
|
|
123
|
+
case "resources/templates/list":
|
|
124
|
+
if (!this.serverCapabilities.resources) throw new Error("Server does not support resources");
|
|
125
|
+
break;
|
|
126
|
+
case "prompts/list":
|
|
127
|
+
case "prompts/get":
|
|
128
|
+
if (!this.serverCapabilities.prompts) throw new Error("Server does not support prompts");
|
|
129
|
+
break;
|
|
130
|
+
default: throw new Error(`Unsupported method: ${method}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Send a JSON-RPC request and wait for response.
|
|
135
|
+
*/
|
|
136
|
+
async request({ method, params, options }) {
|
|
137
|
+
return new Promise((resolve, reject) => {
|
|
138
|
+
if (this.isClosed) return reject(/* @__PURE__ */ new Error("Attempted to send a request from a closed client"));
|
|
139
|
+
this.assertCapability(method);
|
|
140
|
+
const signal = options?.signal;
|
|
141
|
+
signal?.throwIfAborted();
|
|
142
|
+
const messageId = this.requestMessageId++;
|
|
143
|
+
const jsonrpcRequest = {
|
|
144
|
+
jsonrpc: "2.0",
|
|
145
|
+
id: messageId,
|
|
146
|
+
method,
|
|
147
|
+
params
|
|
148
|
+
};
|
|
149
|
+
const cleanup = () => {
|
|
150
|
+
this.responseHandlers.delete(messageId);
|
|
151
|
+
};
|
|
152
|
+
let timeoutId;
|
|
153
|
+
if (options?.timeout !== void 0) timeoutId = setTimeout(() => {
|
|
154
|
+
cleanup();
|
|
155
|
+
reject(/* @__PURE__ */ new Error(`Request timed out after ${options.timeout}ms`));
|
|
156
|
+
}, options.timeout);
|
|
157
|
+
const cleanupWithTimeout = () => {
|
|
158
|
+
cleanup();
|
|
159
|
+
if (timeoutId !== void 0) clearTimeout(timeoutId);
|
|
160
|
+
};
|
|
161
|
+
const abortHandler = () => {
|
|
162
|
+
cleanupWithTimeout();
|
|
163
|
+
reject(/* @__PURE__ */ new Error(`Request was aborted: ${signal?.reason || "Unknown reason"}`));
|
|
164
|
+
};
|
|
165
|
+
signal?.addEventListener("abort", abortHandler);
|
|
166
|
+
this.responseHandlers.set(messageId, (response) => {
|
|
167
|
+
signal?.removeEventListener("abort", abortHandler);
|
|
168
|
+
if (signal?.aborted) {
|
|
169
|
+
cleanupWithTimeout();
|
|
170
|
+
return reject(/* @__PURE__ */ new Error(`Request was aborted: ${signal.reason}`));
|
|
171
|
+
}
|
|
172
|
+
if (response instanceof MCPClientError) {
|
|
173
|
+
cleanupWithTimeout();
|
|
174
|
+
return reject(response);
|
|
175
|
+
}
|
|
176
|
+
if (isJSONRPCError(response)) {
|
|
177
|
+
cleanupWithTimeout();
|
|
178
|
+
const error = new Error(String(response.error.message));
|
|
179
|
+
Object.assign(error, { jsonRpcCode: response.error.code });
|
|
180
|
+
return reject(error);
|
|
181
|
+
}
|
|
182
|
+
if (!isJSONRPCResponse(response)) {
|
|
183
|
+
cleanupWithTimeout();
|
|
184
|
+
return reject(new MCPClientError({ message: "Received invalid JSON-RPC response shape." }));
|
|
185
|
+
}
|
|
186
|
+
cleanupWithTimeout();
|
|
187
|
+
resolve(response.result);
|
|
188
|
+
});
|
|
189
|
+
this.transport.send(jsonrpcRequest).catch((error) => {
|
|
190
|
+
signal?.removeEventListener("abort", abortHandler);
|
|
191
|
+
cleanupWithTimeout();
|
|
192
|
+
reject(error);
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Send a JSON-RPC notification (no response expected).
|
|
198
|
+
*/
|
|
199
|
+
async notification({ method, params }) {
|
|
200
|
+
if (this.isClosed) throw new Error("Attempted to send a notification from a closed client");
|
|
201
|
+
const jsonrpcNotification = {
|
|
202
|
+
jsonrpc: "2.0",
|
|
203
|
+
method,
|
|
204
|
+
params
|
|
205
|
+
};
|
|
206
|
+
await this.transport.send(jsonrpcNotification);
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Handle transport closure.
|
|
210
|
+
*/
|
|
211
|
+
onClose() {
|
|
212
|
+
if (this.isClosed) return;
|
|
213
|
+
this.isClosed = true;
|
|
214
|
+
const error = /* @__PURE__ */ new Error("Connection closed");
|
|
215
|
+
for (const handler of this.responseHandlers.values()) handler({
|
|
216
|
+
jsonrpc: "2.0",
|
|
217
|
+
id: -1,
|
|
218
|
+
error: {
|
|
219
|
+
code: -32e3,
|
|
220
|
+
message: error.message
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
this.responseHandlers.clear();
|
|
224
|
+
this.onUncaughtError?.(error);
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Handle transport errors.
|
|
228
|
+
*/
|
|
229
|
+
onError(error) {
|
|
230
|
+
this.onUncaughtError?.(error);
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Handle incoming JSON-RPC responses.
|
|
234
|
+
*/
|
|
235
|
+
onResponse(response) {
|
|
236
|
+
const messageId = Number(response.id);
|
|
237
|
+
const handler = this.responseHandlers.get(messageId);
|
|
238
|
+
if (handler === void 0) {
|
|
239
|
+
this.onError(new MCPClientError({
|
|
240
|
+
message: `Protocol error: Received a response for an unknown message ID: ${JSON.stringify(response)}`,
|
|
241
|
+
context: {
|
|
242
|
+
messageId,
|
|
243
|
+
response
|
|
244
|
+
}
|
|
245
|
+
}));
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
this.responseHandlers.delete(messageId);
|
|
249
|
+
handler(response);
|
|
250
|
+
}
|
|
251
|
+
async listTools({ params, options } = {}) {
|
|
252
|
+
return this.request({
|
|
253
|
+
method: "tools/list",
|
|
254
|
+
params,
|
|
255
|
+
options
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
async callTool(params, options) {
|
|
259
|
+
return this.request({
|
|
260
|
+
method: "tools/call",
|
|
261
|
+
params,
|
|
262
|
+
options
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
async listResources({ params, options } = {}) {
|
|
266
|
+
return this.request({
|
|
267
|
+
method: "resources/list",
|
|
268
|
+
params,
|
|
269
|
+
options
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
async listResourceTemplates({ options } = {}) {
|
|
273
|
+
return this.request({
|
|
274
|
+
method: "resources/templates/list",
|
|
275
|
+
params: void 0,
|
|
276
|
+
options
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
async readResource(params, options) {
|
|
280
|
+
return this.request({
|
|
281
|
+
method: "resources/read",
|
|
282
|
+
params,
|
|
283
|
+
options
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
async listPrompts({ params, options } = {}) {
|
|
287
|
+
return this.request({
|
|
288
|
+
method: "prompts/list",
|
|
289
|
+
params,
|
|
290
|
+
options
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
async getPrompt(params, options) {
|
|
294
|
+
return this.request({
|
|
295
|
+
method: "prompts/get",
|
|
296
|
+
params,
|
|
297
|
+
options
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
//#endregion
|
|
303
|
+
export { createMCPClient };
|
|
304
|
+
//# sourceMappingURL=mcp-client.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-client.mjs","names":[],"sources":["../../../src/mcp/tool/mcp-client.ts"],"sourcesContent":["import { MCPClientError } from \"../error/mcp-client-error\";\nimport type {\n JSONRPCError,\n JSONRPCMessage,\n JSONRPCRequest,\n JSONRPCResponse,\n} from \"./json-rpc-message\";\nimport { isJSONRPCError, isJSONRPCResponse } from \"./json-rpc-message\";\nimport { HttpMCPTransport } from \"./mcp-http-transport\";\nimport type { MCPTransport, MCPTransportConfig } from \"./mcp-transport\";\nimport { isCustomMCPTransport } from \"./mcp-transport\";\nimport type {\n ClientCapabilities,\n InitializeParams,\n InitializeResult,\n ListPromptsResult,\n ListResourceTemplatesResult,\n ListResourcesResult,\n ListToolsResult,\n MCPCallToolParams,\n MCPCallToolResult,\n MCPGetPromptParams,\n MCPGetPromptResult,\n MCPImplementationInfo,\n MCPReadResourceParams,\n MCPReadResourceResult,\n PaginatedRequest,\n RequestOptions,\n ServerCapabilities,\n} from \"./types\";\nimport { LATEST_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS } from \"./types\";\n\n/**\n * MCP client configuration.\n */\nexport interface MCPClientConfig {\n /** Transport config or a custom transport instance. */\n transport: MCPTransportConfig | MCPTransport;\n\n /** Optional client name. Defaults to `\"better-agent-mcp-client\"`. */\n name?: string;\n\n /** Optional client version. Defaults to `\"1.0.0\"`. */\n version?: string;\n\n /** Optional callback for uncaught errors. */\n onUncaughtError?: (error: MCPClientError) => void;\n\n /** Optional client capabilities to advertise. */\n capabilities?: ClientCapabilities;\n}\n\n/**\n * MCP client interface.\n */\nexport interface MCPClient {\n /** Lists available tools from the server. */\n listTools(options?: {\n params?: PaginatedRequest;\n options?: RequestOptions;\n }): Promise<ListToolsResult>;\n\n /** Calls a tool on the server. */\n callTool(params: MCPCallToolParams, options?: RequestOptions): Promise<MCPCallToolResult>;\n\n /** Lists available resources. */\n listResources(options?: {\n params?: PaginatedRequest;\n options?: RequestOptions;\n }): Promise<ListResourcesResult>;\n\n /** Lists resource templates. */\n listResourceTemplates(options?: {\n options?: RequestOptions;\n }): Promise<ListResourceTemplatesResult>;\n\n /** Reads a resource. */\n readResource(\n params: MCPReadResourceParams,\n options?: RequestOptions,\n ): Promise<MCPReadResourceResult>;\n\n /** Lists available prompts. */\n listPrompts(options?: {\n params?: PaginatedRequest;\n options?: RequestOptions;\n }): Promise<ListPromptsResult>;\n\n /** Gets a prompt. */\n getPrompt(params: MCPGetPromptParams, options?: RequestOptions): Promise<MCPGetPromptResult>;\n\n /** Closes the connection. */\n close(): Promise<void>;\n}\n\n/**\n * Creates and initializes an MCP client.\n *\n * @param config MCP client configuration.\n * @returns An initialized MCP client.\n *\n * @example\n * ```ts\n * const client = await createMCPClient({\n * transport: { type: \"http\", url: \"http://localhost:3000/mcp\" },\n * });\n *\n * const tools = await client.listTools();\n * ```\n */\nexport async function createMCPClient(config: MCPClientConfig): Promise<MCPClient> {\n const client = new DefaultMCPClient(config);\n await client.init();\n return client;\n}\n\n/**\n * Default MCP client implementation.\n */\nclass DefaultMCPClient implements MCPClient {\n private transport: MCPTransport;\n private onUncaughtError: ((error: MCPClientError) => void) | undefined;\n private clientInfo: MCPImplementationInfo;\n private clientCapabilities: ClientCapabilities;\n private requestMessageId = 0;\n private responseHandlers: Map<\n number,\n (response: JSONRPCResponse | JSONRPCError | MCPClientError) => void\n > = new Map();\n private serverCapabilities: ServerCapabilities = {};\n private isClosed = true;\n\n constructor({\n transport: transportConfig,\n name = \"better-agent-mcp-client\",\n version = \"1.0.0\",\n onUncaughtError,\n capabilities,\n }: MCPClientConfig) {\n this.onUncaughtError = onUncaughtError;\n this.clientCapabilities = capabilities ?? {};\n\n // Reuse a custom transport when one is provided.\n if (isCustomMCPTransport(transportConfig)) {\n this.transport = transportConfig;\n } else {\n this.transport = this.createTransport(transportConfig);\n }\n\n // Map transport lifecycle into the client's request/response bookkeeping.\n this.transport.onclose = () => this.onClose();\n this.transport.onerror = (error: MCPClientError) => this.onError(error);\n this.transport.onmessage = (message: JSONRPCMessage) => {\n // Handle requests vs responses/notifications\n if (\"id\" in message) {\n if (\"error\" in message || \"result\" in message) {\n this.onResponse(message as JSONRPCResponse | JSONRPCError);\n } else {\n // Server-initiated requests are not supported yet.\n this.onError(new Error(\"Server requests not supported\") as MCPClientError);\n }\n } else {\n // Notifications are ignored for now.\n }\n };\n\n this.clientInfo = { name, version };\n }\n\n /**\n * Creates a transport from config.\n */\n private createTransport(config: MCPTransportConfig): MCPTransport {\n switch (config.type) {\n case \"http\":\n return new HttpMCPTransport({\n url: config.url,\n headers: config.headers,\n redirect: config.redirect,\n sessionId: config.sessionId,\n advanced: config.advanced,\n });\n case \"sse\":\n // SSE uses the same transport implementation with an inbound SSE channel.\n return new HttpMCPTransport({\n url: config.url,\n headers: config.headers,\n redirect: config.redirect,\n sessionId: undefined,\n advanced: config.advanced,\n });\n default:\n throw new Error(`Unsupported transport type: ${(config as { type: string }).type}`);\n }\n }\n\n /**\n * Initializes the client and completes the MCP handshake.\n */\n async init(): Promise<this> {\n try {\n await this.transport.start();\n this.isClosed = false;\n\n const result = await this.request<InitializeResult>({\n method: \"initialize\",\n params: {\n protocolVersion: LATEST_PROTOCOL_VERSION,\n capabilities: this.clientCapabilities,\n clientInfo: this.clientInfo,\n } as InitializeParams,\n options: undefined,\n });\n\n // Fail fast on unsupported protocol versions.\n const supportedVersions: readonly string[] = SUPPORTED_PROTOCOL_VERSIONS;\n if (!supportedVersions.includes(result.protocolVersion)) {\n throw new Error(\n `Server's protocol version is not supported: ${result.protocolVersion}`,\n );\n }\n\n this.serverCapabilities = result.capabilities;\n\n // Finish the required post-initialize notification.\n await this.notification({ method: \"notifications/initialized\" });\n\n return this;\n } catch (error) {\n await this.close();\n throw error;\n }\n }\n\n /**\n * Closes the connection and cleans up.\n */\n async close(): Promise<void> {\n if (this.isClosed) return;\n await this.transport.close();\n this.onClose();\n }\n\n /**\n * Checks whether the server supports a capability.\n */\n private assertCapability(method: string): void {\n switch (method) {\n case \"initialize\":\n break;\n case \"tools/list\":\n case \"tools/call\":\n if (!this.serverCapabilities.tools) {\n throw new Error(\"Server does not support tools\");\n }\n break;\n case \"resources/list\":\n case \"resources/read\":\n case \"resources/templates/list\":\n if (!this.serverCapabilities.resources) {\n throw new Error(\"Server does not support resources\");\n }\n break;\n case \"prompts/list\":\n case \"prompts/get\":\n if (!this.serverCapabilities.prompts) {\n throw new Error(\"Server does not support prompts\");\n }\n break;\n default:\n throw new Error(`Unsupported method: ${method}`);\n }\n }\n\n /**\n * Send a JSON-RPC request and wait for response.\n */\n private async request<T>({\n method,\n params,\n options,\n }: {\n method: string;\n params: unknown | undefined;\n options: RequestOptions | undefined;\n }): Promise<T> {\n return new Promise((resolve, reject) => {\n if (this.isClosed) {\n return reject(new Error(\"Attempted to send a request from a closed client\"));\n }\n\n this.assertCapability(method);\n\n const signal = options?.signal;\n signal?.throwIfAborted();\n\n const messageId = this.requestMessageId++;\n\n const jsonrpcRequest: JSONRPCRequest = {\n jsonrpc: \"2.0\",\n id: messageId,\n method,\n params: params as Record<string, unknown> | undefined,\n };\n\n const cleanup = () => {\n this.responseHandlers.delete(messageId);\n };\n\n // Set up timeout if specified\n let timeoutId: NodeJS.Timeout | undefined;\n if (options?.timeout !== undefined) {\n timeoutId = setTimeout(() => {\n cleanup();\n reject(new Error(`Request timed out after ${options.timeout}ms`));\n }, options.timeout);\n }\n\n const cleanupWithTimeout = () => {\n cleanup();\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId);\n }\n };\n\n // Add abort signal listener for cancellation\n const abortHandler = () => {\n cleanupWithTimeout();\n reject(new Error(`Request was aborted: ${signal?.reason || \"Unknown reason\"}`));\n };\n\n signal?.addEventListener(\"abort\", abortHandler);\n\n this.responseHandlers.set(messageId, (response) => {\n signal?.removeEventListener(\"abort\", abortHandler);\n\n if (signal?.aborted) {\n cleanupWithTimeout();\n return reject(new Error(`Request was aborted: ${signal.reason}`));\n }\n\n // Check if it's an MCPClientError\n if (response instanceof MCPClientError) {\n cleanupWithTimeout();\n return reject(response);\n }\n\n // Check if it's a JSON-RPC error\n if (isJSONRPCError(response)) {\n cleanupWithTimeout();\n const error = new Error(String(response.error.message)) as MCPClientError;\n // Use Object.assign to set the jsonRpcCode since it's readonly\n Object.assign(error, { jsonRpcCode: response.error.code });\n return reject(error);\n }\n\n if (!isJSONRPCResponse(response)) {\n cleanupWithTimeout();\n return reject(\n new MCPClientError({\n message: \"Received invalid JSON-RPC response shape.\",\n }),\n );\n }\n\n cleanupWithTimeout();\n resolve(response.result as T);\n });\n\n this.transport.send(jsonrpcRequest).catch((error) => {\n signal?.removeEventListener(\"abort\", abortHandler);\n cleanupWithTimeout();\n reject(error);\n });\n });\n }\n\n /**\n * Send a JSON-RPC notification (no response expected).\n */\n private async notification({\n method,\n params,\n }: {\n method: string;\n params?: unknown;\n }): Promise<void> {\n if (this.isClosed) {\n throw new Error(\"Attempted to send a notification from a closed client\");\n }\n\n const jsonrpcNotification = {\n jsonrpc: \"2.0\" as const,\n method,\n params: params as Record<string, unknown> | undefined,\n };\n await this.transport.send(jsonrpcNotification);\n }\n\n /**\n * Handle transport closure.\n */\n private onClose(): void {\n if (this.isClosed) return;\n\n this.isClosed = true;\n const error = new Error(\"Connection closed\") as MCPClientError;\n\n // Reject all pending requests\n for (const handler of this.responseHandlers.values()) {\n handler({\n jsonrpc: \"2.0\",\n id: -1,\n error: { code: -32000, message: error.message },\n } as JSONRPCError);\n }\n\n this.responseHandlers.clear();\n this.onUncaughtError?.(error);\n }\n\n /**\n * Handle transport errors.\n */\n private onError(error: MCPClientError): void {\n this.onUncaughtError?.(error);\n }\n\n /**\n * Handle incoming JSON-RPC responses.\n */\n private onResponse(response: JSONRPCResponse | JSONRPCError): void {\n const messageId = Number(response.id);\n const handler = this.responseHandlers.get(messageId);\n\n if (handler === undefined) {\n this.onError(\n new MCPClientError({\n message: `Protocol error: Received a response for an unknown message ID: ${JSON.stringify(response)}`,\n context: { messageId, response },\n }),\n );\n return;\n }\n\n this.responseHandlers.delete(messageId);\n handler(response);\n }\n\n // Public API implementations\n\n async listTools({\n params,\n options,\n }: {\n params?: PaginatedRequest;\n options?: RequestOptions;\n } = {}): Promise<ListToolsResult> {\n return this.request<ListToolsResult>({\n method: \"tools/list\",\n params,\n options,\n });\n }\n\n async callTool(\n params: MCPCallToolParams,\n options?: RequestOptions,\n ): Promise<MCPCallToolResult> {\n return this.request<MCPCallToolResult>({\n method: \"tools/call\",\n params,\n options,\n });\n }\n\n async listResources({\n params,\n options,\n }: {\n params?: PaginatedRequest;\n options?: RequestOptions;\n } = {}): Promise<ListResourcesResult> {\n return this.request<ListResourcesResult>({\n method: \"resources/list\",\n params,\n options,\n });\n }\n\n async listResourceTemplates({\n options,\n }: {\n options?: RequestOptions;\n } = {}): Promise<ListResourceTemplatesResult> {\n return this.request<ListResourceTemplatesResult>({\n method: \"resources/templates/list\",\n params: undefined,\n options,\n });\n }\n\n async readResource(\n params: MCPReadResourceParams,\n options?: RequestOptions,\n ): Promise<MCPReadResourceResult> {\n return this.request<MCPReadResourceResult>({\n method: \"resources/read\",\n params,\n options,\n });\n }\n\n async listPrompts({\n params,\n options,\n }: {\n params?: PaginatedRequest;\n options?: RequestOptions;\n } = {}): Promise<ListPromptsResult> {\n return this.request<ListPromptsResult>({\n method: \"prompts/list\",\n params,\n options,\n });\n }\n\n async getPrompt(\n params: MCPGetPromptParams,\n options?: RequestOptions,\n ): Promise<MCPGetPromptResult> {\n return this.request<MCPGetPromptResult>({\n method: \"prompts/get\",\n params,\n options,\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { MCPClientError } from "../error/mcp-client-error.mjs";
|
|
2
|
+
import { JSONRPCMessage } from "./json-rpc-message.mjs";
|
|
3
|
+
import { MCPTransport, MCPTransportAdvancedConfig } from "./mcp-transport.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/mcp/tool/mcp-http-transport.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* HTTP transport for MCP using the Streamable HTTP transport pattern.
|
|
8
|
+
*/
|
|
9
|
+
declare class HttpMCPTransport implements MCPTransport {
|
|
10
|
+
private url;
|
|
11
|
+
private abortController?;
|
|
12
|
+
private headers;
|
|
13
|
+
private redirect;
|
|
14
|
+
private sessionId;
|
|
15
|
+
private inboundSseConnection?;
|
|
16
|
+
private lastInboundEventId?;
|
|
17
|
+
private inboundReconnectAttempts;
|
|
18
|
+
private readonly reconnectionOptions;
|
|
19
|
+
onclose: (() => void) | undefined;
|
|
20
|
+
onerror: ((error: MCPClientError) => void) | undefined;
|
|
21
|
+
onmessage: ((message: JSONRPCMessage) => void) | undefined;
|
|
22
|
+
private validateAdvancedNumber;
|
|
23
|
+
constructor({
|
|
24
|
+
url,
|
|
25
|
+
headers,
|
|
26
|
+
redirect,
|
|
27
|
+
sessionId,
|
|
28
|
+
advanced
|
|
29
|
+
}: {
|
|
30
|
+
url: string;
|
|
31
|
+
headers: Record<string, string> | undefined;
|
|
32
|
+
redirect?: RequestRedirect;
|
|
33
|
+
sessionId: string | undefined;
|
|
34
|
+
advanced?: MCPTransportAdvancedConfig;
|
|
35
|
+
});
|
|
36
|
+
/**
|
|
37
|
+
* Builds common headers for requests.
|
|
38
|
+
*/
|
|
39
|
+
private commonHeaders;
|
|
40
|
+
start(): Promise<void>;
|
|
41
|
+
close(): Promise<void>;
|
|
42
|
+
send(message: JSONRPCMessage): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Processes an SSE event stream.
|
|
45
|
+
*/
|
|
46
|
+
private processEventStream;
|
|
47
|
+
/**
|
|
48
|
+
* Calculate next reconnection delay using exponential backoff.
|
|
49
|
+
*/
|
|
50
|
+
private getNextReconnectionDelay;
|
|
51
|
+
/**
|
|
52
|
+
* Schedule SSE reconnection attempt.
|
|
53
|
+
*/
|
|
54
|
+
private scheduleInboundSseReconnection;
|
|
55
|
+
/**
|
|
56
|
+
* Open inbound SSE connection for receiving messages.
|
|
57
|
+
*/
|
|
58
|
+
private openInboundSse;
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
export { HttpMCPTransport };
|
|
62
|
+
//# sourceMappingURL=mcp-http-transport.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-http-transport.d.mts","names":[],"sources":["../../../src/mcp/tool/mcp-http-transport.ts"],"mappings":";;;;;;;AAYA;cAAa,gBAAA,YAA4B,YAAA;EAAA,QAC7B,GAAA;EAAA,QACA,eAAA;EAAA,QACA,OAAA;EAAA,QACA,QAAA;EAAA,QACA,SAAA;EAAA,QACA,oBAAA;EAAA,QAGA,kBAAA;EAAA,QACA,wBAAA;EAAA,iBACS,mBAAA;EAOjB,OAAA;EACA,OAAA,IAAW,KAAA,EAAO,cAAA;EAClB,SAAA,IAAa,OAAA,EAAS,cAAA;EAAA,QAEd,sBAAA;;IAgBJ,GAAA;IACA,OAAA;IACA,QAAA;IACA,SAAA;IACA;EAAA;IAEA,GAAA;IACA,OAAA,EAAS,MAAA;IACT,QAAA,GAAW,eAAA;IACX,SAAA;IACA,QAAA,GAAW,0BAAA;EAAA;EA9CP;;;EAAA,QA+EM,aAAA;EAcR,KAAA,CAAA,GAAS,OAAA;EAWT,KAAA,CAAA,GAAS,OAAA;EAmBT,IAAA,CAAK,OAAA,EAAS,cAAA,GAAiB,OAAA;EAlHpB;;;EAAA,QAkOH,kBAAA;EA1NH;;;EAAA,QA8QH,wBAAA;EA3QA;;;EAAA,QAuRA,8BAAA;EAtQJ;;;EAAA,QA6RU,cAAA;AAAA"}
|