@orkestrel/mcp 0.0.9 → 0.0.11

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.
@@ -1288,10 +1288,20 @@ export declare interface MCPDiscoverResult {
1288
1288
  readonly _meta?: Readonly<Record<string, unknown>>;
1289
1289
  }
1290
1290
 
1291
- /** Per-request execution options every dispatched handler receives. */
1291
+ /**
1292
+ * Per-request execution options every dispatched handler receives.
1293
+ *
1294
+ * @remarks
1295
+ * `caller` is consumer-ASSERTED and NEVER VERIFIED. Sessions mint transport identity, not
1296
+ * caller identity, and nothing in MCP authenticates this value. This package carries it
1297
+ * opaquely without inspecting, validating, or serializing it. A consumer must narrow it with
1298
+ * its own total guard and treat absence as unauthenticated.
1299
+ */
1292
1300
  export declare interface MCPDispatchOptions {
1293
1301
  /** Aborts when the bound transport can observe that the caller's request has ended. */
1294
1302
  readonly signal?: AbortSignal;
1303
+ /** Consumer-asserted caller context, forwarded opaquely and never protocol-verified. */
1304
+ readonly caller?: unknown;
1295
1305
  }
1296
1306
 
1297
1307
  /** One consumer-requested form elicitation, before MCP assigns its map key and signs state. */
