@haikit/mcp 0.0.0-stage → 0.32.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/dist/index.js ADDED
@@ -0,0 +1,412 @@
1
+ /**
2
+ * @haikit/mcp — call MCP servers' tools from inside your own tools.
3
+ *
4
+ * The model never sees an MCP tool. An app declares the server tools it calls,
5
+ * typed by schemas it owns, and calls them from a HaiKIT tool's `run` or an
6
+ * action handler, the way it would call a database: that code decides what the
7
+ * model hears of a result and what the browser shows. So nothing a third-party
8
+ * server says — its tools' names and descriptions, its instructions, its
9
+ * results — reaches the model unless app code puts it there.
10
+ *
11
+ * There is no way to make a HaiKIT `Tool` from an MCP tool here, on purpose:
12
+ * an `McpTool` has no `run`, so `createHai({ tools })` won't take one.
13
+ *
14
+ * Imports only @haikit/core, like the model adapters.
15
+ */
16
+ import { createRequire } from "node:module";
17
+ import { Client, ProtocolError, ProtocolErrorCode, SdkError, SdkErrorCode, } from "@modelcontextprotocol/client";
18
+ import { McpError, McpToolError, isMcpError } from "./errors.js";
19
+ export { McpError, McpToolError, isMcpError, isMcpToolError } from "./errors.js";
20
+ export { textOf } from "./text.js";
21
+ export { http, stdio } from "./transports.js";
22
+ const { version: VERSION } = createRequire(import.meta.url)("../package.json");
23
+ const TIMEOUT_MS = 30_000;
24
+ /** Under the 120 s turn lease the stores default to, which isn't renewed while a tool runs. */
25
+ const MAX_TOTAL_MS = 90_000;
26
+ /** Past the longest timer Node keeps, it fires after about a millisecond. */
27
+ const MAX_TIMER_MS = 2_147_483_647;
28
+ /**
29
+ * The SDK's own checks of a tool's result against the output schema the
30
+ * server declared, as of @modelcontextprotocol/client 2.4: `callTool` throws
31
+ * these, with these codes and words, once the server has answered. A
32
+ * server's own error reads as one only if it has the same code and words.
33
+ */
34
+ const OUTPUT_CHECKS = [
35
+ [ProtocolErrorCode.InvalidRequest, /^Tool .+ has an output schema but did not return structured content$/],
36
+ [ProtocolErrorCode.InvalidParams, /^Structured content does not match the tool's output schema: /],
37
+ [ProtocolErrorCode.InvalidParams, /^Failed to validate structured content: /],
38
+ ];
39
+ /** The connection to an MCP server. Nothing connects until `connect()` or the first call. */
40
+ export function mcpServer(options) {
41
+ return new Connection(options);
42
+ }
43
+ const MESSAGES = {
44
+ args: (who) => `${who} was not called: its args do not match the schema`,
45
+ result: (who) => `${who} returned a result that does not match the schema`,
46
+ timeout: (who) => `${who} did not answer in time`,
47
+ connection: (who) => `${who} could not be reached`,
48
+ protocol: (who) => `${who} was refused by the server`,
49
+ closed: (who) => `${who}: the connection was closed`,
50
+ };
51
+ class Connection {
52
+ name;
53
+ options;
54
+ timeoutMs;
55
+ maxTotalMs;
56
+ /** The connected client, or null between connections. */
57
+ client = null;
58
+ dialing = null;
59
+ /** While a connection is being made: its client, once there is one, so `close()` can stop it. */
60
+ connecting = null;
61
+ /** While `transport()` is pending: gives up on it, for `close()`. */
62
+ abandon = null;
63
+ closed = false;
64
+ /** The first `close()`, which the others wait for. */
65
+ closing = null;
66
+ /** Clients whose connection has gone. */
67
+ dropped = new WeakSet();
68
+ /** The server's tools at the last listing, by name. Null until a first connect passes the check. */
69
+ listed = null;
70
+ /** The tools `tool()` declared: the only ones that can be called. */
71
+ declared = new Set();
72
+ constructor(options) {
73
+ if (typeof options.name !== "string" || options.name === "") {
74
+ throw new TypeError("name must be a non-empty string");
75
+ }
76
+ if (typeof options.transport !== "function") {
77
+ throw new TypeError("transport must be a function that makes a Transport, such as http(url) or stdio({ command })");
78
+ }
79
+ this.name = options.name;
80
+ this.options = options;
81
+ this.timeoutMs = checkMs("timeoutMs", options.timeoutMs ?? TIMEOUT_MS);
82
+ this.maxTotalMs = checkMs("maxTotalMs", options.maxTotalMs ?? MAX_TOTAL_MS);
83
+ }
84
+ tool(name, def) {
85
+ if (typeof name !== "string" || name === "")
86
+ throw new TypeError("a tool's name must be a non-empty string");
87
+ if (typeof def?.args?.parse !== "function") {
88
+ throw new TypeError(`tool "${name}" needs an args schema: anything with a parse method`);
89
+ }
90
+ if (def.result !== undefined && typeof def.result.parse !== "function") {
91
+ throw new TypeError(`tool "${name}" has a result schema with no parse method`);
92
+ }
93
+ if (def.timeoutMs !== undefined)
94
+ checkMs("timeoutMs", def.timeoutMs);
95
+ if (def.maxTotalMs !== undefined)
96
+ checkMs("maxTotalMs", def.maxTotalMs);
97
+ if (this.listed) {
98
+ const problem = problemWith(name, this.listed);
99
+ if (problem)
100
+ throw new Error(`${this.name}: ${problem}`);
101
+ }
102
+ this.declared.add(name);
103
+ return Object.freeze({
104
+ server: this.name,
105
+ name,
106
+ call: (args, ctx) => this.call(name, def, args, ctx),
107
+ });
108
+ }
109
+ async connect() {
110
+ await this.open();
111
+ }
112
+ close() {
113
+ // every close() resolves once the first has closed everything
114
+ this.closing ??= this.shut();
115
+ return this.closing;
116
+ }
117
+ async shut() {
118
+ this.closed = true;
119
+ const client = this.client;
120
+ this.client = null;
121
+ // a connection still being made is stopped where it is, and sees `closed`
122
+ this.abandon?.();
123
+ await this.connecting?.close().catch(() => { });
124
+ await this.dialing?.catch(() => { });
125
+ await client?.close();
126
+ }
127
+ open() {
128
+ if (this.closed)
129
+ return Promise.reject(this.error("closed", undefined));
130
+ if (this.client)
131
+ return Promise.resolve(this.client);
132
+ // one connection at a time: calls that arrive meanwhile share it
133
+ this.dialing ??= this.dial().finally(() => {
134
+ this.dialing = null;
135
+ this.connecting = null;
136
+ });
137
+ return this.dialing;
138
+ }
139
+ /**
140
+ * What `transport()` makes, within `timeoutMs` and unless `close()` comes
141
+ * first. A transport made after that is closed when it comes.
142
+ */
143
+ async made() {
144
+ const making = Promise.resolve().then(() => this.options.transport());
145
+ let timer;
146
+ const cut = new Promise((_, reject) => {
147
+ timer = setTimeout(() => reject(new Error(`no transport within ${this.timeoutMs} ms`)), this.timeoutMs);
148
+ this.abandon = () => reject(new Error("closed while the transport was being made"));
149
+ });
150
+ try {
151
+ return await Promise.race([making, cut]);
152
+ }
153
+ catch (err) {
154
+ making.then((transport) => transport.close()).catch(() => { });
155
+ throw err;
156
+ }
157
+ finally {
158
+ clearTimeout(timer);
159
+ this.abandon = null;
160
+ }
161
+ }
162
+ async dial() {
163
+ let client;
164
+ try {
165
+ const transport = await this.made();
166
+ // close() may have come as it was made, with nothing yet to stop
167
+ if (this.closed) {
168
+ await transport.close().catch(() => { });
169
+ throw new Error("closed as the transport was made");
170
+ }
171
+ const self = new Client({ name: "haikit", version: VERSION }, {
172
+ // No capabilities are advertised, so a server has no reason to ask
173
+ // this client for input; one that does gets the call refused,
174
+ // rather than a reply nobody wrote.
175
+ inputRequired: { autoFulfill: false },
176
+ ...(this.options.versionNegotiation === undefined
177
+ ? {}
178
+ : { versionNegotiation: { mode: this.options.versionNegotiation } }),
179
+ listChanged: {
180
+ tools: {
181
+ onChanged: (error, tools) => {
182
+ if (!error && tools && this.client === self)
183
+ this.compare(tools);
184
+ },
185
+ },
186
+ },
187
+ });
188
+ client = self;
189
+ this.connecting = self;
190
+ self.onclose = () => {
191
+ this.dropped.add(self);
192
+ if (this.client === self)
193
+ this.client = null;
194
+ };
195
+ await self.connect(transport, { timeout: this.timeoutMs });
196
+ }
197
+ catch (err) {
198
+ await client?.close().catch(() => { });
199
+ throw this.error(this.closed ? "closed" : "connection", undefined, { cause: err });
200
+ }
201
+ let tools;
202
+ try {
203
+ ({ tools } = await client.listTools(undefined, { timeout: this.timeoutMs }));
204
+ }
205
+ catch (err) {
206
+ await client.close().catch(() => { });
207
+ throw this.failure(err, undefined, client);
208
+ }
209
+ if (this.listed === null) {
210
+ const listing = new Map(tools.map((t) => [t.name, t]));
211
+ const problems = [...this.declared].flatMap((name) => problemWith(name, listing) ?? []);
212
+ if (problems.length) {
213
+ await client.close().catch(() => { });
214
+ throw new Error(`${this.name}: ${problems.join("; ")}`);
215
+ }
216
+ this.listed = listing;
217
+ }
218
+ else {
219
+ this.compare(tools);
220
+ }
221
+ if (this.closed) {
222
+ await client.close().catch(() => { });
223
+ throw this.error("closed", undefined);
224
+ }
225
+ if (this.dropped.has(client))
226
+ throw this.error("connection", undefined);
227
+ this.client = client;
228
+ return client;
229
+ }
230
+ /** Report what changed about the declared tools since the last listing, and keep this one. */
231
+ compare(tools) {
232
+ const before = this.listed ?? new Map();
233
+ const next = new Map(tools.map((t) => [t.name, t]));
234
+ this.listed = next;
235
+ const removed = [];
236
+ const changed = [];
237
+ for (const name of this.declared) {
238
+ const was = before.get(name);
239
+ const now = next.get(name);
240
+ if (!was)
241
+ continue;
242
+ if (!now)
243
+ removed.push(name);
244
+ else if (shape(was) !== shape(now))
245
+ changed.push(name);
246
+ }
247
+ if (!removed.length && !changed.length)
248
+ return;
249
+ try {
250
+ (this.options.onChange ?? warn)({ server: this.name, removed, changed });
251
+ }
252
+ catch (err) {
253
+ console.error(err);
254
+ }
255
+ }
256
+ async call(tool, def, args, ctx) {
257
+ let input;
258
+ try {
259
+ input = def.args.parse(args);
260
+ }
261
+ catch (err) {
262
+ throw this.error("args", tool, { cause: err });
263
+ }
264
+ if (typeof input !== "object" || input === null || Array.isArray(input)) {
265
+ throw new McpError("args", `${this.name}/${tool} was not called: its args must be an object`, {
266
+ server: this.name,
267
+ tool,
268
+ });
269
+ }
270
+ // maxTotalMs bounds the whole call, connecting included, and is ours to
271
+ // keep: the SDK checks its own maxTotalTimeout only when progress comes
272
+ const deadline = new AbortController();
273
+ const timer = setTimeout(() => deadline.abort(), def.maxTotalMs ?? this.maxTotalMs);
274
+ let result;
275
+ try {
276
+ let client;
277
+ try {
278
+ client = await this.until(deadline.signal, tool, this.open());
279
+ }
280
+ catch (err) {
281
+ // named again for this call, with what the server said; the
282
+ // declared-tool check throws as it is
283
+ if (!isMcpError(err) || err.tool === tool)
284
+ throw err;
285
+ throw this.error(err.reason, tool, { cause: err.cause ?? err, text: err.text, code: err.code });
286
+ }
287
+ try {
288
+ result = await client.callTool({ name: tool, arguments: input }, {
289
+ timeout: def.timeoutMs ?? this.timeoutMs,
290
+ // cancels the request, and rejects it as a timeout
291
+ signal: deadline.signal,
292
+ // asked for whether or not anyone hears it, so progress always
293
+ // keeps a long call alive
294
+ resetTimeoutOnProgress: true,
295
+ onprogress: (p) => {
296
+ ctx?.progress?.({
297
+ done: p.progress,
298
+ ...(p.total === undefined ? {} : { total: p.total }),
299
+ ...(p.message === undefined ? {} : { message: p.message }),
300
+ });
301
+ },
302
+ });
303
+ }
304
+ catch (err) {
305
+ throw this.failure(err, tool, client);
306
+ }
307
+ }
308
+ finally {
309
+ clearTimeout(timer);
310
+ }
311
+ const content = result.content ?? [];
312
+ if (result.isError)
313
+ throw new McpToolError(this.name, tool, content);
314
+ if (!def.result) {
315
+ return result.structuredContent === undefined ? { content } : { content, structuredContent: result.structuredContent };
316
+ }
317
+ let value;
318
+ if (result.structuredContent !== undefined) {
319
+ value = result.structuredContent;
320
+ }
321
+ else {
322
+ const only = content.length === 1 ? content[0] : undefined;
323
+ if (only?.type !== "text") {
324
+ throw this.error("result", tool, {
325
+ cause: new Error("the result has no structured content, and isn't one text block"),
326
+ });
327
+ }
328
+ try {
329
+ value = JSON.parse(only.text);
330
+ }
331
+ catch (err) {
332
+ throw this.error("result", tool, { cause: err });
333
+ }
334
+ }
335
+ try {
336
+ return def.result.parse(value);
337
+ }
338
+ catch (err) {
339
+ throw this.error("result", tool, { cause: err });
340
+ }
341
+ }
342
+ /** What `promise` resolves to, or a timeout for `tool` if `signal` aborts first. */
343
+ until(signal, tool, promise) {
344
+ return new Promise((resolve, reject) => {
345
+ const stop = () => reject(this.error("timeout", tool));
346
+ signal.addEventListener("abort", stop, { once: true });
347
+ promise.then(resolve, reject).finally(() => signal.removeEventListener("abort", stop));
348
+ });
349
+ }
350
+ /** An SDK error, as one of ours. */
351
+ failure(err, tool, client) {
352
+ if (isMcpError(err))
353
+ return err;
354
+ if (this.closed)
355
+ return this.error("closed", tool, { cause: err });
356
+ if (err instanceof ProtocolError) {
357
+ // The SDK's own check of a call's result throws one too: the server's
358
+ // result is at fault there, not the call. Only a call has a result.
359
+ const checked = tool !== undefined && OUTPUT_CHECKS.some(([code, words]) => err.code === code && words.test(err.message));
360
+ return this.error(checked ? "result" : "protocol", tool, { cause: err, text: err.message, code: err.code });
361
+ }
362
+ if (err instanceof SdkError) {
363
+ switch (err.code) {
364
+ case SdkErrorCode.RequestTimeout:
365
+ return this.error("timeout", tool, { cause: err });
366
+ case SdkErrorCode.NotConnected:
367
+ case SdkErrorCode.ConnectionClosed:
368
+ case SdkErrorCode.SendFailed:
369
+ case SdkErrorCode.ClientHttpFailedToOpenStream:
370
+ return this.error("connection", tool, { cause: err });
371
+ case SdkErrorCode.InvalidResult:
372
+ // only a call has a result; a listing the SDK can't read is the server's fault
373
+ if (tool !== undefined)
374
+ return this.error("result", tool, { cause: err });
375
+ return this.error("protocol", tool, { cause: err, text: err.message });
376
+ default:
377
+ return this.error("protocol", tool, { cause: err, text: err.message });
378
+ }
379
+ }
380
+ // the SDK throws a plain Error for a call on a connection that has gone
381
+ return this.error(this.dropped.has(client) ? "connection" : "protocol", tool, { cause: err });
382
+ }
383
+ error(reason, tool, detail = {}) {
384
+ const who = tool === undefined ? this.name : `${this.name}/${tool}`;
385
+ return new McpError(reason, MESSAGES[reason](who), { server: this.name, tool, ...detail });
386
+ }
387
+ }
388
+ function checkMs(label, ms) {
389
+ if (typeof ms !== "number" || !Number.isInteger(ms) || ms <= 0 || ms > MAX_TIMER_MS) {
390
+ throw new RangeError(`${label} must be a whole number of milliseconds, from 1 to ${MAX_TIMER_MS} (got ${String(ms)})`);
391
+ }
392
+ return ms;
393
+ }
394
+ function problemWith(name, listing) {
395
+ const tool = listing.get(name);
396
+ if (!tool)
397
+ return `the server has no tool named "${name}"`;
398
+ if (tool.execution?.taskSupport === "required") {
399
+ return `tool "${name}" can only run as an MCP task, which @haikit/mcp does not support`;
400
+ }
401
+ return null;
402
+ }
403
+ /** What a change to a tool can break: its schemas, and whether it must run as a task. */
404
+ const shape = (tool) => JSON.stringify([tool.inputSchema, tool.outputSchema ?? null, tool.execution?.taskSupport ?? null]);
405
+ function warn(change) {
406
+ const parts = [
407
+ ...change.removed.map((name) => `tool "${name}" was removed`),
408
+ ...change.changed.map((name) => `tool "${name}" changed its schema`),
409
+ ];
410
+ console.warn(`@haikit/mcp: ${change.server}: ${parts.join("; ")}`);
411
+ }
412
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/text.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import type { McpResult } from "./index.js";
2
+ export interface TextOptions {
3
+ /** The longest text returned, before the line saying it was cut. Default 8,000 (about 2,000 tokens). */
4
+ maxChars?: number;
5
+ }
6
+ /**
7
+ * A result as text, for a tool that decides to pass some of it on. Nothing
8
+ * calls this for you: what a result becomes is the tool's choice.
9
+ *
10
+ * Text blocks, and resources embedded as text, come as they are; anything
11
+ * else becomes one line saying what it was. With no content, the structured
12
+ * result as JSON. Longer than `maxChars`, it is cut, and a last line says so:
13
+ * a cut nobody mentions turns a cost problem into a correctness problem.
14
+ */
15
+ export declare function textOf(result: McpResult, options?: TextOptions): string;
16
+ //# sourceMappingURL=text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../src/text.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,WAAW,WAAW;IAC1B,wGAAwG;IACxG,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID;;;;;;;;GAQG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,CAa3E"}
package/dist/text.js ADDED
@@ -0,0 +1,51 @@
1
+ const MAX_CHARS = 8_000;
2
+ /**
3
+ * A result as text, for a tool that decides to pass some of it on. Nothing
4
+ * calls this for you: what a result becomes is the tool's choice.
5
+ *
6
+ * Text blocks, and resources embedded as text, come as they are; anything
7
+ * else becomes one line saying what it was. With no content, the structured
8
+ * result as JSON. Longer than `maxChars`, it is cut, and a last line says so:
9
+ * a cut nobody mentions turns a cost problem into a correctness problem.
10
+ */
11
+ export function textOf(result, options = {}) {
12
+ const maxChars = options.maxChars ?? MAX_CHARS;
13
+ if (!Number.isSafeInteger(maxChars) || maxChars < 0) {
14
+ throw new RangeError(`maxChars must be a whole number of characters, 0 or more (got ${String(maxChars)})`);
15
+ }
16
+ const text = result.content.length === 0
17
+ ? result.structuredContent === undefined
18
+ ? ""
19
+ : JSON.stringify(result.structuredContent)
20
+ : result.content.map(blockText).join("\n");
21
+ if (text.length <= maxChars)
22
+ return text;
23
+ return `${text.slice(0, maxChars)}\n[Cut at ${maxChars} of ${text.length} characters.]`;
24
+ }
25
+ function blockText(block) {
26
+ switch (block.type) {
27
+ case "text":
28
+ return block.text;
29
+ case "image":
30
+ case "audio":
31
+ return `[${block.type}: ${block.mimeType}, ${bytes(block.data)} bytes, not included]`;
32
+ case "resource_link":
33
+ return `[resource link: ${block.name} ${block.uri}]`;
34
+ case "resource": {
35
+ const r = block.resource;
36
+ if ("text" in r && typeof r.text === "string")
37
+ return r.text;
38
+ const blob = "blob" in r && typeof r.blob === "string" ? r.blob : "";
39
+ return `[resource: ${r.uri}${r.mimeType ? `, ${r.mimeType}` : ""}, ${bytes(blob)} bytes, not included]`;
40
+ }
41
+ default:
42
+ // a content type from a later protocol revision
43
+ return `[${String(block.type)} content, not included]`;
44
+ }
45
+ }
46
+ /** The size of what base64 `data` encodes, without decoding it. */
47
+ function bytes(data) {
48
+ const padding = data.endsWith("==") ? 2 : data.endsWith("=") ? 1 : 0;
49
+ return Math.max(0, Math.floor((data.length * 3) / 4) - padding);
50
+ }
51
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../src/text.ts"],"names":[],"mappings":"AAQA,MAAM,SAAS,GAAG,KAAK,CAAC;AAExB;;;;;;;;GAQG;AACH,MAAM,UAAU,MAAM,CAAC,MAAiB,EAAE,UAAuB,EAAE;IACjE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,SAAS,CAAC;IAC/C,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,UAAU,CAAC,iEAAiE,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC7G,CAAC;IACD,MAAM,IAAI,GACR,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;QACzB,CAAC,CAAC,MAAM,CAAC,iBAAiB,KAAK,SAAS;YACtC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,iBAAiB,CAAC;QAC5C,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/C,IAAI,IAAI,CAAC,MAAM,IAAI,QAAQ;QAAE,OAAO,IAAI,CAAC;IACzC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,aAAa,QAAQ,OAAO,IAAI,CAAC,MAAM,eAAe,CAAC;AAC1F,CAAC;AAED,SAAS,SAAS,CAAC,KAAmB;IACpC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,MAAM;YACT,OAAO,KAAK,CAAC,IAAI,CAAC;QACpB,KAAK,OAAO,CAAC;QACb,KAAK,OAAO;YACV,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC;QACxF,KAAK,eAAe;YAClB,OAAO,mBAAmB,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,GAAG,GAAG,CAAC;QACvD,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC;YACzB,IAAI,MAAM,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO,CAAC,CAAC,IAAI,CAAC;YAC7D,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YACrE,OAAO,cAAc,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC;QAC1G,CAAC;QACD;YACE,gDAAgD;YAChD,OAAO,IAAI,MAAM,CAAE,KAA4B,CAAC,IAAI,CAAC,yBAAyB,CAAC;IACnF,CAAC;AACH,CAAC;AAED,mEAAmE;AACnE,SAAS,KAAK,CAAC,IAAY;IACzB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC;AAClE,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { type StreamableHTTPClientTransportOptions, type Transport } from "@modelcontextprotocol/client";
2
+ import { type StdioServerParameters } from "@modelcontextprotocol/client/stdio";
3
+ export interface HttpOptions extends StreamableHTTPClientTransportOptions {
4
+ /** Sent on every request, over any of the same name in `requestInit.headers`. */
5
+ headers?: Record<string, string>;
6
+ }
7
+ /**
8
+ * A server at `url`, over Streamable HTTP. Everything but `headers` is the
9
+ * SDK's own `StreamableHTTPClientTransportOptions`, such as an `authProvider`.
10
+ * The URL is checked now, so a bad one fails at startup.
11
+ */
12
+ export declare function http(url: string | URL, options?: HttpOptions): () => Transport;
13
+ /**
14
+ * A server this process starts, and talks to over its stdin and stdout. Each
15
+ * connection starts a new child; `close()` stops it. Unless `env` is given,
16
+ * the child gets only the SDK's short list of safe variables (such as `HOME`
17
+ * and `PATH`), not this process's environment and the secrets in it.
18
+ */
19
+ export declare function stdio(params: StdioServerParameters): () => Transport;
20
+ //# sourceMappingURL=transports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transports.d.ts","sourceRoot":"","sources":["../src/transports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiC,KAAK,oCAAoC,EAAE,KAAK,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACxI,OAAO,EAAwB,KAAK,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAEtG,MAAM,WAAW,WAAY,SAAQ,oCAAoC;IACvE,iFAAiF;IACjF,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,SAAS,CASlF;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,SAAS,CAEpE"}
@@ -0,0 +1,28 @@
1
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/client";
2
+ import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
3
+ /**
4
+ * A server at `url`, over Streamable HTTP. Everything but `headers` is the
5
+ * SDK's own `StreamableHTTPClientTransportOptions`, such as an `authProvider`.
6
+ * The URL is checked now, so a bad one fails at startup.
7
+ */
8
+ export function http(url, options = {}) {
9
+ const target = new URL(url);
10
+ const { headers, ...rest } = options;
11
+ if (headers) {
12
+ const merged = new Headers(rest.requestInit?.headers);
13
+ for (const [name, value] of Object.entries(headers))
14
+ merged.set(name, value);
15
+ rest.requestInit = { ...rest.requestInit, headers: merged };
16
+ }
17
+ return () => new StreamableHTTPClientTransport(target, rest);
18
+ }
19
+ /**
20
+ * A server this process starts, and talks to over its stdin and stdout. Each
21
+ * connection starts a new child; `close()` stops it. Unless `env` is given,
22
+ * the child gets only the SDK's short list of safe variables (such as `HOME`
23
+ * and `PATH`), not this process's environment and the secrets in it.
24
+ */
25
+ export function stdio(params) {
26
+ return () => new StdioClientTransport(params);
27
+ }
28
+ //# sourceMappingURL=transports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transports.js","sourceRoot":"","sources":["../src/transports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAA6D,MAAM,8BAA8B,CAAC;AACxI,OAAO,EAAE,oBAAoB,EAA8B,MAAM,oCAAoC,CAAC;AAOtG;;;;GAIG;AACH,MAAM,UAAU,IAAI,CAAC,GAAiB,EAAE,UAAuB,EAAE;IAC/D,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5B,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IACrC,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,MAAM,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACtD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;YAAE,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC7E,IAAI,CAAC,WAAW,GAAG,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAC9D,CAAC;IACD,OAAO,GAAG,EAAE,CAAC,IAAI,6BAA6B,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,KAAK,CAAC,MAA6B;IACjD,OAAO,GAAG,EAAE,CAAC,IAAI,oBAAoB,CAAC,MAAM,CAAC,CAAC;AAChD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,54 @@
1
1
  {
2
2
  "name": "@haikit/mcp",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.32.0",
4
+ "description": "Call MCP servers' tools from inside your haikit tools. The model never sees an MCP tool: your tool decides what it hears and what the browser shows. Imports only @haikit/core.",
5
+ "keywords": [
6
+ "haikit",
7
+ "mcp",
8
+ "model-context-protocol",
9
+ "llm",
10
+ "agent",
11
+ "agentic-ui",
12
+ "tool-use",
13
+ "ai"
14
+ ],
15
+ "type": "module",
16
+ "main": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "default": "./dist/index.js"
22
+ },
23
+ "./package.json": "./package.json"
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "src"
28
+ ],
29
+ "sideEffects": false,
30
+ "engines": {
31
+ "node": ">=22"
32
+ },
33
+ "scripts": {
34
+ "prepack": "npm --prefix ../.. run build"
35
+ },
36
+ "dependencies": {
37
+ "@haikit/core": "0.32.0",
38
+ "@modelcontextprotocol/client": "^2.4.0",
39
+ "@types/node": ">=22"
40
+ },
41
+ "publishConfig": {
42
+ "access": "public"
43
+ },
44
+ "license": "MIT",
45
+ "homepage": "https://github.com/wfoxd/haikit/tree/main/packages/mcp#readme",
46
+ "bugs": {
47
+ "url": "https://github.com/wfoxd/haikit/issues"
48
+ },
49
+ "repository": {
50
+ "type": "git",
51
+ "url": "git+https://github.com/wfoxd/haikit.git",
52
+ "directory": "packages/mcp"
53
+ }
54
+ }