@voltro/mcp 0.32.0 → 0.34.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/CHANGELOG.md +2006 -0
- package/dist/http-BGeW8WkP.js +104 -0
- package/dist/httpServer.js +3 -3
- package/dist/index.d.ts +207 -5
- package/dist/index.js +3 -3
- package/dist/mcp-CZJe2Frv.js +542 -0
- package/dist/serve-ZSmqUcRM.js +47 -0
- package/dist/server.js +1 -1
- package/package.json +3 -2
- package/dist/http-CtkNxu9A.js +0 -103
- package/dist/mcp-DrI72Mwz.js +0 -338
- package/dist/serve-CRW_Na4H.js +0 -47
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { D as e, E as t, a as n } from "./mcp-CZJe2Frv.js";
|
|
2
|
+
import { randomUUID as r } from "node:crypto";
|
|
3
|
+
//#region src/http.ts
|
|
4
|
+
var i = "mcp-session-id", a = "application/json", o = "text/event-stream", s = (e) => e.some((e) => e.method === "initialize"), c = async (e) => {
|
|
5
|
+
let t = e.newSessionId ?? r;
|
|
6
|
+
if (e.method === "DELETE") return {
|
|
7
|
+
kind: "empty",
|
|
8
|
+
status: 204
|
|
9
|
+
};
|
|
10
|
+
if (e.method === "GET") return e.acceptsSse ? {
|
|
11
|
+
kind: "sse",
|
|
12
|
+
events: [],
|
|
13
|
+
keepOpen: !0
|
|
14
|
+
} : {
|
|
15
|
+
kind: "json",
|
|
16
|
+
status: 405,
|
|
17
|
+
body: u(null, "GET requires Accept: text/event-stream")
|
|
18
|
+
};
|
|
19
|
+
if (e.method !== "POST") return {
|
|
20
|
+
kind: "json",
|
|
21
|
+
status: 405,
|
|
22
|
+
body: u(null, `method ${e.method} not allowed`)
|
|
23
|
+
};
|
|
24
|
+
if (e.body === void 0 || e.body === null) return {
|
|
25
|
+
kind: "json",
|
|
26
|
+
status: 400,
|
|
27
|
+
body: l("empty POST body")
|
|
28
|
+
};
|
|
29
|
+
let a = Array.isArray(e.body) ? e.body : [e.body], o = s(a), c = e.headers[i];
|
|
30
|
+
if (!o && c === void 0) return {
|
|
31
|
+
kind: "json",
|
|
32
|
+
status: 400,
|
|
33
|
+
body: l("missing Mcp-Session-Id header")
|
|
34
|
+
};
|
|
35
|
+
let d = o ? c ?? t() : c, f = (await Promise.all(a.map((t) => n(e.snapshot, t, e.serverInfo, e.live)))).filter((e) => e !== null);
|
|
36
|
+
return f.length === 0 ? {
|
|
37
|
+
kind: "empty",
|
|
38
|
+
status: 202
|
|
39
|
+
} : e.acceptsSse ? {
|
|
40
|
+
kind: "sse",
|
|
41
|
+
events: f,
|
|
42
|
+
keepOpen: !1,
|
|
43
|
+
...d === void 0 ? {} : { sessionId: d }
|
|
44
|
+
} : {
|
|
45
|
+
kind: "json",
|
|
46
|
+
status: 200,
|
|
47
|
+
body: f.length === 1 ? f[0] : f,
|
|
48
|
+
...d === void 0 ? {} : { sessionId: d }
|
|
49
|
+
};
|
|
50
|
+
}, l = (e) => ({
|
|
51
|
+
jsonrpc: "2.0",
|
|
52
|
+
id: null,
|
|
53
|
+
error: {
|
|
54
|
+
code: -32700,
|
|
55
|
+
message: e
|
|
56
|
+
}
|
|
57
|
+
}), u = (e, t) => ({
|
|
58
|
+
jsonrpc: "2.0",
|
|
59
|
+
id: e,
|
|
60
|
+
error: {
|
|
61
|
+
code: -32601,
|
|
62
|
+
message: t
|
|
63
|
+
}
|
|
64
|
+
}), d = (e) => `event: message\ndata: ${JSON.stringify(e)}\n\n`, f = (e) => e !== void 0 && e.split(",").some((e) => e.trim().startsWith(o)), p = async (e) => {
|
|
65
|
+
let t = "";
|
|
66
|
+
for await (let n of e) t += String(n);
|
|
67
|
+
if (t.trim() !== "") try {
|
|
68
|
+
return JSON.parse(t);
|
|
69
|
+
} catch {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
}, m = (n) => async (r, s) => {
|
|
73
|
+
let l = r.method ?? "GET", u = l === "POST" ? await p(r) : void 0, m = await n.source.get(), h = {};
|
|
74
|
+
for (let [e, t] of Object.entries(r.headers)) h[e.toLowerCase()] = Array.isArray(t) ? t[0] : t;
|
|
75
|
+
let g = await c({
|
|
76
|
+
method: l,
|
|
77
|
+
headers: h,
|
|
78
|
+
body: u,
|
|
79
|
+
snapshot: m,
|
|
80
|
+
serverInfo: n.serverInfo,
|
|
81
|
+
acceptsSse: f(h.accept),
|
|
82
|
+
live: n.live ?? e(t(process.env)),
|
|
83
|
+
...n.newSessionId === void 0 ? {} : { newSessionId: n.newSessionId }
|
|
84
|
+
});
|
|
85
|
+
if (g.kind === "empty") {
|
|
86
|
+
s.writeHead(g.status), s.end();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (g.kind === "json") {
|
|
90
|
+
let e = { "content-type": a };
|
|
91
|
+
g.sessionId !== void 0 && (e[i] = g.sessionId), s.writeHead(g.status, e), s.end(JSON.stringify(g.body));
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
let _ = {
|
|
95
|
+
"content-type": o,
|
|
96
|
+
"cache-control": "no-cache",
|
|
97
|
+
connection: "keep-alive"
|
|
98
|
+
};
|
|
99
|
+
g.sessionId !== void 0 && (_[i] = g.sessionId), s.writeHead(200, _);
|
|
100
|
+
for (let e of g.events) s.write(d(e));
|
|
101
|
+
g.keepOpen || s.end();
|
|
102
|
+
};
|
|
103
|
+
//#endregion
|
|
104
|
+
export { c as n, d as r, m as t };
|
package/dist/httpServer.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { t } from "./http-
|
|
4
|
-
import { t as n } from "./serve-
|
|
2
|
+
import { j as e } from "./mcp-CZJe2Frv.js";
|
|
3
|
+
import { t } from "./http-BGeW8WkP.js";
|
|
4
|
+
import { t as n } from "./serve-ZSmqUcRM.js";
|
|
5
5
|
import { createServer as r } from "node:http";
|
|
6
6
|
//#endregion
|
|
7
7
|
//#region src/httpServer.ts
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,56 @@
|
|
|
1
1
|
import { IncomingMessage } from 'node:http';
|
|
2
2
|
import { ServerResponse } from 'node:http';
|
|
3
3
|
|
|
4
|
+
/** The MCP tool-name prefix for an app procedure. Reserved: a static
|
|
5
|
+
* `voltro_*` tool can never collide with it. */
|
|
6
|
+
export declare const APP_TOOL_PREFIX = "app_";
|
|
7
|
+
|
|
8
|
+
export declare interface AppToolInventory {
|
|
9
|
+
readonly enabled: boolean;
|
|
10
|
+
readonly reason?: string;
|
|
11
|
+
readonly tools: ReadonlyArray<AppToolListing>;
|
|
12
|
+
readonly dropped: ReadonlyArray<{
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly reason: string;
|
|
15
|
+
}>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** One admitted app tool, as `GET /_voltro/inspect/agent/tools` reports it. */
|
|
19
|
+
export declare interface AppToolListing {
|
|
20
|
+
readonly name: string;
|
|
21
|
+
readonly tag: string;
|
|
22
|
+
readonly kind: string;
|
|
23
|
+
readonly description: string;
|
|
24
|
+
readonly write: boolean;
|
|
25
|
+
readonly confirm: boolean;
|
|
26
|
+
readonly maxPerRun?: number;
|
|
27
|
+
readonly input?: Record<string, unknown>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* `todos.create` → `app_todos_create`.
|
|
32
|
+
*
|
|
33
|
+
* MCP tool names are `[A-Za-z0-9_-]`; an rpc tag is dotted. The mapping is NOT
|
|
34
|
+
* reversed by string surgery at call time — a tag containing a `-` and one
|
|
35
|
+
* containing a `.` can produce the same name — so the call path looks the
|
|
36
|
+
* original up in the SAME listing it rendered from. A collision drops the later
|
|
37
|
+
* tag (sorted first, so the drop is deterministic) rather than silently
|
|
38
|
+
* shadowing one procedure with another.
|
|
39
|
+
*/
|
|
40
|
+
export declare const appToolName: (tag: string) => string;
|
|
41
|
+
|
|
42
|
+
export declare const boundText: (raw: unknown, maxChars: number) => string;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* `POST /_voltro/inspect/agent/call`. Returns the text the model sees.
|
|
46
|
+
*
|
|
47
|
+
* A refusal — missing credential, policy denial, the app's own guard — comes
|
|
48
|
+
* back as `Error: …` text rather than a thrown failure, exactly as an app tool's
|
|
49
|
+
* rejection does in `@voltro/ai`: a refusal IS information the model should act
|
|
50
|
+
* on, and hiding it behind a transport error makes the agent retry blindly.
|
|
51
|
+
*/
|
|
52
|
+
export declare const callAppTool: (options: LiveAppOptions, tag: string, input: unknown) => Promise<string>;
|
|
53
|
+
|
|
4
54
|
/** Pure tool dispatch → the text payload for an MCP `tools/call` result. */
|
|
5
55
|
export declare const callTool: (snapshot: ManifestSnapshot, name: string, args: Record<string, unknown>) => string;
|
|
6
56
|
|
|
@@ -30,6 +80,14 @@ export declare const createManifestSource: (options: ManifestSourceOptions) => M
|
|
|
30
80
|
|
|
31
81
|
export declare const EMPTY_MANIFEST: CapabilityManifest;
|
|
32
82
|
|
|
83
|
+
/** `GET /_voltro/inspect/agent/tools`. Never throws — a failure becomes an
|
|
84
|
+
* `enabled: false` inventory carrying the reason, because a model handed an
|
|
85
|
+
* empty tool list with no explanation concludes the app has no tools. */
|
|
86
|
+
export declare const fetchAppTools: (options: LiveAppOptions) => Promise<AppToolInventory>;
|
|
87
|
+
|
|
88
|
+
/** `GET /_voltro/inspect/checks` — the framework's invariant checks. */
|
|
89
|
+
export declare const fetchInvariantChecks: (options: LiveAppOptions) => Promise<string>;
|
|
90
|
+
|
|
33
91
|
/** Fetch the live capability manifest from a running api. */
|
|
34
92
|
export declare const fetchManifest: (baseUrl: string, token?: string,
|
|
35
93
|
/** Abort the request after this long — a hung api must not hang the agent. */
|
|
@@ -49,6 +107,27 @@ export declare const getPrompt: (snapshot: ManifestSnapshot, name: string, args?
|
|
|
49
107
|
*/
|
|
50
108
|
export declare const handleMcpRequest: (snapshot: ManifestSnapshot, request: JsonRpcRequest, serverInfo?: ServerInfo) => JsonRpcResponse | null;
|
|
51
109
|
|
|
110
|
+
/**
|
|
111
|
+
* The same protocol, for the methods that need a ROUND TRIP to the app.
|
|
112
|
+
*
|
|
113
|
+
* Two of them do: `tools/list` has to fold in the app's executable agent tools
|
|
114
|
+
* (a set the app's policy decides, not us), and `tools/call` has to reach the
|
|
115
|
+
* app for those tools and for `voltro_check_invariants`. Everything else is
|
|
116
|
+
* unchanged and delegates to the pure `handleMcpRequest` above.
|
|
117
|
+
*
|
|
118
|
+
* A SEPARATE async entry point rather than a widened return type on the pure
|
|
119
|
+
* one — the same split `@voltro/cli` made between `handleInspectRequest` and
|
|
120
|
+
* `handleInspectAsyncRequest`, for the same reason: most of the surface does no
|
|
121
|
+
* I/O and should not become awaitable, and the pure core stays testable without
|
|
122
|
+
* a transport.
|
|
123
|
+
*
|
|
124
|
+
* `live === undefined` degrades to exactly the previous behaviour: manifest
|
|
125
|
+
* introspection only, no app tools, and `voltro_check_invariants` says why it
|
|
126
|
+
* cannot answer rather than throwing an "unknown tool" a reader would misread as
|
|
127
|
+
* a version mismatch.
|
|
128
|
+
*/
|
|
129
|
+
export declare const handleMcpRequestAsync: (snapshot: ManifestSnapshot, request: JsonRpcRequest, serverInfo?: ServerInfo, live?: LiveSurface) => Promise<JsonRpcResponse | null>;
|
|
130
|
+
|
|
52
131
|
/** What `routeHttp` decided the transport should do. */
|
|
53
132
|
export declare type HttpOutcome =
|
|
54
133
|
/** Reply once with a JSON body + status (single JSON-RPC response, or an error). */
|
|
@@ -71,6 +150,8 @@ export declare type HttpOutcome =
|
|
|
71
150
|
readonly status: number;
|
|
72
151
|
};
|
|
73
152
|
|
|
153
|
+
export declare const isAppToolName: (name: string) => boolean;
|
|
154
|
+
|
|
74
155
|
export declare interface JsonRpcRequest {
|
|
75
156
|
readonly jsonrpc: '2.0';
|
|
76
157
|
readonly id?: string | number | null;
|
|
@@ -97,6 +178,73 @@ export declare const listPrompts: () => ReadonlyArray<McpPrompt>;
|
|
|
97
178
|
*/
|
|
98
179
|
export declare const listResources: (snapshot: ManifestSnapshot) => ReadonlyArray<McpResource>;
|
|
99
180
|
|
|
181
|
+
export declare const LIVE_BOUNDS_DEFAULTS: LiveBounds;
|
|
182
|
+
|
|
183
|
+
/** Where the app is and what we may present to it. */
|
|
184
|
+
export declare interface LiveAppOptions {
|
|
185
|
+
readonly baseUrl: string;
|
|
186
|
+
readonly inspectToken?: string;
|
|
187
|
+
/** `VOLTRO_INSPECT_WRITE_TOKEN` — required for any non-GET inspect call. */
|
|
188
|
+
readonly inspectWriteToken?: string;
|
|
189
|
+
/** `VOLTRO_AGENT_TOKEN` — the APP credential a tool call executes as. */
|
|
190
|
+
readonly agentToken?: string;
|
|
191
|
+
readonly bounds: LiveBounds;
|
|
192
|
+
/** Injectable for tests; defaults to the global `fetch`. */
|
|
193
|
+
readonly fetchImpl?: typeof fetch;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export declare const liveAppOptionsFromEnv: (env: Readonly<Record<string, string | undefined>>, overrides?: Partial<LiveBounds>) => LiveAppOptions;
|
|
197
|
+
|
|
198
|
+
/** Ceilings on what the app may send back into a model's context. Every one an
|
|
199
|
+
* env-overridable number rather than a literal buried in the code. */
|
|
200
|
+
export declare interface LiveBounds {
|
|
201
|
+
/** How many app tools may mount. Env `VOLTRO_MCP_MAX_APP_TOOLS`. */
|
|
202
|
+
readonly maxTools: number;
|
|
203
|
+
/** Ceiling on one tool description. Env `VOLTRO_MCP_MAX_DESCRIPTION_CHARS`. */
|
|
204
|
+
readonly maxDescriptionChars: number;
|
|
205
|
+
/** Ceiling on one tool-call result, in bytes. Env `VOLTRO_MCP_MAX_RESULT_BYTES`. */
|
|
206
|
+
readonly maxResultBytes: number;
|
|
207
|
+
/** Per-request deadline. Env `VOLTRO_MCP_TIMEOUT_MS`. */
|
|
208
|
+
readonly requestTimeoutMs: number;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/** The MCP tool shape, mirrored from `tools.ts` to avoid an import cycle. */
|
|
212
|
+
export declare interface LiveMcpTool {
|
|
213
|
+
readonly name: string;
|
|
214
|
+
readonly description: string;
|
|
215
|
+
readonly inputSchema: Record<string, unknown>;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/** What `handleMcpRequestAsync` needs. One interface so a test supplies a fake
|
|
219
|
+
* and never opens a socket — the same seam `McpTransport` is on the client. */
|
|
220
|
+
export declare interface LiveSurface {
|
|
221
|
+
/** The app tools mountable right now, plus everything that did not mount. */
|
|
222
|
+
readonly appTools: () => Promise<{
|
|
223
|
+
readonly mounted: ReadonlyArray<MountedAppTool>;
|
|
224
|
+
readonly dropped: ReadonlyArray<{
|
|
225
|
+
readonly name: string;
|
|
226
|
+
readonly reason: string;
|
|
227
|
+
}>;
|
|
228
|
+
}>;
|
|
229
|
+
/** Execute one, by its rpc TAG (never by the MCP name the model produced). */
|
|
230
|
+
readonly callAppTool: (tag: string, input: unknown) => Promise<string>;
|
|
231
|
+
/** The framework's invariant checks, as JSON text. */
|
|
232
|
+
readonly invariantChecks: () => Promise<string>;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* A `LiveSurface` over a running app, with the tool list TTL-cached.
|
|
237
|
+
*
|
|
238
|
+
* Cached for the same reason `createManifestSource` caches: during `voltro dev`
|
|
239
|
+
* the set changes as files are saved, so a process-lifetime snapshot goes stale
|
|
240
|
+
* within a minute — and re-fetching on every `tools/call` would put a round trip
|
|
241
|
+
* in front of every action. The CALL is never cached.
|
|
242
|
+
*/
|
|
243
|
+
export declare const makeLiveSurface: (options: LiveAppOptions, cache?: {
|
|
244
|
+
readonly ttlMs?: number;
|
|
245
|
+
readonly now?: () => number;
|
|
246
|
+
}) => LiveSurface;
|
|
247
|
+
|
|
100
248
|
/** The stable URI for the whole-manifest resource. */
|
|
101
249
|
export declare const MANIFEST_URI = "voltro://manifest";
|
|
102
250
|
|
|
@@ -123,6 +271,13 @@ export declare interface ManifestProcedure {
|
|
|
123
271
|
readonly kind: 'policy';
|
|
124
272
|
readonly action: string;
|
|
125
273
|
readonly resourceType: string;
|
|
274
|
+
} | {
|
|
275
|
+
/** The erased `openAccess: '<why>'` decision. A procedure is guarded,
|
|
276
|
+
* open-on-purpose, or undecided; without this variant the middle state
|
|
277
|
+
* is indistinguishable from the last, and an agent reading the manifest
|
|
278
|
+
* cannot tell a deliberately public tool from an unreviewed one. */
|
|
279
|
+
readonly kind: 'open';
|
|
280
|
+
readonly reason: string;
|
|
126
281
|
}>;
|
|
127
282
|
/** Present when the descriptor is projected to a public REST endpoint. */
|
|
128
283
|
readonly publicApi?: Record<string, unknown>;
|
|
@@ -168,9 +323,21 @@ export declare interface ManifestTable {
|
|
|
168
323
|
readonly nullable: boolean;
|
|
169
324
|
readonly refersTo?: string;
|
|
170
325
|
readonly enum?: ReadonlyArray<string>;
|
|
326
|
+
/** `.serverOnly()` — never crosses any wire, and refused as mutation input.
|
|
327
|
+
* The only one of the three exposure axes that is a claim ABOUT the wire,
|
|
328
|
+
* so the only one a tool may act on by omitting a field. */
|
|
329
|
+
readonly serverOnly?: boolean;
|
|
330
|
+
/** `.encrypted()` — ciphertext at rest. NOT a wire-exposure signal. */
|
|
331
|
+
readonly encrypted?: boolean;
|
|
332
|
+
/** `.sensitive(class)` — the declared class. The export-masking axis. */
|
|
333
|
+
readonly sensitive?: string;
|
|
171
334
|
}>;
|
|
172
335
|
readonly reactive: boolean;
|
|
173
336
|
readonly framework: boolean;
|
|
337
|
+
/** The primary-key column a row-keyed action targets, when there is one. */
|
|
338
|
+
readonly pkColumn?: string;
|
|
339
|
+
/** False when no single primary key exists — no row can be addressed. */
|
|
340
|
+
readonly editable?: boolean;
|
|
174
341
|
}
|
|
175
342
|
|
|
176
343
|
/** A `prompts/get` result. */
|
|
@@ -231,6 +398,27 @@ export declare class MissingPromptArgumentError extends Error {
|
|
|
231
398
|
constructor(promptName: string, argument: string);
|
|
232
399
|
}
|
|
233
400
|
|
|
401
|
+
/**
|
|
402
|
+
* Project the app's inventory onto MCP tools, bounded and deduplicated.
|
|
403
|
+
*
|
|
404
|
+
* The description carries the WRITE marker explicitly. A model choosing between
|
|
405
|
+
* `app_todos_list` and `app_todos_delete` has no other signal that one of them
|
|
406
|
+
* destroys data — the kind is in our type system, not in its context.
|
|
407
|
+
*/
|
|
408
|
+
export declare const mountAppTools: (inventory: AppToolInventory, bounds: LiveBounds) => {
|
|
409
|
+
readonly mounted: ReadonlyArray<MountedAppTool>;
|
|
410
|
+
readonly dropped: ReadonlyArray<{
|
|
411
|
+
name: string;
|
|
412
|
+
reason: string;
|
|
413
|
+
}>;
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
/** An app tool as a mountable MCP tool, plus the tag to call it by. */
|
|
417
|
+
export declare interface MountedAppTool {
|
|
418
|
+
readonly tool: LiveMcpTool;
|
|
419
|
+
readonly tag: string;
|
|
420
|
+
}
|
|
421
|
+
|
|
234
422
|
/**
|
|
235
423
|
* MCP version negotiation: echo the client's requested revision when we
|
|
236
424
|
* support it, otherwise answer with our latest (the client then decides
|
|
@@ -249,6 +437,9 @@ export declare interface NodeHttpHandlerOptions {
|
|
|
249
437
|
readonly source: ManifestSource;
|
|
250
438
|
readonly serverInfo: ServerInfo;
|
|
251
439
|
readonly newSessionId?: () => string;
|
|
440
|
+
/** Defaults to a surface built from `process.env` — the same variables the
|
|
441
|
+
* stdio bin reads, so the two transports expose the same tools. */
|
|
442
|
+
readonly live?: LiveSurface;
|
|
252
443
|
}
|
|
253
444
|
|
|
254
445
|
export declare const PROMPTS: ReadonlyArray<McpPrompt>;
|
|
@@ -263,13 +454,21 @@ export declare const PROTOCOL_VERSION = "2025-06-18";
|
|
|
263
454
|
*/
|
|
264
455
|
export declare const readResource: (snapshot: ManifestSnapshot, uri: string) => ReadonlyArray<McpResourceContents>;
|
|
265
456
|
|
|
457
|
+
export declare const resolveLiveBounds: (env: Readonly<Record<string, string | undefined>>, overrides?: Partial<LiveBounds>) => LiveBounds;
|
|
458
|
+
|
|
266
459
|
/**
|
|
267
|
-
* The
|
|
268
|
-
*
|
|
269
|
-
*
|
|
270
|
-
*
|
|
460
|
+
* The protocol core of the Streamable HTTP transport. Given the HTTP method,
|
|
461
|
+
* headers and parsed body, decide the response shape. Reuses the SAME
|
|
462
|
+
* `handleMcpRequestAsync` the stdio transport uses — the two transports share one
|
|
463
|
+
* protocol implementation, and that is the property that stopped an executable
|
|
464
|
+
* tool surface from existing on one of them only.
|
|
465
|
+
*
|
|
466
|
+
* Async because two methods now reach the app (`tools/list` folds in its agent
|
|
467
|
+
* tools, `tools/call` executes one). Everything else still resolves without
|
|
468
|
+
* touching the network. The DECISION is still pure in the sense that matters —
|
|
469
|
+
* no socket is bound here, and a test supplies a `live` double.
|
|
271
470
|
*/
|
|
272
|
-
export declare const routeHttp: (options: RouteHttpOptions) => HttpOutcome
|
|
471
|
+
export declare const routeHttp: (options: RouteHttpOptions) => Promise<HttpOutcome>;
|
|
273
472
|
|
|
274
473
|
export declare interface RouteHttpOptions {
|
|
275
474
|
readonly method: string;
|
|
@@ -283,6 +482,9 @@ export declare interface RouteHttpOptions {
|
|
|
283
482
|
readonly acceptsSse: boolean;
|
|
284
483
|
/** Mint a session id (override for deterministic tests). */
|
|
285
484
|
readonly newSessionId?: () => string;
|
|
485
|
+
/** The live app surface — executable agent tools + invariant checks. Absent ⇒
|
|
486
|
+
* manifest introspection only, which is what this transport did before. */
|
|
487
|
+
readonly live?: LiveSurface;
|
|
286
488
|
}
|
|
287
489
|
|
|
288
490
|
/** Fallback identity. The bin overrides `version` with the value from its own
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as
|
|
3
|
-
export { e as EMPTY_MANIFEST,
|
|
1
|
+
import { A as e, C as t, D as n, E as r, M as i, O as a, S as o, T as s, _ as c, a as l, b as u, c as d, d as f, f as p, g as m, h, i as g, j as _, k as v, l as y, m as b, n as x, o as S, p as C, r as w, s as T, t as E, u as D, v as O, w as k, x as A, y as j } from "./mcp-CZJe2Frv.js";
|
|
2
|
+
import { n as M, r as N, t as P } from "./http-BGeW8WkP.js";
|
|
3
|
+
export { O as APP_TOOL_PREFIX, e as EMPTY_MANIFEST, j as LIVE_BOUNDS_DEFAULTS, p as MANIFEST_URI, T as MissingPromptArgumentError, d as PROMPTS, E as PROTOCOL_VERSION, x as SERVER_INFO, w as SUPPORTED_PROTOCOL_VERSIONS, m as TOOLS, y as UnknownPromptError, C as UnknownResourceError, u as appToolName, A as boundText, o as callAppTool, c as callTool, _ as createManifestSource, t as fetchAppTools, k as fetchInvariantChecks, i as fetchManifest, D as getPrompt, g as handleMcpRequest, l as handleMcpRequestAsync, s as isAppToolName, f as listPrompts, b as listResources, r as liveAppOptionsFromEnv, n as makeLiveSurface, a as mountAppTools, S as negotiateProtocolVersion, P as nodeHttpHandler, h as readResource, v as resolveLiveBounds, M as routeHttp, N as sseEvent };
|