@@ -1437,7 +1447,8 @@ export declare interface MCPListResult {
1437
1447
  * @remarks
1438
1448
  * `undefined` answers nothing (the notification arm); an {@link MCPStream} holds the
1439
1449
  * request open. `options.signal` aborts when the caller's request ends — what a handler
1440
- * does with it is the handler's decision, never this package's.
1450
+ * does with it is the handler's decision, never this package's. `options.caller` is
1451
+ * consumer-asserted and never verified by this package.
1441
1452
  *
1442
1453
  * @param request - The parsed modern request being dispatched
1443
1454
  * @param options - The per-request execution options (see {@link MCPDispatchOptions})
@@ -1503,8 +1514,14 @@ export declare interface MCPMethodManagerInterface {
1503
1514
  method(name: string): MCPMethodHandler | undefined;
1504
1515
  }
1505
1516
 
1506
- /** Derive the deployment-authenticated principal bound into signed request state. */
1507
- export declare type MCPPrincipalHandler = (request: JSONRPCRequest) => string | Promise<string>;
1517
+ /**
1518
+ * Derive the deployment-authenticated principal bound into signed request state.
1519
+ *
1520
+ * @param request - The parsed `tools/call` request
1521
+ * @param options - The per-request execution options
1522
+ * @returns The authenticated principal to bind into protected state
1523
+ */
1524
+ export declare type MCPPrincipalHandler = (request: JSONRPCRequest, options: MCPDispatchOptions) => string | Promise<string>;
1508
1525
 
1509
1526
  /**
1510
1527
  * The validated per-request context projected from a modern request's reserved
@@ -1288,10 +1288,20 @@ export declare interface MCPDiscoverResult {
1288
1288
  readonly _meta?: Readonly<Record<string, unknown>>;
1289
1289
  }
1290
1290
 
1291
- /** Per-request execution options every dispatched handler receives. */
1291
+ /**
1292
+ * Per-request execution options every dispatched handler receives.
1293
+ *
1294
+ * @remarks
1295
+ * `caller` is consumer-ASSERTED and NEVER VERIFIED. Sessions mint transport identity, not
1296
+ * caller identity, and nothing in MCP authenticates this value. This package carries it
1297
+ * opaquely without inspecting, validating, or serializing it. A consumer must narrow it with
1298
+ * its own total guard and treat absence as unauthenticated.
1299
+ */
1292
1300
  export declare interface MCPDispatchOptions {
1293
1301
  /** Aborts when the bound transport can observe that the caller's request has ended. */
1294
1302
  readonly signal?: AbortSignal;
1303
+ /** Consumer-asserted caller context, forwarded opaquely and never protocol-verified. */
1304
+ readonly caller?: unknown;
1295
1305
  }
1296
1306
 
1297
1307
  /** One consumer-requested form elicitation, before MCP assigns its map key and signs state. */
@@ -1437,7 +1447,8 @@ export declare interface MCPListResult {
1437
1447
  * @remarks
1438
1448
  * `undefined` answers nothing (the notification arm); an {@link MCPStream} holds the
1439
1449
  * request open. `options.signal` aborts when the caller's request ends — what a handler
1440
- * does with it is the handler's decision, never this package's.
1450
+ * does with it is the handler's decision, never this package's. `options.caller` is
1451
+ * consumer-asserted and never verified by this package.
1441
1452
  *
1442
1453
  * @param request - The parsed modern request being dispatched
1443
1454
  * @param options - The per-request execution options (see {@link MCPDispatchOptions})
@@ -1503,8 +1514,14 @@ export declare interface MCPMethodManagerInterface {
1503
1514
  method(name: string): MCPMethodHandler | undefined;
1504
1515
  }
1505
1516
 
1506
- /** Derive the deployment-authenticated principal bound into signed request state. */
1507
- export declare type MCPPrincipalHandler = (request: JSONRPCRequest) => string | Promise<string>;
1517
+ /**
1518
+ * Derive the deployment-authenticated principal bound into signed request state.
1519
+ *
1520
+ * @param request - The parsed `tools/call` request
1521
+ * @param options - The per-request execution options
1522
+ * @returns The authenticated principal to bind into protected state
1523
+ */
1524
+ export declare type MCPPrincipalHandler = (request: JSONRPCRequest, options: MCPDispatchOptions) => string | Promise<string>;
1508
1525
 
1509
1526
  /**
1510
1527
  * The validated per-request context projected from a modern request's reserved
@@ -1382,7 +1382,7 @@ var MCPServer = class {
1382
1382
  keys: this.#limits.keys,
1383
1383
  depth: this.#limits.depth
1384
1384
  })) return buildJSONRPCError(id, JSONRPC_INVALID_PARAMS, "Invalid params: `_meta` exceeds the configured limit or contains an unsafe value");
1385
- return modern ? this.#modern(request, id, options) : this.#legacy(request, id);
1385
+ return modern ? this.#modern(request, id, options) : this.#legacy(request, id, options);
1386
1386
  }
1387
1387
  async handle(message, options) {
1388
1388
  if (!isBoundedString(message, this.#limits.message)) return JSON.stringify(buildJSONRPCError(null, JSONRPC_PARSE_ERROR, "Parse error"));
@@ -1398,7 +1398,7 @@ var MCPServer = class {
1398
1398
  if (answer === void 0) return void 0;
1399
1399
  return Symbol.asyncIterator in answer ? serializeStream(answer) : JSON.stringify(answer);
1400
1400
  }
1401
- async #legacy(request, id) {
1401
+ async #legacy(request, id, options) {
1402
1402
  switch (request.method) {
1403
1403
  case "initialize": {
1404
1404
  const requested = request.params?.["protocolVersion"];
@@ -1407,7 +1407,7 @@ var MCPServer = class {
1407
1407
  case "ping": return buildJSONRPCResult(id, {});
1408
1408
  case "tools/list": return buildJSONRPCResult(id, { tools: buildToolDescriptors(this.#options.tools) });
1409
1409
  case "tools/call": {
1410
- const result = await this.#runTool(request, id);
1410
+ const result = await this.#runTool(request, id, options);
1411
1411
  return "jsonrpc" in result ? result : buildJSONRPCResult(id, result);
1412
1412
  }
1413
1413
  default: return buildJSONRPCError(id, JSONRPC_METHOD_NOT_FOUND, `Method not found: ${request.method}`);
@@ -1440,7 +1440,7 @@ var MCPServer = class {
1440
1440
  const id = request.id ?? null;
1441
1441
  const input = await this.#input(request, options);
1442
1442
  if (input !== void 0) return input;
1443
- const result = await this.#runTool(request, id);
1443
+ const result = await this.#runTool(request, id, options);
1444
1444
  return "jsonrpc" in result ? result : buildJSONRPCResult(id, buildModernResult(result, this.#options.identity));
1445
1445
  }
1446
1446
  async #input(request, options) {
@@ -1462,12 +1462,12 @@ var MCPServer = class {
1462
1462
  arguments: args
1463
1463
  }, options);
1464
1464
  if (elicitation === void 0) return void 0;
1465
- const principal = await configured.principal(request);
1465
+ const principal = await configured.principal(request, options);
1466
1466
  return this.#required(request, name, elicitation, principal);
1467
1467
  }
1468
1468
  if (!isBoundedString(requestState, this.#limits.state) || !isRecord(inputResponses)) return buildJSONRPCError(id, JSONRPC_INVALID_PARAMS, "Invalid params: `inputResponses` and `requestState` are required together");
1469
1469
  const state = parseMCPInputState(await verifyToken(requestState, configured.secret));
1470
- const principal = await configured.principal(request);
1470
+ const principal = await configured.principal(request, options);
1471
1471
  if (state === void 0 || state.principal !== principal || state.ttl !== configured.ttl || state.origin === id || state.name !== name || !Object.hasOwn(inputResponses, state.key)) return buildJSONRPCError(id, JSONRPC_INVALID_PARAMS, "Invalid params: request state could not be verified for this retry");
1472
1472
  const response = inputResponses[state.key];
1473
1473
  if (!isElicitResult(response)) return buildJSONRPCError(id, JSONRPC_INVALID_PARAMS, "Invalid params: the elicitation response is missing or malformed");
@@ -1542,7 +1542,7 @@ var MCPServer = class {
1542
1542
  this.#subscriptions -= 1;
1543
1543
  }
1544
1544
  }
1545
- async #runTool(request, id) {
1545
+ async #runTool(request, id, options) {
1546
1546
  const params = request.params;
1547
1547
  const name = params?.["name"];
1548
1548
  if (!isString(name)) return buildJSONRPCError(id, JSONRPC_INVALID_PARAMS, "Invalid params: a string `name` is required");
@@ -1552,7 +1552,8 @@ var MCPServer = class {
1552
1552
  const result = await this.#options.tools.execute({
1553
1553
  id: callId,
1554
1554
  name,
1555
- arguments: args
1555
+ arguments: args,
1556
+ ...options.caller === void 0 ? {} : { caller: options.caller }
1556
1557
  });
1557
1558
  if (!result.success && !isBoundedString(result.error, this.#limits.content)) return buildJSONRPCError(id, JSONRPC_SERVER_ERROR, "Server limit exceeded: tool content is too large");
1558
1559
  if (result.success && result.value !== void 0 && !isBoundedJSON(result.value, {