@mcp-index/sdk 0.18.0 → 0.19.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 +22 -1
- package/README.md +178 -0
- package/dist/src/ai.d.ts +96 -0
- package/dist/src/ai.d.ts.map +1 -0
- package/dist/src/ai.js +151 -0
- package/dist/src/ai.js.map +1 -0
- package/dist/src/lock/check.d.ts +143 -0
- package/dist/src/lock/check.d.ts.map +1 -0
- package/dist/src/lock/check.js +274 -0
- package/dist/src/lock/check.js.map +1 -0
- package/dist/src/lock/digest.d.ts +48 -0
- package/dist/src/lock/digest.d.ts.map +1 -0
- package/dist/src/lock/digest.js +234 -0
- package/dist/src/lock/digest.js.map +1 -0
- package/dist/src/lock/events.d.ts +82 -0
- package/dist/src/lock/events.d.ts.map +1 -0
- package/dist/src/lock/events.js +80 -0
- package/dist/src/lock/events.js.map +1 -0
- package/dist/src/lock/index.d.ts +20 -0
- package/dist/src/lock/index.d.ts.map +1 -0
- package/dist/src/lock/index.js +14 -0
- package/dist/src/lock/index.js.map +1 -0
- package/dist/src/lock/lock.d.ts +195 -0
- package/dist/src/lock/lock.d.ts.map +1 -0
- package/dist/src/lock/lock.js +1075 -0
- package/dist/src/lock/lock.js.map +1 -0
- package/dist/src/lock/pg.d.ts +150 -0
- package/dist/src/lock/pg.d.ts.map +1 -0
- package/dist/src/lock/pg.js +539 -0
- package/dist/src/lock/pg.js.map +1 -0
- package/dist/src/lock/rawList.d.ts +127 -0
- package/dist/src/lock/rawList.d.ts.map +1 -0
- package/dist/src/lock/rawList.js +561 -0
- package/dist/src/lock/rawList.js.map +1 -0
- package/dist/src/lock/signing.d.ts +35 -0
- package/dist/src/lock/signing.d.ts.map +1 -0
- package/dist/src/lock/signing.js +85 -0
- package/dist/src/lock/signing.js.map +1 -0
- package/dist/src/lock/store.d.ts +149 -0
- package/dist/src/lock/store.d.ts.map +1 -0
- package/dist/src/lock/store.js +459 -0
- package/dist/src/lock/store.js.map +1 -0
- package/dist/src/wrap.d.ts.map +1 -1
- package/dist/src/wrap.js +85 -3
- package/dist/src/wrap.js.map +1 -1
- package/package.json +31 -2
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lock mode for the official MCP TypeScript client, at the transport.
|
|
3
|
+
*
|
|
4
|
+
* `Client.listTools()` returns tools after its zod schema has stripped unknown
|
|
5
|
+
* members, so a digest over that result is not a digest over what the server
|
|
6
|
+
* sent. LockedTransport sits between the Client and its real Transport and
|
|
7
|
+
* works on the parsed JSON-RPC message instead. The transports parse each
|
|
8
|
+
* message with JSON.parse and check only the envelope, so every member inside
|
|
9
|
+
* `result.tools`, `__proto__` included, is still there as sent.
|
|
10
|
+
*
|
|
11
|
+
* For a `tools/list` request from the client it:
|
|
12
|
+
* - starts a listing (section 9.2.1) when it sends the request. Until the
|
|
13
|
+
* listing is decided or fails, every `tools/call` is refused with
|
|
14
|
+
* `no-listing`. A second cursorless `tools/list` abandons the first, whose
|
|
15
|
+
* request is answered with an error;
|
|
16
|
+
* - classifies every frame from the server as section 9.2.2 says
|
|
17
|
+
* (classifyFrame): only the response to an unanswered `tools/list`,
|
|
18
|
+
* matched by id with exact JSON type and value, can carry tools, and only
|
|
19
|
+
* that or the `initialize` or `server/discover` response can carry
|
|
20
|
+
* instructions. Anything else that carries them, or has both a method and
|
|
21
|
+
* a result or error, is dropped and reported to onerror. A client request
|
|
22
|
+
* whose id it matches is answered with an error under that id and is no
|
|
23
|
+
* longer pending; when that request is the listing's, or one of its page
|
|
24
|
+
* requests, the listing fails. A response whose id matches no request is
|
|
25
|
+
* dropped too;
|
|
26
|
+
* - follows `nextCursor` itself, sending its own page requests under private
|
|
27
|
+
* ids, so one listing is every page (section 9.2). The client gets one
|
|
28
|
+
* response with every shown tool and no cursor. A client request that
|
|
29
|
+
* carries a cursor is answered with an error, since there is no partial
|
|
30
|
+
* listing in lock mode;
|
|
31
|
+
* - loads a lock snapshot, runs checkListing on the raw tools, installs the
|
|
32
|
+
* decision in the CallGate, emits a listing event, and passes on only the
|
|
33
|
+
* shown raw entries, without a top-level `_meta` that the decision removes
|
|
34
|
+
* (section 9.2.3). The client then parses exactly those.
|
|
35
|
+
*
|
|
36
|
+
* Every outgoing `tools/call` goes through the CallGate first. A refused call
|
|
37
|
+
* is never sent; the client gets a -32011 error with data.reason. This covers
|
|
38
|
+
* callTool, request, requestStream and the task helpers alike, because they
|
|
39
|
+
* all end in Transport.send. A call on a snapshot older than maxStalenessMs
|
|
40
|
+
* (default 60 s) reloads it first; the reload can only shrink the allow-list,
|
|
41
|
+
* and if it fails the call gets `lock-stale` and the next call tries again.
|
|
42
|
+
*
|
|
43
|
+
* `notifications/tools/list_changed` is passed on and marks a listing as due.
|
|
44
|
+
* It does not change the allow-list, and this adapter does not start a
|
|
45
|
+
* listing on its own (the spec's SHOULD); the client asks for one. A listing
|
|
46
|
+
* that fails (an error response, a result with no tools array, a page that
|
|
47
|
+
* cannot be requested or gets no response, a page or tool limit exceeded)
|
|
48
|
+
* refuses every call with `unreachable` until a listing completes (section
|
|
49
|
+
* 9.5). Server instructions arrive in the initialize or server/discover
|
|
50
|
+
* result; they are checked there and stripped when the check says so.
|
|
51
|
+
*
|
|
52
|
+
* Unanswered requests are tracked in bounded maps. An entry leaves on its
|
|
53
|
+
* response, on the client's notifications/cancelled, after REQUEST_TTL_MS, or,
|
|
54
|
+
* when the map is full, oldest first. If that entry is the listing in
|
|
55
|
+
* progress, the listing fails.
|
|
56
|
+
*
|
|
57
|
+
* Lock mode has no auto-accept, first-use pin or re-pin, and this adapter
|
|
58
|
+
* takes no option that would add one.
|
|
59
|
+
*/
|
|
60
|
+
import { CallGate, DEFAULT_MAX_STALENESS_MS, checkInstructions, checkListing, isPosture, refusalError } from "./check.js";
|
|
61
|
+
import { listingEvent, refusalEvent, emit } from "./events.js";
|
|
62
|
+
import { LockError, validateIdentity } from "./lock.js";
|
|
63
|
+
import { snapshotOfError } from "./store.js";
|
|
64
|
+
/** Pages and tools one listing may span before the server is treated as unreachable. */
|
|
65
|
+
export const MAX_LIST_PAGES = 100;
|
|
66
|
+
export const MAX_LIST_TOOLS = 10_000;
|
|
67
|
+
/** Unanswered requests tracked at once; past this the oldest is forgotten. */
|
|
68
|
+
export const MAX_OUTSTANDING = 4_096;
|
|
69
|
+
/** Age after which an unanswered request is forgotten (its late response is dropped). */
|
|
70
|
+
export const REQUEST_TTL_MS = 600_000;
|
|
71
|
+
export { DEFAULT_MAX_STALENESS_MS };
|
|
72
|
+
const FORBIDDEN_OPTIONS = ["autoAccept", "autoApprove", "tofu", "newTools", "repin", "migrate"];
|
|
73
|
+
function isObj(v) {
|
|
74
|
+
return v !== null && typeof v === "object" && !Array.isArray(v);
|
|
75
|
+
}
|
|
76
|
+
function own(obj, key) {
|
|
77
|
+
return Object.getOwnPropertyDescriptor(obj, key)?.value;
|
|
78
|
+
}
|
|
79
|
+
function hasOwn(obj, key) {
|
|
80
|
+
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
81
|
+
}
|
|
82
|
+
/** Map key for a request id: JSON type and value. Null, booleans and the rest have none. */
|
|
83
|
+
function idKey(id) {
|
|
84
|
+
if (typeof id === "number" && Number.isFinite(id))
|
|
85
|
+
return `n:${id}`;
|
|
86
|
+
if (typeof id === "string")
|
|
87
|
+
return `s:${id}`;
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
/** Section 9.2.2: `id` equals one of `ids` in JSON type and value. Null matches nothing. */
|
|
91
|
+
export function idMatches(id, ids) {
|
|
92
|
+
const key = idKey(id);
|
|
93
|
+
return key !== null && ids.some((i) => idKey(i) === key);
|
|
94
|
+
}
|
|
95
|
+
/** Requests whose response may carry instructions (section 9.2.2). */
|
|
96
|
+
export const HANDSHAKE_METHODS = Object.freeze(["initialize", "server/discover"]);
|
|
97
|
+
/**
|
|
98
|
+
* What the host does with one frame from the server (section 9.2.2):
|
|
99
|
+
* `listing` (a page of the listing whose request it answers), `handshake`
|
|
100
|
+
* (the initialize or server/discover response; its instructions are
|
|
101
|
+
* checked), `drop`, or `relay`. `isInflight` and `isHandshake` say whether an
|
|
102
|
+
* id matches an unanswered tools/list or handshake request; unanswered
|
|
103
|
+
* tools/list requests are matched first.
|
|
104
|
+
*/
|
|
105
|
+
export function classifyFrame(frame, isInflight, isHandshake) {
|
|
106
|
+
if (!isObj(frame))
|
|
107
|
+
return "drop";
|
|
108
|
+
const result = own(frame, "result");
|
|
109
|
+
const carriesTools = isObj(result) && hasOwn(result, "tools");
|
|
110
|
+
const carriesInstructions = isObj(result) && hasOwn(result, "instructions");
|
|
111
|
+
if (hasOwn(frame, "method"))
|
|
112
|
+
return hasOwn(frame, "result") || hasOwn(frame, "error") ? "drop" : "relay";
|
|
113
|
+
if (!hasOwn(frame, "id"))
|
|
114
|
+
return carriesTools || carriesInstructions ? "drop" : "relay";
|
|
115
|
+
const id = own(frame, "id");
|
|
116
|
+
if (isInflight(id))
|
|
117
|
+
return "listing";
|
|
118
|
+
if (carriesTools)
|
|
119
|
+
return "drop";
|
|
120
|
+
if (isHandshake(id))
|
|
121
|
+
return "handshake";
|
|
122
|
+
if (carriesInstructions)
|
|
123
|
+
return "drop";
|
|
124
|
+
return "relay";
|
|
125
|
+
}
|
|
126
|
+
/** Copy a result object member by member, leaving out `drop`. */
|
|
127
|
+
function copyWithout(result, drop) {
|
|
128
|
+
const out = {};
|
|
129
|
+
for (const key of Object.keys(result)) {
|
|
130
|
+
if (drop.includes(key))
|
|
131
|
+
continue;
|
|
132
|
+
Object.defineProperty(out, key, { value: own(result, key), enumerable: true, writable: true, configurable: true });
|
|
133
|
+
}
|
|
134
|
+
return out;
|
|
135
|
+
}
|
|
136
|
+
export class LockedTransport {
|
|
137
|
+
onclose;
|
|
138
|
+
onerror;
|
|
139
|
+
onmessage;
|
|
140
|
+
gate;
|
|
141
|
+
#inner;
|
|
142
|
+
#store;
|
|
143
|
+
#identity;
|
|
144
|
+
#posture;
|
|
145
|
+
#sink;
|
|
146
|
+
#events;
|
|
147
|
+
#now;
|
|
148
|
+
/** Client request id key to method, for every request still unanswered. */
|
|
149
|
+
#outstanding = new Map();
|
|
150
|
+
/** Private page request id key to the listing it belongs to. */
|
|
151
|
+
#pages = new Map();
|
|
152
|
+
#current = null;
|
|
153
|
+
#queue = Promise.resolve();
|
|
154
|
+
#served = undefined;
|
|
155
|
+
#lastTools = null;
|
|
156
|
+
#listingDue = false;
|
|
157
|
+
#seq = 0;
|
|
158
|
+
#tag = Math.random().toString(36).slice(2, 10);
|
|
159
|
+
constructor(inner, options) {
|
|
160
|
+
for (const key of FORBIDDEN_OPTIONS) {
|
|
161
|
+
if (key in options)
|
|
162
|
+
throw new Error(`lock mode does not accept ${key}`);
|
|
163
|
+
}
|
|
164
|
+
if (!isPosture(options.posture))
|
|
165
|
+
throw new Error(`unknown posture ${String(options.posture)}`);
|
|
166
|
+
this.#inner = inner;
|
|
167
|
+
this.#store = options.store;
|
|
168
|
+
this.#identity = validateIdentity(options.identity);
|
|
169
|
+
this.#posture = options.posture;
|
|
170
|
+
this.#sink = options.sink;
|
|
171
|
+
this.#now = options.now ?? Date.now;
|
|
172
|
+
this.gate = new CallGate({ maxStalenessMs: options.maxStalenessMs ?? DEFAULT_MAX_STALENESS_MS, now: this.#now });
|
|
173
|
+
this.#events = { host: options.host ?? "mcpindex-sdk", identity: this.#identity };
|
|
174
|
+
}
|
|
175
|
+
get sessionId() {
|
|
176
|
+
return this.#inner.sessionId;
|
|
177
|
+
}
|
|
178
|
+
setProtocolVersion(version) {
|
|
179
|
+
this.#inner.setProtocolVersion?.(version);
|
|
180
|
+
}
|
|
181
|
+
/** True after a list_changed notification until the next listing completes. */
|
|
182
|
+
get listingDue() {
|
|
183
|
+
return this.#listingDue;
|
|
184
|
+
}
|
|
185
|
+
/** The decision for the latest complete listing on this connection, or null. */
|
|
186
|
+
get decision() {
|
|
187
|
+
return this.gate.decision;
|
|
188
|
+
}
|
|
189
|
+
async start() {
|
|
190
|
+
this.#inner.onmessage = (message, extra) => {
|
|
191
|
+
this.#queue = this.#queue
|
|
192
|
+
.then(() => this.#incoming(message, extra))
|
|
193
|
+
.catch((exc) => this.onerror?.(exc instanceof Error ? exc : new Error(String(exc))));
|
|
194
|
+
};
|
|
195
|
+
this.#inner.onerror = (error) => this.onerror?.(error);
|
|
196
|
+
this.#inner.onclose = () => this.onclose?.();
|
|
197
|
+
await this.#inner.start();
|
|
198
|
+
}
|
|
199
|
+
async close() {
|
|
200
|
+
await this.#inner.close();
|
|
201
|
+
}
|
|
202
|
+
async send(message, options) {
|
|
203
|
+
const msg = message;
|
|
204
|
+
if (Array.isArray(msg))
|
|
205
|
+
throw new Error("lock mode does not send JSON-RPC batches");
|
|
206
|
+
this.#expire();
|
|
207
|
+
if (isObj(msg) && own(msg, "method") === "notifications/cancelled") {
|
|
208
|
+
const params = own(msg, "params");
|
|
209
|
+
const key = isObj(params) ? idKey(own(params, "requestId")) : null;
|
|
210
|
+
if (key !== null)
|
|
211
|
+
this.#forget(key, "the client cancelled the listing request");
|
|
212
|
+
}
|
|
213
|
+
if (isObj(msg) && own(msg, "method") === "tools/call" && idKey(own(msg, "id")) === null) {
|
|
214
|
+
throw new Error("lock mode refuses a tools/call without a valid request id");
|
|
215
|
+
}
|
|
216
|
+
if (isObj(msg) && typeof own(msg, "method") === "string" && idKey(own(msg, "id")) !== null) {
|
|
217
|
+
const method = own(msg, "method");
|
|
218
|
+
const id = own(msg, "id");
|
|
219
|
+
const key = idKey(id);
|
|
220
|
+
const params = own(msg, "params");
|
|
221
|
+
if (method === "tools/call") {
|
|
222
|
+
const name = isObj(params) ? own(params, "name") : undefined;
|
|
223
|
+
const verdict = await this.#checkCall(typeof name === "string" ? name : null);
|
|
224
|
+
if (verdict !== "allow") {
|
|
225
|
+
const tool = typeof name === "string" ? name : null;
|
|
226
|
+
// As in the Python host: the event names "" and data.tool is left out.
|
|
227
|
+
emit(this.#sink, refusalEvent(this.#events, tool ?? "", verdict));
|
|
228
|
+
this.#deliverLater({ jsonrpc: "2.0", id, error: refusalError(tool, verdict) });
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
if (method === "tools/list" && isObj(params) && own(params, "cursor") !== undefined) {
|
|
233
|
+
this.#deliverLater({
|
|
234
|
+
jsonrpc: "2.0",
|
|
235
|
+
id,
|
|
236
|
+
error: { code: -32602, message: "lock mode collects every page itself; send tools/list without a cursor" },
|
|
237
|
+
});
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
this.#forget(key, "the listing request id was reused");
|
|
241
|
+
while (this.#outstanding.size >= MAX_OUTSTANDING) {
|
|
242
|
+
this.#forget(this.#outstanding.keys().next().value, "too many requests without a response");
|
|
243
|
+
}
|
|
244
|
+
this.#outstanding.set(key, { value: method, at: this.#now() });
|
|
245
|
+
if (method === "tools/list") {
|
|
246
|
+
// Section 9.2.1: the listing starts now; an earlier one is abandoned.
|
|
247
|
+
if (this.#current !== null)
|
|
248
|
+
this.#abandon(this.#current);
|
|
249
|
+
this.#current = { clientId: id, clientKey: key, collecting: null };
|
|
250
|
+
this.gate.beginListing();
|
|
251
|
+
try {
|
|
252
|
+
await this.#inner.send(message, options);
|
|
253
|
+
}
|
|
254
|
+
catch (exc) {
|
|
255
|
+
this.#outstanding.delete(key);
|
|
256
|
+
if (this.#current?.clientKey === key) {
|
|
257
|
+
this.#current = null;
|
|
258
|
+
this.gate.markUnreachable();
|
|
259
|
+
}
|
|
260
|
+
throw exc;
|
|
261
|
+
}
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
await this.#inner.send(message, options);
|
|
266
|
+
}
|
|
267
|
+
/** Stop tracking a client request. If it is the listing in progress, that listing fails. */
|
|
268
|
+
#forget(key, why) {
|
|
269
|
+
if (!this.#outstanding.delete(key))
|
|
270
|
+
return;
|
|
271
|
+
const current = this.#current;
|
|
272
|
+
if (current !== null && current.clientKey === key)
|
|
273
|
+
this.#fail(current, why);
|
|
274
|
+
}
|
|
275
|
+
/** A newer cursorless tools/list replaced this listing. */
|
|
276
|
+
#abandon(listing) {
|
|
277
|
+
this.#dropPages(listing);
|
|
278
|
+
this.#outstanding.delete(listing.clientKey);
|
|
279
|
+
if (this.#current === listing)
|
|
280
|
+
this.#current = null;
|
|
281
|
+
this.#deliverLater({
|
|
282
|
+
jsonrpc: "2.0",
|
|
283
|
+
id: listing.clientId,
|
|
284
|
+
error: { code: -32603, message: "lock mode: a newer tools/list replaced this listing" },
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
#dropPages(listing) {
|
|
288
|
+
for (const [key, entry] of this.#pages)
|
|
289
|
+
if (entry.value === listing)
|
|
290
|
+
this.#pages.delete(key);
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* The listing failed. Fail closed: every call is refused with unreachable
|
|
294
|
+
* until a listing completes, and the client's request gets an error.
|
|
295
|
+
*/
|
|
296
|
+
#fail(listing, why, error) {
|
|
297
|
+
if (this.#current !== listing)
|
|
298
|
+
return;
|
|
299
|
+
this.#current = null;
|
|
300
|
+
this.#dropPages(listing);
|
|
301
|
+
this.#outstanding.delete(listing.clientKey);
|
|
302
|
+
this.gate.markUnreachable();
|
|
303
|
+
this.#deliver({ jsonrpc: "2.0", id: listing.clientId, error: error ?? { code: -32603, message: `lock mode: ${why}` } });
|
|
304
|
+
}
|
|
305
|
+
async #checkCall(name) {
|
|
306
|
+
const decision = this.gate.decision;
|
|
307
|
+
if (this.gate.isStale() &&
|
|
308
|
+
!this.gate.listingInProgress &&
|
|
309
|
+
!this.gate.unreachable &&
|
|
310
|
+
decision !== null &&
|
|
311
|
+
decision.lockError === null) {
|
|
312
|
+
// Section 9.8: a decided whole-lock failure never reloads; it keeps its reason.
|
|
313
|
+
await this.#refresh();
|
|
314
|
+
}
|
|
315
|
+
const verdict = this.gate.check(name ?? "");
|
|
316
|
+
// A name that is not a string is never on an allow-list.
|
|
317
|
+
if (name === null && verdict === "allow")
|
|
318
|
+
return "not-listed";
|
|
319
|
+
return verdict;
|
|
320
|
+
}
|
|
321
|
+
/** Forget requests older than REQUEST_TTL_MS. A forgotten page request fails its listing. */
|
|
322
|
+
#expire() {
|
|
323
|
+
const cutoff = this.#now() - REQUEST_TTL_MS;
|
|
324
|
+
for (const [key, entry] of this.#outstanding) {
|
|
325
|
+
if (entry.at > cutoff)
|
|
326
|
+
break;
|
|
327
|
+
this.#forget(key, "the listing request got no response");
|
|
328
|
+
}
|
|
329
|
+
for (const [key, entry] of this.#pages) {
|
|
330
|
+
if (entry.at > cutoff)
|
|
331
|
+
break;
|
|
332
|
+
this.#pages.delete(key);
|
|
333
|
+
this.#fail(entry.value, "page request got no response");
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Reload the snapshot and re-check the last listing (section 9.8). The
|
|
338
|
+
* allow-list keeps only names allowed both before and after; a name the
|
|
339
|
+
* reload drops takes its new reason. A reload whose lock does not load
|
|
340
|
+
* changes nothing, so the call gets lock-stale and the next one retries.
|
|
341
|
+
*/
|
|
342
|
+
async #refresh() {
|
|
343
|
+
const previous = this.gate.decision;
|
|
344
|
+
const tools = this.#lastTools;
|
|
345
|
+
if (previous === null || tools === null)
|
|
346
|
+
return;
|
|
347
|
+
let snapshot;
|
|
348
|
+
try {
|
|
349
|
+
snapshot = await this.#store.loadSnapshot();
|
|
350
|
+
}
|
|
351
|
+
catch {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
if (snapshot.lock instanceof LockError)
|
|
355
|
+
return;
|
|
356
|
+
// A listing that started, completed or failed during the await is newer; never overwrite it.
|
|
357
|
+
if (this.gate.decision !== previous || this.gate.unreachable || this.gate.listingInProgress)
|
|
358
|
+
return;
|
|
359
|
+
const fresh = checkListing(snapshot.lock, this.#identity, { tools, instructions: this.#served }, this.#posture);
|
|
360
|
+
const callable = new Set([...previous.callable].filter((n) => fresh.callable.has(n)));
|
|
361
|
+
const withheld = new Map(previous.withheld);
|
|
362
|
+
for (const name of previous.callable) {
|
|
363
|
+
const reason = callable.has(name) ? undefined : fresh.withheld.get(name);
|
|
364
|
+
if (reason !== undefined)
|
|
365
|
+
withheld.set(name, reason); // otherwise checkCall says not-listed
|
|
366
|
+
}
|
|
367
|
+
this.gate.record(Object.freeze({ ...previous, callable, withheld }), snapshot);
|
|
368
|
+
}
|
|
369
|
+
#deliver(message, extra) {
|
|
370
|
+
this.onmessage?.(message, extra);
|
|
371
|
+
}
|
|
372
|
+
#deliverLater(message) {
|
|
373
|
+
queueMicrotask(() => this.#deliver(message));
|
|
374
|
+
}
|
|
375
|
+
async #snapshot() {
|
|
376
|
+
try {
|
|
377
|
+
return await this.#store.loadSnapshot();
|
|
378
|
+
}
|
|
379
|
+
catch (exc) {
|
|
380
|
+
return snapshotOfError(new LockError("lock-unreadable", exc.message ?? "store failed"), this.#now());
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
#isInflight(id) {
|
|
384
|
+
const key = idKey(id);
|
|
385
|
+
return key !== null && (this.#pages.has(key) || this.#outstanding.get(key)?.value === "tools/list");
|
|
386
|
+
}
|
|
387
|
+
#isHandshake(id) {
|
|
388
|
+
const key = idKey(id);
|
|
389
|
+
const method = key === null ? undefined : this.#outstanding.get(key)?.value;
|
|
390
|
+
return method !== undefined && HANDSHAKE_METHODS.includes(method);
|
|
391
|
+
}
|
|
392
|
+
async #incoming(message, extra) {
|
|
393
|
+
this.#expire();
|
|
394
|
+
const kind = classifyFrame(message, (id) => this.#isInflight(id), (id) => this.#isHandshake(id));
|
|
395
|
+
if (kind === "drop") {
|
|
396
|
+
this.#drop(message);
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
const msg = message;
|
|
400
|
+
if (kind === "relay" && hasOwn(msg, "method")) {
|
|
401
|
+
if (own(msg, "method") === "notifications/tools/list_changed" && !hasOwn(msg, "id"))
|
|
402
|
+
this.#listingDue = true;
|
|
403
|
+
this.#deliver(msg, extra);
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
const key = idKey(own(msg, "id"));
|
|
407
|
+
if (kind === "relay" && key === null) {
|
|
408
|
+
this.#deliver(msg, extra); // a response without a usable id and without tools; the client reports it
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
const page = key === null ? undefined : this.#pages.get(key);
|
|
412
|
+
if (page !== undefined) {
|
|
413
|
+
this.#pages.delete(key);
|
|
414
|
+
await this.#onPage(page.value, msg);
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
const entry = key === null ? undefined : this.#outstanding.get(key);
|
|
418
|
+
if (entry === undefined) {
|
|
419
|
+
this.onerror?.(new Error("dropped a response that matches no outstanding request"));
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
this.#outstanding.delete(key);
|
|
423
|
+
if (kind === "handshake") {
|
|
424
|
+
await this.#onInitialize(msg, extra);
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
if (kind === "listing") {
|
|
428
|
+
const listing = this.#current;
|
|
429
|
+
if (listing === null || listing.clientKey !== key)
|
|
430
|
+
return; // abandoned or failed already
|
|
431
|
+
const error = own(msg, "error");
|
|
432
|
+
if (error !== undefined) {
|
|
433
|
+
this.#fail(listing, "tools/list failed", error);
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
const result = own(msg, "result");
|
|
437
|
+
if (!isObj(result)) {
|
|
438
|
+
this.#fail(listing, "tools/list result is not an object");
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
listing.collecting = { first: result, tools: [], cursors: new Set(), pages: 0 };
|
|
442
|
+
await this.#onPage(listing, msg);
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
this.#deliver(msg, extra);
|
|
446
|
+
}
|
|
447
|
+
/** Report a dropped frame, and answer the client request it matched so the client does not wait. */
|
|
448
|
+
#drop(message) {
|
|
449
|
+
this.onerror?.(new Error("dropped a frame from the server that section 9.2.2 does not allow to reach the client"));
|
|
450
|
+
if (!isObj(message))
|
|
451
|
+
return;
|
|
452
|
+
const key = idKey(own(message, "id"));
|
|
453
|
+
if (key === null)
|
|
454
|
+
return;
|
|
455
|
+
const page = this.#pages.get(key);
|
|
456
|
+
if (page !== undefined) {
|
|
457
|
+
this.#pages.delete(key);
|
|
458
|
+
this.#fail(page.value, "the server answered a page request with a frame that was dropped");
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
const entry = this.#outstanding.get(key);
|
|
462
|
+
if (entry === undefined)
|
|
463
|
+
return;
|
|
464
|
+
const current = this.#current;
|
|
465
|
+
if (current !== null && current.clientKey === key) {
|
|
466
|
+
this.#fail(current, "the server answered tools/list with a frame that was dropped");
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
this.#outstanding.delete(key);
|
|
470
|
+
this.#deliver({
|
|
471
|
+
jsonrpc: "2.0",
|
|
472
|
+
id: own(message, "id"),
|
|
473
|
+
error: { code: -32603, message: `lock mode: the response to ${entry.value} was dropped` },
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
async #onInitialize(message, extra) {
|
|
477
|
+
const result = own(message, "result");
|
|
478
|
+
if (!isObj(result)) {
|
|
479
|
+
this.#deliver(message, extra);
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
this.#served = own(result, "instructions");
|
|
483
|
+
const snapshot = await this.#snapshot();
|
|
484
|
+
const verdict = checkInstructions(snapshot.lock, this.#identity, this.#served, this.#posture);
|
|
485
|
+
if (!verdict.strip) {
|
|
486
|
+
this.#deliver(message, extra);
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
this.#deliver({ ...copyWithout(message, ["result"]), result: copyWithout(result, ["instructions"]) }, extra);
|
|
490
|
+
}
|
|
491
|
+
async #onPage(listing, message) {
|
|
492
|
+
const collecting = listing.collecting;
|
|
493
|
+
if (this.#current !== listing || collecting === null)
|
|
494
|
+
return;
|
|
495
|
+
const error = own(message, "error");
|
|
496
|
+
if (error !== undefined) {
|
|
497
|
+
// A failed page means the listing failed; no earlier allow-list is used.
|
|
498
|
+
this.#fail(listing, "a page request failed", error);
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
const result = own(message, "result");
|
|
502
|
+
const tools = isObj(result) ? own(result, "tools") : undefined;
|
|
503
|
+
if (!Array.isArray(tools)) {
|
|
504
|
+
this.#fail(listing, "tools/list result has no tools array");
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
collecting.pages += 1;
|
|
508
|
+
for (const t of tools)
|
|
509
|
+
collecting.tools.push(t);
|
|
510
|
+
if (collecting.pages > MAX_LIST_PAGES || collecting.tools.length > MAX_LIST_TOOLS) {
|
|
511
|
+
this.#fail(listing, "listing exceeds the page or tool limit");
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
const cursor = isObj(result) ? own(result, "nextCursor") : undefined;
|
|
515
|
+
if (typeof cursor === "string" && cursor !== "") {
|
|
516
|
+
if (collecting.cursors.has(cursor)) {
|
|
517
|
+
this.#fail(listing, "server repeated a cursor");
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
collecting.cursors.add(cursor);
|
|
521
|
+
this.#seq += 1;
|
|
522
|
+
const pid = `mcplock:${this.#tag}:${this.#seq}`;
|
|
523
|
+
const pkey = idKey(pid);
|
|
524
|
+
this.#pages.set(pkey, { value: listing, at: this.#now() });
|
|
525
|
+
try {
|
|
526
|
+
await this.#inner.send({ jsonrpc: "2.0", id: pid, method: "tools/list", params: { cursor } });
|
|
527
|
+
}
|
|
528
|
+
catch (exc) {
|
|
529
|
+
this.#pages.delete(pkey);
|
|
530
|
+
this.#fail(listing, `page request failed: ${exc.message}`);
|
|
531
|
+
}
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
await this.#finish(listing, collecting);
|
|
535
|
+
}
|
|
536
|
+
async #finish(listing, collecting) {
|
|
537
|
+
const tools = collecting.tools;
|
|
538
|
+
const snapshot = await this.#snapshot();
|
|
539
|
+
if (this.#current !== listing)
|
|
540
|
+
return; // abandoned or failed while the snapshot loaded
|
|
541
|
+
const decision = checkListing(snapshot.lock, this.#identity, { tools, instructions: this.#served }, this.#posture);
|
|
542
|
+
this.#current = null;
|
|
543
|
+
this.gate.record(decision, snapshot);
|
|
544
|
+
this.#lastTools = tools;
|
|
545
|
+
this.#listingDue = false;
|
|
546
|
+
emit(this.#sink, listingEvent(this.#events, decision, snapshot.snapshotId));
|
|
547
|
+
const result = copyWithout(collecting.first, ["tools", "nextCursor"]);
|
|
548
|
+
result.tools = decision.shownIndexes.map((i) => {
|
|
549
|
+
const tool = tools[i];
|
|
550
|
+
return decision.stripMeta.has(i) && isObj(tool) ? copyWithout(tool, ["_meta"]) : tool;
|
|
551
|
+
});
|
|
552
|
+
this.#deliver({ jsonrpc: "2.0", id: listing.clientId, result });
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
/** Wrap `transport` in lock mode and connect `client` through it. */
|
|
556
|
+
export async function lockClient(client, transport, options) {
|
|
557
|
+
const locked = new LockedTransport(transport, options);
|
|
558
|
+
await client.connect(locked);
|
|
559
|
+
return locked;
|
|
560
|
+
}
|
|
561
|
+
//# sourceMappingURL=rawList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rawList.js","sourceRoot":"","sources":["../../../src/lock/rawList.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manifest signature verification (section 8.2).
|
|
3
|
+
*
|
|
4
|
+
* The signer identity and the trust root come from the host's own config
|
|
5
|
+
* object. Nothing here reads the lock repository or the environment for
|
|
6
|
+
* either. `sigstore` is an optional peer dependency, loaded on the verify
|
|
7
|
+
* path only; when it is missing, verify returns false and the reader fails
|
|
8
|
+
* with lock-signature-invalid, as it does for a missing or bad bundle.
|
|
9
|
+
*
|
|
10
|
+
* Verification is offline against a trusted_root.json the operator supplies.
|
|
11
|
+
* The issuer and SAN are matched exactly: sigstore treats the SAN policy as a
|
|
12
|
+
* regular expression, so it gets an escaped, anchored pattern, and the signer
|
|
13
|
+
* it returns is compared again by plain string equality.
|
|
14
|
+
*/
|
|
15
|
+
import type { ManifestVerifier } from "./lock.js";
|
|
16
|
+
export type { ManifestVerifier, SignerIdentity } from "./lock.js";
|
|
17
|
+
export interface SigstoreVerifierOptions {
|
|
18
|
+
/** Path to a Sigstore trusted_root.json, from host configuration. */
|
|
19
|
+
readonly trustedRootPath: string;
|
|
20
|
+
/** Transparency log entries required (sigstore default 1). */
|
|
21
|
+
readonly tlogThreshold?: number;
|
|
22
|
+
/** Certificate transparency entries required (sigstore default 1). */
|
|
23
|
+
readonly ctlogThreshold?: number;
|
|
24
|
+
/** Module loader, for tests. Defaults to resolving `sigstore` from this package. */
|
|
25
|
+
readonly load?: (name: string) => unknown;
|
|
26
|
+
}
|
|
27
|
+
/** Exact, anchored pattern for sigstore's regex-based SAN policy. */
|
|
28
|
+
export declare function anchoredPattern(text: string): string;
|
|
29
|
+
/**
|
|
30
|
+
* Sigstore verifier for MANIFEST.json. Returns false (never throws) on a
|
|
31
|
+
* missing module, unreadable trust root, malformed bundle, failed signature,
|
|
32
|
+
* or a signer that differs from the configured issuer and SAN.
|
|
33
|
+
*/
|
|
34
|
+
export declare function sigstoreVerifier(options: SigstoreVerifierOptions): ManifestVerifier;
|
|
35
|
+
//# sourceMappingURL=signing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signing.d.ts","sourceRoot":"","sources":["../../../src/lock/signing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,KAAK,EAAE,gBAAgB,EAAkB,MAAM,WAAW,CAAC;AAElE,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAElE,MAAM,WAAW,uBAAuB;IACtC,qEAAqE;IACrE,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,8DAA8D;IAC9D,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,sEAAsE;IACtE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,oFAAoF;IACpF,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;CAC3C;AAMD,qEAAqE;AACrE,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AA2CD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,gBAAgB,CA2BnF"}
|