@adia-ai/agent 0.8.28 → 0.8.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/README.md +384 -11
- package/agent.d.ts +44 -3
- package/agent.d.ts.map +1 -1
- package/agent.js +172 -8
- package/agent.js.map +1 -1
- package/events.d.ts +46 -2
- package/events.d.ts.map +1 -1
- package/events.js +30 -1
- package/events.js.map +1 -1
- package/guardrail.d.ts +68 -0
- package/guardrail.d.ts.map +1 -0
- package/guardrail.js +79 -0
- package/guardrail.js.map +1 -0
- package/index.d.ts +15 -7
- package/index.d.ts.map +1 -1
- package/index.js +7 -3
- package/index.js.map +1 -1
- package/integrations.d.ts +19 -2
- package/integrations.d.ts.map +1 -1
- package/integrations.js +6 -1
- package/integrations.js.map +1 -1
- package/loop.d.ts +19 -8
- package/loop.d.ts.map +1 -1
- package/loop.js +176 -9
- package/loop.js.map +1 -1
- package/mcp-transport.d.ts +128 -0
- package/mcp-transport.d.ts.map +1 -0
- package/mcp-transport.js +361 -0
- package/mcp-transport.js.map +1 -0
- package/mcp.d.ts +120 -0
- package/mcp.d.ts.map +1 -0
- package/mcp.js +264 -0
- package/mcp.js.map +1 -0
- package/package.json +1 -1
- package/resource.d.ts +28 -3
- package/resource.d.ts.map +1 -1
- package/resource.js +43 -5
- package/resource.js.map +1 -1
- package/session.d.ts +18 -0
- package/session.d.ts.map +1 -1
- package/session.js +40 -0
- package/session.js.map +1 -1
- package/stub.d.ts +8 -0
- package/stub.d.ts.map +1 -1
- package/stub.js +13 -0
- package/stub.js.map +1 -1
- package/tools.d.ts +6 -0
- package/tools.d.ts.map +1 -1
- package/tools.js.map +1 -1
- package/trace.d.ts +50 -0
- package/trace.d.ts.map +1 -0
- package/trace.js +60 -0
- package/trace.js.map +1 -0
- package/workflow.d.ts +113 -11
- package/workflow.d.ts.map +1 -1
- package/workflow.js +93 -15
- package/workflow.js.map +1 -1
package/mcp-transport.js
ADDED
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP streamable-HTTP client transport — the smallest thing that speaks the
|
|
3
|
+
* protocol.
|
|
4
|
+
*
|
|
5
|
+
* Deliberately NOT `@modelcontextprotocol/sdk`. The subset a client needs to
|
|
6
|
+
* consume a server as a tool/resource source is five methods over one POST
|
|
7
|
+
* endpoint (initialize · notifications/initialized · tools/list · tools/call ·
|
|
8
|
+
* resources/list · resources/read); the SDK brings a server framework, stdio
|
|
9
|
+
* and websocket transports, an auth stack, and zod along with it. This
|
|
10
|
+
* package's whole posture is zero runtime dependencies beyond `@adia-ai/llm`
|
|
11
|
+
* and a browser-first build, so the subset is hand-rolled here and the SDK
|
|
12
|
+
* stays where it belongs — `packages/a2ui/mcp`, which SERVES.
|
|
13
|
+
*
|
|
14
|
+
* Wire rules the spec fixes and this module obeys:
|
|
15
|
+
* - Every request is a POST carrying one JSON-RPC message, with
|
|
16
|
+
* `accept: application/json, text/event-stream` — the server picks.
|
|
17
|
+
* - A `mcp-session-id` response header on the initialize response is echoed
|
|
18
|
+
* on every subsequent request (and on the DELETE that closes the session).
|
|
19
|
+
* - The negotiated `MCP-Protocol-Version` rides every post-initialize
|
|
20
|
+
* request.
|
|
21
|
+
* - An SSE response body is read until the event whose `data:` payload is
|
|
22
|
+
* the JSON-RPC response for THIS request id; server-initiated
|
|
23
|
+
* notifications interleaved on that stream are ignored (this client
|
|
24
|
+
* subscribes to nothing, so there is nothing it can act on).
|
|
25
|
+
* - The protocol headers are the LAST spread in every request, so a caller
|
|
26
|
+
* header cannot quietly replace `accept` or the session id and turn a
|
|
27
|
+
* working connection into an inexplicable one.
|
|
28
|
+
*
|
|
29
|
+
* Nothing here waits forever. Every round trip carries a deadline covering
|
|
30
|
+
* BOTH the fetch and the wait for the answer to arrive on an SSE body — a
|
|
31
|
+
* server that accepts a POST and then says nothing is a real failure mode,
|
|
32
|
+
* and it is indistinguishable from a hang unless someone is holding a clock.
|
|
33
|
+
* The deadline and the caller's `signal` share one abort path, so a timeout
|
|
34
|
+
* and a user cancellation both actually cancel the request rather than
|
|
35
|
+
* abandoning it.
|
|
36
|
+
*
|
|
37
|
+
* Everything is `fetch`-only, so it runs unchanged in a browser — with the
|
|
38
|
+
* CORS caveat the README records. `fetchImpl` exists so a test can hand the
|
|
39
|
+
* transport an in-process server instead of a network.
|
|
40
|
+
*/
|
|
41
|
+
const CLIENT_PROTOCOL_VERSION = '2025-06-18';
|
|
42
|
+
/** Versions this client can talk. A server answering initialize with
|
|
43
|
+
* anything else is a hard stop: guessing at an unknown dialect is how you
|
|
44
|
+
* get a half-working tool list. A version NEWER than the one requested is
|
|
45
|
+
* refused too — the server would be answering a question we did not ask,
|
|
46
|
+
* and the dialect it picked is by definition one this client was not
|
|
47
|
+
* written against. */
|
|
48
|
+
const SUPPORTED_PROTOCOL_VERSIONS = new Set([
|
|
49
|
+
'2025-06-18', '2025-03-26', '2024-11-05',
|
|
50
|
+
]);
|
|
51
|
+
/**
|
|
52
|
+
* Default per-request deadline: 60 seconds.
|
|
53
|
+
*
|
|
54
|
+
* It has to clear the slowest legitimate answer, and for MCP that is a tool
|
|
55
|
+
* that thinks — the in-repo a2ui server's `generate_ui` runs an LLM inside
|
|
56
|
+
* `tools/call`. A handshake-sized number (5–10s) would make MCP-client mode
|
|
57
|
+
* useless for exactly the servers this repo has. One knob rather than
|
|
58
|
+
* separate connect/call budgets: two numbers to tune is worse than one
|
|
59
|
+
* generous one, and `timeoutMs` is per-request, so a caller with a slower
|
|
60
|
+
* tool raises it in the one place that matters.
|
|
61
|
+
*/
|
|
62
|
+
export const DEFAULT_MCP_TIMEOUT_MS = 60_000;
|
|
63
|
+
/** Every MCP failure this package raises carries this name, so a consumer
|
|
64
|
+
* can tell an MCP fault from a tool's own bad day without string-matching. */
|
|
65
|
+
export class McpError extends Error {
|
|
66
|
+
name = 'McpError';
|
|
67
|
+
/** The server the fault belongs to. Empty for a fault raised while
|
|
68
|
+
* assembling several sources, where no single server owns it. */
|
|
69
|
+
url;
|
|
70
|
+
constructor(message, url = '', options) {
|
|
71
|
+
super(url ? `${message} [${url}]` : message, options);
|
|
72
|
+
this.url = url;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/** Connect-time faults: unreachable server, non-2xx, protocol mismatch, a
|
|
76
|
+
* timeout, a JSON-RPC error on initialize/list, or a listed tool this
|
|
77
|
+
* harness cannot register. Thrown, never swallowed — an agent that
|
|
78
|
+
* silently ran with an empty tool list would look like a model that forgot
|
|
79
|
+
* how to use its tools. */
|
|
80
|
+
export class McpConnectionError extends McpError {
|
|
81
|
+
name = 'McpConnectionError';
|
|
82
|
+
}
|
|
83
|
+
/** A `tools/call` or `resources/read` that failed after the connection was
|
|
84
|
+
* established. Thrown inside a ToolDef's `execute`, which `executeTool`
|
|
85
|
+
* turns into an `isError` tool_result — the model sees it and can react. */
|
|
86
|
+
export class McpCallError extends McpError {
|
|
87
|
+
name = 'McpCallError';
|
|
88
|
+
}
|
|
89
|
+
function isResponseFor(message, id) {
|
|
90
|
+
return !!message && typeof message === 'object' && message.id === id;
|
|
91
|
+
}
|
|
92
|
+
/** One abort path for the deadline and every caller signal. Returns the
|
|
93
|
+
* controller (so the caller can abort the underlying request on timeout)
|
|
94
|
+
* plus a `settle` to release the timer and the listeners — a per-request
|
|
95
|
+
* listener left on a long-lived connection signal IS a leak. */
|
|
96
|
+
function abortPath(signals, timeoutMs) {
|
|
97
|
+
const controller = new AbortController();
|
|
98
|
+
let expired = false;
|
|
99
|
+
const live = signals.filter((s) => !!s);
|
|
100
|
+
const onAbort = () => controller.abort();
|
|
101
|
+
for (const signal of live) {
|
|
102
|
+
if (signal.aborted)
|
|
103
|
+
controller.abort();
|
|
104
|
+
else
|
|
105
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
106
|
+
}
|
|
107
|
+
const timer = timeoutMs > 0
|
|
108
|
+
? setTimeout(() => { expired = true; controller.abort(); }, timeoutMs)
|
|
109
|
+
: null;
|
|
110
|
+
return {
|
|
111
|
+
signal: controller.signal,
|
|
112
|
+
timedOut: () => expired,
|
|
113
|
+
settle: () => {
|
|
114
|
+
if (timer)
|
|
115
|
+
clearTimeout(timer);
|
|
116
|
+
for (const signal of live)
|
|
117
|
+
signal.removeEventListener('abort', onAbort);
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/** Reject as soon as the shared abort path fires, whatever `promise` is
|
|
122
|
+
* doing. `fetch` honors the signal; an in-memory Response's reader does
|
|
123
|
+
* not, and a hung server is exactly the case where nobody else is holding
|
|
124
|
+
* a clock — so the race is explicit rather than delegated. */
|
|
125
|
+
function untilAborted(promise, path) {
|
|
126
|
+
if (path.signal.aborted)
|
|
127
|
+
return Promise.reject(abortReason(path));
|
|
128
|
+
return new Promise((resolve, reject) => {
|
|
129
|
+
const onAbort = () => reject(abortReason(path));
|
|
130
|
+
path.signal.addEventListener('abort', onAbort, { once: true });
|
|
131
|
+
promise.then(resolve, reject).finally(() => {
|
|
132
|
+
path.signal.removeEventListener('abort', onAbort);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
function abortReason(path) {
|
|
137
|
+
return path.timedOut()
|
|
138
|
+
? new Error('__mcp_timeout__')
|
|
139
|
+
: new Error('__mcp_aborted__');
|
|
140
|
+
}
|
|
141
|
+
/** Turn the internal marker (or a fetch's own AbortError) into the right
|
|
142
|
+
* named MCP error, so a caller reads "timed out" / "aborted" instead of
|
|
143
|
+
* the DOM's vocabulary. */
|
|
144
|
+
function describeFailure(err, timeoutMs) {
|
|
145
|
+
const message = err?.message ?? String(err);
|
|
146
|
+
if (message === '__mcp_timeout__')
|
|
147
|
+
return `timed out after ${timeoutMs}ms`;
|
|
148
|
+
if (message === '__mcp_aborted__')
|
|
149
|
+
return 'aborted by caller';
|
|
150
|
+
if (err?.name === 'AbortError')
|
|
151
|
+
return 'aborted';
|
|
152
|
+
return message;
|
|
153
|
+
}
|
|
154
|
+
/** Pull the JSON-RPC response for `id` out of an SSE body.
|
|
155
|
+
*
|
|
156
|
+
* Event-block granularity, per the SSE spec rather than per line: an event
|
|
157
|
+
* ends at a blank line and its `data:` lines are joined with newlines, so a
|
|
158
|
+
* server that pretty-prints its JSON across several `data:` lines is read
|
|
159
|
+
* correctly instead of silently discarded as unparseable. */
|
|
160
|
+
async function readSseResponse(res, id, url, path, ErrorClass) {
|
|
161
|
+
const body = res.body;
|
|
162
|
+
if (!body)
|
|
163
|
+
throw new ErrorClass('server sent an SSE response with no body', url);
|
|
164
|
+
const reader = body.getReader();
|
|
165
|
+
const decoder = new TextDecoder();
|
|
166
|
+
let buffer = '';
|
|
167
|
+
let data = [];
|
|
168
|
+
const flush = () => {
|
|
169
|
+
if (!data.length)
|
|
170
|
+
return null;
|
|
171
|
+
const payload = data.join('\n');
|
|
172
|
+
data = [];
|
|
173
|
+
let message;
|
|
174
|
+
try {
|
|
175
|
+
message = JSON.parse(payload);
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
return null; // A malformed event is not this request's answer.
|
|
179
|
+
}
|
|
180
|
+
return isResponseFor(message, id) ? message : null;
|
|
181
|
+
};
|
|
182
|
+
try {
|
|
183
|
+
for (;;) {
|
|
184
|
+
const { done, value } = await untilAborted(reader.read(), path);
|
|
185
|
+
if (done)
|
|
186
|
+
break;
|
|
187
|
+
buffer += decoder.decode(value, { stream: true });
|
|
188
|
+
let cut;
|
|
189
|
+
while ((cut = buffer.indexOf('\n')) !== -1) {
|
|
190
|
+
const line = buffer.slice(0, cut).replace(/\r$/, '');
|
|
191
|
+
buffer = buffer.slice(cut + 1);
|
|
192
|
+
if (!line) {
|
|
193
|
+
const message = flush();
|
|
194
|
+
if (message)
|
|
195
|
+
return message;
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
if (line.startsWith('data:')) {
|
|
199
|
+
// One optional space after the colon is part of the framing.
|
|
200
|
+
data.push(line.slice(5).replace(/^ /, ''));
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
const trailing = flush();
|
|
205
|
+
if (trailing)
|
|
206
|
+
return trailing;
|
|
207
|
+
}
|
|
208
|
+
finally {
|
|
209
|
+
await reader.cancel().catch(() => { });
|
|
210
|
+
}
|
|
211
|
+
throw new ErrorClass(`SSE stream ended before a response to request ${id} arrived`, url);
|
|
212
|
+
}
|
|
213
|
+
/** `connectOptions.signal` covers the HANDSHAKE only. It is deliberately not
|
|
214
|
+
* `options.signal`: that one is connection-level and would keep aborting
|
|
215
|
+
* every later call, so a turn that cancelled the connect would poison every
|
|
216
|
+
* turn after it. */
|
|
217
|
+
export async function connectStreamableHttp(options, connectOptions = {}) {
|
|
218
|
+
const { url } = options;
|
|
219
|
+
const doFetch = options.fetchImpl ?? globalThis.fetch;
|
|
220
|
+
if (typeof doFetch !== 'function') {
|
|
221
|
+
throw new McpConnectionError('no global fetch available — pass fetchImpl', url);
|
|
222
|
+
}
|
|
223
|
+
const clientInfo = options.clientInfo ?? { name: '@adia-ai/agent', version: '1' };
|
|
224
|
+
const defaultTimeout = options.timeoutMs ?? DEFAULT_MCP_TIMEOUT_MS;
|
|
225
|
+
let sessionId;
|
|
226
|
+
let negotiated = CLIENT_PROTOCOL_VERSION;
|
|
227
|
+
let nextId = 1;
|
|
228
|
+
/** Caller headers first: the protocol's own headers are not negotiable,
|
|
229
|
+
* and a caller who sets `accept` or `mcp-session-id` by accident should
|
|
230
|
+
* not be able to break the transport from the outside. */
|
|
231
|
+
function headers(extra) {
|
|
232
|
+
return {
|
|
233
|
+
...options.headers,
|
|
234
|
+
'content-type': 'application/json',
|
|
235
|
+
accept: 'application/json, text/event-stream',
|
|
236
|
+
...(sessionId ? { 'mcp-session-id': sessionId } : {}),
|
|
237
|
+
...extra,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
async function post(body, ErrorClass, path, timeoutMs, extraHeaders) {
|
|
241
|
+
let res;
|
|
242
|
+
try {
|
|
243
|
+
res = await untilAborted(doFetch(url, {
|
|
244
|
+
method: 'POST',
|
|
245
|
+
headers: headers(extraHeaders),
|
|
246
|
+
body: JSON.stringify(body),
|
|
247
|
+
signal: path.signal,
|
|
248
|
+
}), path);
|
|
249
|
+
}
|
|
250
|
+
catch (err) {
|
|
251
|
+
throw new ErrorClass(`cannot reach MCP server: ${describeFailure(err, timeoutMs)}`, url, { cause: err });
|
|
252
|
+
}
|
|
253
|
+
if (!res.ok) {
|
|
254
|
+
const text = await res.text().catch(() => '');
|
|
255
|
+
throw new ErrorClass(`MCP server returned ${res.status}${text ? `: ${text.slice(0, 300)}` : ''}`, url);
|
|
256
|
+
}
|
|
257
|
+
return res;
|
|
258
|
+
}
|
|
259
|
+
async function rpc(method, params, ErrorClass, requestOptions) {
|
|
260
|
+
const id = nextId++;
|
|
261
|
+
const timeoutMs = requestOptions?.timeoutMs ?? defaultTimeout;
|
|
262
|
+
const path = abortPath([options.signal, requestOptions?.signal], timeoutMs);
|
|
263
|
+
try {
|
|
264
|
+
const res = await post({ jsonrpc: '2.0', id, method, ...(params ? { params } : {}) }, ErrorClass, path, timeoutMs, method === 'initialize' ? {} : { 'mcp-protocol-version': negotiated });
|
|
265
|
+
if (method === 'initialize') {
|
|
266
|
+
const assigned = res.headers.get('mcp-session-id');
|
|
267
|
+
if (assigned)
|
|
268
|
+
sessionId = assigned;
|
|
269
|
+
}
|
|
270
|
+
const contentType = res.headers.get('content-type') ?? '';
|
|
271
|
+
let message;
|
|
272
|
+
if (contentType.includes('text/event-stream')) {
|
|
273
|
+
try {
|
|
274
|
+
message = await readSseResponse(res, id, url, path, ErrorClass);
|
|
275
|
+
}
|
|
276
|
+
catch (err) {
|
|
277
|
+
if (err instanceof McpError)
|
|
278
|
+
throw err;
|
|
279
|
+
throw new ErrorClass(`${method} failed: ${describeFailure(err, timeoutMs)}`, url, { cause: err });
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
const text = await untilAborted(res.text(), path).catch((err) => {
|
|
284
|
+
throw new ErrorClass(`${method} failed: ${describeFailure(err, timeoutMs)}`, url, { cause: err });
|
|
285
|
+
});
|
|
286
|
+
try {
|
|
287
|
+
message = JSON.parse(text);
|
|
288
|
+
}
|
|
289
|
+
catch {
|
|
290
|
+
throw new ErrorClass(`MCP server sent a non-JSON response to ${method}: ${text.slice(0, 200)}`, url);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
if (message.error) {
|
|
294
|
+
throw new ErrorClass(`${method} failed (${message.error.code}): ${message.error.message}`, url);
|
|
295
|
+
}
|
|
296
|
+
return message.result;
|
|
297
|
+
}
|
|
298
|
+
finally {
|
|
299
|
+
path.settle();
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
const initResult = await rpc('initialize', {
|
|
303
|
+
protocolVersion: CLIENT_PROTOCOL_VERSION,
|
|
304
|
+
capabilities: {},
|
|
305
|
+
clientInfo,
|
|
306
|
+
}, McpConnectionError, connectOptions.signal ? { signal: connectOptions.signal } : undefined);
|
|
307
|
+
const serverVersion = initResult?.protocolVersion ?? CLIENT_PROTOCOL_VERSION;
|
|
308
|
+
// Dates sort lexicographically, so "newer than we asked for" is a string
|
|
309
|
+
// comparison — and it is refused as firmly as an unknown one.
|
|
310
|
+
if (!SUPPORTED_PROTOCOL_VERSIONS.has(serverVersion) || serverVersion > CLIENT_PROTOCOL_VERSION) {
|
|
311
|
+
throw new McpConnectionError(`server speaks MCP protocol "${serverVersion}", this client asked for ` +
|
|
312
|
+
`${CLIENT_PROTOCOL_VERSION} and accepts ${[...SUPPORTED_PROTOCOL_VERSIONS].join(', ')}`, url);
|
|
313
|
+
}
|
|
314
|
+
negotiated = serverVersion;
|
|
315
|
+
// The spec's post-initialize notification. It carries no id and gets no
|
|
316
|
+
// response body worth reading — but a server that rejects it has told us
|
|
317
|
+
// the handshake did not take, so the failure is fatal like any other
|
|
318
|
+
// connect-time fault.
|
|
319
|
+
{
|
|
320
|
+
const path = abortPath([options.signal, connectOptions.signal], defaultTimeout);
|
|
321
|
+
try {
|
|
322
|
+
const res = await post({ jsonrpc: '2.0', method: 'notifications/initialized' }, McpConnectionError, path, defaultTimeout, { 'mcp-protocol-version': negotiated });
|
|
323
|
+
await res.body?.cancel().catch(() => { });
|
|
324
|
+
}
|
|
325
|
+
finally {
|
|
326
|
+
path.settle();
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return {
|
|
330
|
+
url,
|
|
331
|
+
serverInfo: {
|
|
332
|
+
name: initResult?.serverInfo?.name ?? 'unknown',
|
|
333
|
+
version: initResult?.serverInfo?.version ?? '0',
|
|
334
|
+
},
|
|
335
|
+
protocolVersion: negotiated,
|
|
336
|
+
capabilities: initResult?.capabilities ?? {},
|
|
337
|
+
request(method, params, requestOptions) {
|
|
338
|
+
return rpc(method, params, McpCallError, requestOptions);
|
|
339
|
+
},
|
|
340
|
+
async close() {
|
|
341
|
+
if (!sessionId)
|
|
342
|
+
return;
|
|
343
|
+
const path = abortPath([], defaultTimeout);
|
|
344
|
+
try {
|
|
345
|
+
await untilAborted(doFetch(url, {
|
|
346
|
+
method: 'DELETE',
|
|
347
|
+
headers: headers({ 'mcp-protocol-version': negotiated }),
|
|
348
|
+
signal: path.signal,
|
|
349
|
+
}), path);
|
|
350
|
+
}
|
|
351
|
+
catch {
|
|
352
|
+
// A session the server will time out on its own is not worth a throw.
|
|
353
|
+
}
|
|
354
|
+
finally {
|
|
355
|
+
path.settle();
|
|
356
|
+
}
|
|
357
|
+
sessionId = undefined;
|
|
358
|
+
},
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
//# sourceMappingURL=mcp-transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-transport.js","sourceRoot":"","sources":["src/mcp-transport.ts"],"names":[],"mappings":"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"}
|
package/mcp.d.ts
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP-client mode — a server becomes a tool/resource source.
|
|
3
|
+
*
|
|
4
|
+
* `mcpServer({ url })` declares a source; the agent connects it and every
|
|
5
|
+
* tool the server lists arrives as a normal `ToolDef` in the loop. Nothing
|
|
6
|
+
* downstream knows the difference: guardrails see the calls, the tracer
|
|
7
|
+
* records the executions, `checkInput` runs at the boundary, a failure comes
|
|
8
|
+
* back as an `isError` tool_result. That sameness is the point — MCP is a
|
|
9
|
+
* SOURCE of tools, not a second kind of tool.
|
|
10
|
+
*
|
|
11
|
+
* How it composes with the tier-2 registry (integrations.ts):
|
|
12
|
+
* - `register` — used, and it is the fail-fast the lead cares about: two
|
|
13
|
+
* servers exposing `search`, or a server tool colliding with a declared
|
|
14
|
+
* one, throws at connect instead of silently shadowing.
|
|
15
|
+
* - `buildToolDispatch` — used: the ONE place a manifest becomes a ToolDef
|
|
16
|
+
* (law 8's shared executor seam) stays the only place.
|
|
17
|
+
* - `resolveIntegrations` — deliberately NOT used. Its two jobs are
|
|
18
|
+
* persona-enablement intersection and dropping manifests whose env key is
|
|
19
|
+
* unprovisioned; an MCP server has neither a persona list nor an env key,
|
|
20
|
+
* and its `MAX_INTEGRATIONS` cap SILENTLY drops the overflow. A server
|
|
21
|
+
* exposing more tools than the cap is a real thing (the in-repo a2ui
|
|
22
|
+
* server has ~20), and quietly serving two thirds of them is the failure
|
|
23
|
+
* mode this whole feature is supposed to prevent. So the cap here is
|
|
24
|
+
* explicit and LOUD: `maxTools` (default `MAX_INTEGRATIONS`) throws when
|
|
25
|
+
* exceeded, and `tools` narrows the list on purpose.
|
|
26
|
+
*
|
|
27
|
+
* Schemas arrive as JSON Schema and are passed to the model VERBATIM. They
|
|
28
|
+
* are not trimmed to `checkInput`'s allowlist: the MCP server is the
|
|
29
|
+
* authoritative validator (its rejection comes back as an error result the
|
|
30
|
+
* model can read), so a faithful copy of a contract someone else owns beats
|
|
31
|
+
* a locally-enforceable subset that describes the tool less accurately. The
|
|
32
|
+
* manifest says so with `validation: 'remote'` rather than leaving it
|
|
33
|
+
* implied.
|
|
34
|
+
*
|
|
35
|
+
* RESOURCES map onto the two existing modes and no new one. `tool` is the
|
|
36
|
+
* default — the harness cannot know which of a remote server's resources an
|
|
37
|
+
* app wants in every prompt, and attaching all of them would grow the system
|
|
38
|
+
* prompt without bound — and `attach: [name|uri]` promotes the ones the APP
|
|
39
|
+
* decides belong there every turn. That is the whole application-controlled
|
|
40
|
+
* vs. model-controlled distinction MCP itself draws, expressed with the
|
|
41
|
+
* modes the harness already has. gh#671's third mode is NOT needed here; see
|
|
42
|
+
* the README's ruling.
|
|
43
|
+
*
|
|
44
|
+
* Everything a server returns — tool descriptions, resource text, error
|
|
45
|
+
* strings — is DATA. A description that reads like an instruction is still a
|
|
46
|
+
* description; it lands inside the tool spec or a `<resource>` envelope and
|
|
47
|
+
* decides nothing about what the harness does.
|
|
48
|
+
*/
|
|
49
|
+
import { type ResourceDef } from './resource.js';
|
|
50
|
+
import type { ToolDef } from './tools.js';
|
|
51
|
+
import { type McpConnection, type McpTransportOptions } from './mcp-transport.js';
|
|
52
|
+
export interface McpServerOptions extends McpTransportOptions {
|
|
53
|
+
/** Prefix for every tool name this server contributes — the way to run
|
|
54
|
+
* two servers that both expose `search`. Applied before the
|
|
55
|
+
* `[a-zA-Z0-9_-]` sanitize, so `weather_` + `get-forecast` is
|
|
56
|
+
* `weather_get-forecast`. */
|
|
57
|
+
prefix?: string;
|
|
58
|
+
/** Allowlist of server-side tool names to register. Absent = all of them
|
|
59
|
+
* (subject to `maxTools`). */
|
|
60
|
+
tools?: string[];
|
|
61
|
+
/** Loud cap: more listed tools than this throws at connect rather than
|
|
62
|
+
* registering a silent subset. Default `MAX_INTEGRATIONS`. */
|
|
63
|
+
maxTools?: number;
|
|
64
|
+
/** `false` skips `resources/list` entirely — a server whose resources are
|
|
65
|
+
* irrelevant to this agent shouldn't pay for the round trip. */
|
|
66
|
+
resources?: boolean;
|
|
67
|
+
/** Resource names or URIs to expose as `attach` mode (fetched every turn
|
|
68
|
+
* and inlined in the system prompt). Everything else is `tool` mode. */
|
|
69
|
+
attach?: string[];
|
|
70
|
+
}
|
|
71
|
+
/** What `createAgent({ integrations })` accepts. One arm today; the union
|
|
72
|
+
* is the extension point a future source (an OpenAPI spec, a worker) adds
|
|
73
|
+
* an arm to without changing the config surface. */
|
|
74
|
+
export interface McpSource {
|
|
75
|
+
kind: 'mcp';
|
|
76
|
+
url: string;
|
|
77
|
+
options: McpServerOptions;
|
|
78
|
+
}
|
|
79
|
+
export interface McpServerReport {
|
|
80
|
+
url: string;
|
|
81
|
+
serverInfo: {
|
|
82
|
+
name: string;
|
|
83
|
+
version: string;
|
|
84
|
+
};
|
|
85
|
+
protocolVersion: string;
|
|
86
|
+
tools: string[];
|
|
87
|
+
resources: Array<{
|
|
88
|
+
name: string;
|
|
89
|
+
uri: string;
|
|
90
|
+
mode: 'attach' | 'tool';
|
|
91
|
+
}>;
|
|
92
|
+
}
|
|
93
|
+
export interface ConnectedMcpServer extends McpServerReport {
|
|
94
|
+
connection: McpConnection;
|
|
95
|
+
toolDefs: ToolDef[];
|
|
96
|
+
resourceDefs: ResourceDef[];
|
|
97
|
+
}
|
|
98
|
+
/** Declare an MCP server as a source. Pure — no connection happens here, so
|
|
99
|
+
* this is safe to call at module scope; the agent connects on first use (or
|
|
100
|
+
* eagerly via `agent.connect()`). */
|
|
101
|
+
export declare function mcpServer(options: McpServerOptions): McpSource;
|
|
102
|
+
/** Connect one declared source: handshake, list, register, build. Any
|
|
103
|
+
* failure along the way throws `McpConnectionError` — including a failure
|
|
104
|
+
* the REGISTRY raises, which is a plain Error about a manifest and would
|
|
105
|
+
* otherwise escape as a different error class than the one the failure
|
|
106
|
+
* table promises. The caller never receives a half-built source or an empty
|
|
107
|
+
* tool list that looks like a server with nothing to offer.
|
|
108
|
+
*
|
|
109
|
+
* `signal` cancels the connect in flight (the turn that triggered it was
|
|
110
|
+
* aborted); it does NOT stay attached to the resulting connection, whose
|
|
111
|
+
* later calls carry their own turn's signal. */
|
|
112
|
+
export declare function connectMcpSource(source: McpSource, opts?: {
|
|
113
|
+
signal?: AbortSignal;
|
|
114
|
+
}): Promise<ConnectedMcpServer>;
|
|
115
|
+
/** The whole assembled tool set must have unique names — the loop dispatches
|
|
116
|
+
* by name, so a duplicate is a tool that silently never runs. Per-server
|
|
117
|
+
* registration cannot see across sources or into the declared tools, so the
|
|
118
|
+
* check lands here, once, over everything. */
|
|
119
|
+
export declare function assertUniqueToolNames(tools: ToolDef[]): void;
|
|
120
|
+
//# sourceMappingURL=mcp.d.ts.map
|
package/mcp.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["src/mcp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAMH,OAAO,EAAkB,KAAK,WAAW,EAAwB,MAAM,eAAe,CAAC;AACvF,OAAO,KAAK,EAAe,OAAO,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EAEL,KAAK,aAAa,EAAE,KAAK,mBAAmB,EAC7C,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,gBAAiB,SAAQ,mBAAmB;IAC3D;;;kCAG8B;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;mCAC+B;IAC/B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB;mEAC+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;qEACiE;IACjE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;6EACyE;IACzE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;qDAEqD;AACrD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,gBAAgB,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1E;AAED,MAAM,WAAW,kBAAmB,SAAQ,eAAe;IACzD,UAAU,EAAE,aAAa,CAAC;IAC1B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,YAAY,EAAE,WAAW,EAAE,CAAC;CAC7B;AAyBD;;sCAEsC;AACtC,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAG9D;AA2GD;;;;;;;;;iDASiD;AACjD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,SAAS,EACjB,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,WAAW,CAAA;CAAO,GAClC,OAAO,CAAC,kBAAkB,CAAC,CAa7B;AA+GD;;;+CAG+C;AAC/C,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI,CAW5D"}
|