@orkestrel/mcp 0.0.21 → 0.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/core/index.d.cts +5 -0
- package/dist/src/core/index.d.ts +5 -0
- package/dist/src/server/index.cjs +97 -9
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +91 -7
- package/dist/src/server/index.d.ts +91 -7
- package/dist/src/server/index.js +96 -10
- package/dist/src/server/index.js.map +1 -1
- package/package.json +17 -15
|
@@ -336,10 +336,14 @@ export declare function createReadableStream<T>(pull: (controller: ReadableStrea
|
|
|
336
336
|
* inherits it. Each JSON-RPC message the client `send`s is written as one
|
|
337
337
|
* newline-terminated line to the child's `stdin`; each decoded reply line from the
|
|
338
338
|
* child's `stdout` is surfaced on the transport's `message` event for the client's
|
|
339
|
-
* id correlation.
|
|
339
|
+
* id correlation. That write is bounded: a child that stays alive without ever reading
|
|
340
|
+
* its `stdin` fills the pipe, and `options.delivery` is how long the unconfirmed write
|
|
341
|
+
* waits before the `send` rejects. An omitted `delivery` selects {@link
|
|
342
|
+
* import('./constants.js').DEFAULT_MCP_DELIVERY}; an explicit `0` removes the bound.
|
|
340
343
|
*
|
|
341
344
|
* @param options - `command` (the executable to spawn; REQUIRED), optional `args`,
|
|
342
|
-
* and optional `
|
|
345
|
+
* optional `env`, and an optional `delivery` bound in milliseconds on an unconfirmed
|
|
346
|
+
* `stdin` write; see {@link StdioClientTransportOptions}
|
|
343
347
|
* @returns A working {@link StdioClientTransportInterface} over a child process's stdio,
|
|
344
348
|
* whose `evidence` carries the supervised child's bounded stderr tail
|
|
345
349
|
*
|
|
@@ -498,6 +502,19 @@ export declare function createWebSocketServer(mcp: MCPDispatcherInterface, optio
|
|
|
498
502
|
*/
|
|
499
503
|
export declare function decodeEvent(data: string): JSONRPCMessage | undefined;
|
|
500
504
|
|
|
505
|
+
/**
|
|
506
|
+
* The default bound in milliseconds on one unconfirmed write to a stdio client transport's
|
|
507
|
+
* child `stdin` — the `delivery` a `createStdioClientTransport` caller who supplies none gets.
|
|
508
|
+
*
|
|
509
|
+
* @remarks
|
|
510
|
+
* Ten seconds. The load-bearing property is the ordering, not the magnitude: this bound stays
|
|
511
|
+
* BELOW {@link import('@orkestrel/mcp').DEFAULT_MCP_REQUEST_TIMEOUT}, so a write the child never
|
|
512
|
+
* reads fails as an undeliverable message while the request that carried it is still open,
|
|
513
|
+
* rather than being masked by that request's own deadline expiring first. Override per
|
|
514
|
+
* transport with `delivery`; an explicit `0` there removes the bound.
|
|
515
|
+
*/
|
|
516
|
+
export declare const DEFAULT_MCP_DELIVERY = 10000;
|
|
517
|
+
|
|
501
518
|
/**
|
|
502
519
|
* The default interval in milliseconds between SSE keepalive comments on held-open MCP
|
|
503
520
|
* responses.
|
|
@@ -1262,9 +1279,10 @@ export declare const SSE_KEEPALIVE_COMMENT = "keepalive";
|
|
|
1262
1279
|
* - **Outbound (`send`).** `send(message)` writes one newline-terminated `JSON.stringify`d line
|
|
1263
1280
|
* through the supervisor's `send` and AWAITS its answer, so this promise settles only after the
|
|
1264
1281
|
* host reports the line handled rather than the moment the write is queued. The supervisor never
|
|
1265
|
-
* rejects — it answers `false` for a channel that was closed, destroyed, or ended,
|
|
1266
|
-
* that failed
|
|
1267
|
-
*
|
|
1282
|
+
* rejects — it answers `false` for a channel that was closed, destroyed, or ended, for a write
|
|
1283
|
+
* that failed, or for one that remained unconfirmed through `delivery`. A call made without a
|
|
1284
|
+
* live child rejects as not connected; a `false` answer from a live child rejects as unable to
|
|
1285
|
+
* deliver. The supervisor does not disclose which cause produced that answer.
|
|
1268
1286
|
* - **`close()`** runs the supervisor's bounded termination and teardown, then fires `close` once
|
|
1269
1287
|
* (idempotent). That teardown reaches the child's TERMINAL MOMENT, where the supervisor freezes
|
|
1270
1288
|
* `evidence`, ends `lines`, and settles `exit` together, so this transport needs no release of
|
|
@@ -1307,6 +1325,16 @@ export declare class StdioClientTransport implements StdioClientTransportInterfa
|
|
|
1307
1325
|
get duplex(): boolean;
|
|
1308
1326
|
get evidence(): string | undefined;
|
|
1309
1327
|
start(): Promise<void>;
|
|
1328
|
+
/**
|
|
1329
|
+
* Sends one newline-delimited JSON-RPC message to the live child.
|
|
1330
|
+
*
|
|
1331
|
+
* @param message - The message to write to the child's `stdin`
|
|
1332
|
+
* @returns Resolves when the supervisor confirms the write
|
|
1333
|
+
* @throws Thrown with `stdio transport is not connected` when no live child is available before
|
|
1334
|
+
* the write
|
|
1335
|
+
* @throws Thrown with `stdio transport could not deliver the message` when a live child's write
|
|
1336
|
+
* resolves `false`
|
|
1337
|
+
*/
|
|
1310
1338
|
send(message: JSONRPCMessage_2): Promise<void>;
|
|
1311
1339
|
close(): Promise<void>;
|
|
1312
1340
|
}
|
|
@@ -1391,11 +1419,34 @@ export declare interface StdioClientTransportInterface extends MCPClientTranspor
|
|
|
1391
1419
|
* OMITTED the child inherits the full `process.env`, when PROVIDED each named key overrides
|
|
1392
1420
|
* the inherited value while every unlisted key is still inherited. This transport cannot
|
|
1393
1421
|
* REPLACE the inherited environment entirely — the supervisor always merges over the parent.
|
|
1422
|
+
* - `delivery` — the bound in milliseconds on one unconfirmed write to the child's `stdin`;
|
|
1423
|
+
* an explicit `0` opts out. Defaults to {@link import('./constants.js').DEFAULT_MCP_DELIVERY}.
|
|
1394
1424
|
*/
|
|
1395
1425
|
export declare interface StdioClientTransportOptions {
|
|
1396
1426
|
readonly command: string;
|
|
1397
1427
|
readonly args?: readonly string[];
|
|
1398
1428
|
readonly env?: Readonly<Record<string, string>>;
|
|
1429
|
+
/**
|
|
1430
|
+
* Bounds the wait on one unconfirmed `send` write to the child's `stdin`, in milliseconds.
|
|
1431
|
+
*
|
|
1432
|
+
* @remarks
|
|
1433
|
+
* A full pipe is the case this bounds: a live child that never reads its `stdin` leaves the
|
|
1434
|
+
* kernel unable to confirm the write, and the supervisor holds that write open. When the
|
|
1435
|
+
* window elapses the supervisor answers that write `false`, which this transport surfaces as
|
|
1436
|
+
* a rejection, so the caller learns the message did not land instead of waiting on a peer
|
|
1437
|
+
* that will never read it. Default: {@link import('./constants.js').DEFAULT_MCP_DELIVERY}.
|
|
1438
|
+
*
|
|
1439
|
+
* An explicit `0` opts out: the bound is off, and an unconfirmed write stays pending until
|
|
1440
|
+
* the channel faults or teardown settles it. Omission does NOT opt out here, which is where
|
|
1441
|
+
* this option diverges from the supervisor's own `delivery` on {@link
|
|
1442
|
+
* import('@orkestrel/process').ProcessOptions} — omitted THERE disables the bound, omitted
|
|
1443
|
+
* HERE selects the default.
|
|
1444
|
+
*
|
|
1445
|
+
* An out-of-range value surfaces at `start()` rather than at construction. This transport
|
|
1446
|
+
* forwards the value verbatim and adds no validator of its own, so the supervisor's own timer
|
|
1447
|
+
* range is what rejects it, at the moment it spawns the child.
|
|
1448
|
+
*/
|
|
1449
|
+
readonly delivery?: number;
|
|
1399
1450
|
}
|
|
1400
1451
|
|
|
1401
1452
|
/**
|
|
@@ -1433,8 +1484,10 @@ export declare interface StdioServerOptions {
|
|
|
1433
1484
|
* emits `error` (never throws). `input`'s `close` bridges to this
|
|
1434
1485
|
* transport's `close`.
|
|
1435
1486
|
* - **Outbound (`send`).** `send(message)` writes one newline-terminated
|
|
1436
|
-
* `JSON.stringify`d line to `output
|
|
1437
|
-
*
|
|
1487
|
+
* `JSON.stringify`d line to `output` and awaits the writable completion callback. The
|
|
1488
|
+
* callback is the backpressure boundary and its error rejects the send.
|
|
1489
|
+
* - **`close()`** removes this transport's input and output subscriptions, rejects every
|
|
1490
|
+
* pending send, and fires its `close`
|
|
1438
1491
|
* event (idempotent). It pauses the input only when the caller was not already reading
|
|
1439
1492
|
* it at `start` (`readableFlowing !== true`) AND no `data` listener remains once this
|
|
1440
1493
|
* transport's own is removed — so a process holding `process.stdin` can exit, and a
|
|
@@ -1457,6 +1510,19 @@ export declare class StdioServerTransport implements MCPClientTransportInterface
|
|
|
1457
1510
|
get session(): string | undefined;
|
|
1458
1511
|
get duplex(): boolean;
|
|
1459
1512
|
start(): Promise<void>;
|
|
1513
|
+
/**
|
|
1514
|
+
* Sends one newline-delimited JSON-RPC message through the caller-owned output stream.
|
|
1515
|
+
*
|
|
1516
|
+
* @remarks
|
|
1517
|
+
* The writable completion callback is the backpressure boundary. This method awaits that
|
|
1518
|
+
* callback rather than adding a `drain` listener. Closing the transport rejects every send
|
|
1519
|
+
* whose callback has not settled.
|
|
1520
|
+
*
|
|
1521
|
+
* @param message - The message to serialize and write
|
|
1522
|
+
* @returns Resolves when the output confirms the write
|
|
1523
|
+
* @throws Thrown with `stdio transport is not connected` after the transport closes
|
|
1524
|
+
* @throws Thrown with the output callback error or synchronous write failure
|
|
1525
|
+
*/
|
|
1460
1526
|
send(message: JSONRPCMessage_2): Promise<void>;
|
|
1461
1527
|
close(): Promise<void>;
|
|
1462
1528
|
}
|
|
@@ -1633,4 +1699,22 @@ export declare class WebSocketServerTransport implements MCPClientTransportInter
|
|
|
1633
1699
|
close(): Promise<void>;
|
|
1634
1700
|
}
|
|
1635
1701
|
|
|
1702
|
+
/**
|
|
1703
|
+
* Writes one line to a Node writable stream and waits for its completion callback.
|
|
1704
|
+
*
|
|
1705
|
+
* @remarks
|
|
1706
|
+
* The completion callback is the writable channel's backpressure boundary. A callback error and
|
|
1707
|
+
* a synchronous `write` throw reject the returned promise with the original value.
|
|
1708
|
+
*
|
|
1709
|
+
* @param output - The writable stream that receives the line
|
|
1710
|
+
* @param line - The complete line to write
|
|
1711
|
+
* @returns Resolves when the stream confirms the write; rejects when the write fails
|
|
1712
|
+
*
|
|
1713
|
+
* @example
|
|
1714
|
+
* ```ts
|
|
1715
|
+
* await writeLine(process.stdout, '{"jsonrpc":"2.0","method":"ping"}\n')
|
|
1716
|
+
* ```
|
|
1717
|
+
*/
|
|
1718
|
+
export declare function writeLine(output: NodeJS.WritableStream, line: string): Promise<void>;
|
|
1719
|
+
|
|
1636
1720
|
export { }
|
|
@@ -336,10 +336,14 @@ export declare function createReadableStream<T>(pull: (controller: ReadableStrea
|
|
|
336
336
|
* inherits it. Each JSON-RPC message the client `send`s is written as one
|
|
337
337
|
* newline-terminated line to the child's `stdin`; each decoded reply line from the
|
|
338
338
|
* child's `stdout` is surfaced on the transport's `message` event for the client's
|
|
339
|
-
* id correlation.
|
|
339
|
+
* id correlation. That write is bounded: a child that stays alive without ever reading
|
|
340
|
+
* its `stdin` fills the pipe, and `options.delivery` is how long the unconfirmed write
|
|
341
|
+
* waits before the `send` rejects. An omitted `delivery` selects {@link
|
|
342
|
+
* import('./constants.js').DEFAULT_MCP_DELIVERY}; an explicit `0` removes the bound.
|
|
340
343
|
*
|
|
341
344
|
* @param options - `command` (the executable to spawn; REQUIRED), optional `args`,
|
|
342
|
-
* and optional `
|
|
345
|
+
* optional `env`, and an optional `delivery` bound in milliseconds on an unconfirmed
|
|
346
|
+
* `stdin` write; see {@link StdioClientTransportOptions}
|
|
343
347
|
* @returns A working {@link StdioClientTransportInterface} over a child process's stdio,
|
|
344
348
|
* whose `evidence` carries the supervised child's bounded stderr tail
|
|
345
349
|
*
|
|
@@ -498,6 +502,19 @@ export declare function createWebSocketServer(mcp: MCPDispatcherInterface, optio
|
|
|
498
502
|
*/
|
|
499
503
|
export declare function decodeEvent(data: string): JSONRPCMessage | undefined;
|
|
500
504
|
|
|
505
|
+
/**
|
|
506
|
+
* The default bound in milliseconds on one unconfirmed write to a stdio client transport's
|
|
507
|
+
* child `stdin` — the `delivery` a `createStdioClientTransport` caller who supplies none gets.
|
|
508
|
+
*
|
|
509
|
+
* @remarks
|
|
510
|
+
* Ten seconds. The load-bearing property is the ordering, not the magnitude: this bound stays
|
|
511
|
+
* BELOW {@link import('@orkestrel/mcp').DEFAULT_MCP_REQUEST_TIMEOUT}, so a write the child never
|
|
512
|
+
* reads fails as an undeliverable message while the request that carried it is still open,
|
|
513
|
+
* rather than being masked by that request's own deadline expiring first. Override per
|
|
514
|
+
* transport with `delivery`; an explicit `0` there removes the bound.
|
|
515
|
+
*/
|
|
516
|
+
export declare const DEFAULT_MCP_DELIVERY = 10000;
|
|
517
|
+
|
|
501
518
|
/**
|
|
502
519
|
* The default interval in milliseconds between SSE keepalive comments on held-open MCP
|
|
503
520
|
* responses.
|
|
@@ -1262,9 +1279,10 @@ export declare const SSE_KEEPALIVE_COMMENT = "keepalive";
|
|
|
1262
1279
|
* - **Outbound (`send`).** `send(message)` writes one newline-terminated `JSON.stringify`d line
|
|
1263
1280
|
* through the supervisor's `send` and AWAITS its answer, so this promise settles only after the
|
|
1264
1281
|
* host reports the line handled rather than the moment the write is queued. The supervisor never
|
|
1265
|
-
* rejects — it answers `false` for a channel that was closed, destroyed, or ended,
|
|
1266
|
-
* that failed
|
|
1267
|
-
*
|
|
1282
|
+
* rejects — it answers `false` for a channel that was closed, destroyed, or ended, for a write
|
|
1283
|
+
* that failed, or for one that remained unconfirmed through `delivery`. A call made without a
|
|
1284
|
+
* live child rejects as not connected; a `false` answer from a live child rejects as unable to
|
|
1285
|
+
* deliver. The supervisor does not disclose which cause produced that answer.
|
|
1268
1286
|
* - **`close()`** runs the supervisor's bounded termination and teardown, then fires `close` once
|
|
1269
1287
|
* (idempotent). That teardown reaches the child's TERMINAL MOMENT, where the supervisor freezes
|
|
1270
1288
|
* `evidence`, ends `lines`, and settles `exit` together, so this transport needs no release of
|
|
@@ -1307,6 +1325,16 @@ export declare class StdioClientTransport implements StdioClientTransportInterfa
|
|
|
1307
1325
|
get duplex(): boolean;
|
|
1308
1326
|
get evidence(): string | undefined;
|
|
1309
1327
|
start(): Promise<void>;
|
|
1328
|
+
/**
|
|
1329
|
+
* Sends one newline-delimited JSON-RPC message to the live child.
|
|
1330
|
+
*
|
|
1331
|
+
* @param message - The message to write to the child's `stdin`
|
|
1332
|
+
* @returns Resolves when the supervisor confirms the write
|
|
1333
|
+
* @throws Thrown with `stdio transport is not connected` when no live child is available before
|
|
1334
|
+
* the write
|
|
1335
|
+
* @throws Thrown with `stdio transport could not deliver the message` when a live child's write
|
|
1336
|
+
* resolves `false`
|
|
1337
|
+
*/
|
|
1310
1338
|
send(message: JSONRPCMessage_2): Promise<void>;
|
|
1311
1339
|
close(): Promise<void>;
|
|
1312
1340
|
}
|
|
@@ -1391,11 +1419,34 @@ export declare interface StdioClientTransportInterface extends MCPClientTranspor
|
|
|
1391
1419
|
* OMITTED the child inherits the full `process.env`, when PROVIDED each named key overrides
|
|
1392
1420
|
* the inherited value while every unlisted key is still inherited. This transport cannot
|
|
1393
1421
|
* REPLACE the inherited environment entirely — the supervisor always merges over the parent.
|
|
1422
|
+
* - `delivery` — the bound in milliseconds on one unconfirmed write to the child's `stdin`;
|
|
1423
|
+
* an explicit `0` opts out. Defaults to {@link import('./constants.js').DEFAULT_MCP_DELIVERY}.
|
|
1394
1424
|
*/
|
|
1395
1425
|
export declare interface StdioClientTransportOptions {
|
|
1396
1426
|
readonly command: string;
|
|
1397
1427
|
readonly args?: readonly string[];
|
|
1398
1428
|
readonly env?: Readonly<Record<string, string>>;
|
|
1429
|
+
/**
|
|
1430
|
+
* Bounds the wait on one unconfirmed `send` write to the child's `stdin`, in milliseconds.
|
|
1431
|
+
*
|
|
1432
|
+
* @remarks
|
|
1433
|
+
* A full pipe is the case this bounds: a live child that never reads its `stdin` leaves the
|
|
1434
|
+
* kernel unable to confirm the write, and the supervisor holds that write open. When the
|
|
1435
|
+
* window elapses the supervisor answers that write `false`, which this transport surfaces as
|
|
1436
|
+
* a rejection, so the caller learns the message did not land instead of waiting on a peer
|
|
1437
|
+
* that will never read it. Default: {@link import('./constants.js').DEFAULT_MCP_DELIVERY}.
|
|
1438
|
+
*
|
|
1439
|
+
* An explicit `0` opts out: the bound is off, and an unconfirmed write stays pending until
|
|
1440
|
+
* the channel faults or teardown settles it. Omission does NOT opt out here, which is where
|
|
1441
|
+
* this option diverges from the supervisor's own `delivery` on {@link
|
|
1442
|
+
* import('@orkestrel/process').ProcessOptions} — omitted THERE disables the bound, omitted
|
|
1443
|
+
* HERE selects the default.
|
|
1444
|
+
*
|
|
1445
|
+
* An out-of-range value surfaces at `start()` rather than at construction. This transport
|
|
1446
|
+
* forwards the value verbatim and adds no validator of its own, so the supervisor's own timer
|
|
1447
|
+
* range is what rejects it, at the moment it spawns the child.
|
|
1448
|
+
*/
|
|
1449
|
+
readonly delivery?: number;
|
|
1399
1450
|
}
|
|
1400
1451
|
|
|
1401
1452
|
/**
|
|
@@ -1433,8 +1484,10 @@ export declare interface StdioServerOptions {
|
|
|
1433
1484
|
* emits `error` (never throws). `input`'s `close` bridges to this
|
|
1434
1485
|
* transport's `close`.
|
|
1435
1486
|
* - **Outbound (`send`).** `send(message)` writes one newline-terminated
|
|
1436
|
-
* `JSON.stringify`d line to `output
|
|
1437
|
-
*
|
|
1487
|
+
* `JSON.stringify`d line to `output` and awaits the writable completion callback. The
|
|
1488
|
+
* callback is the backpressure boundary and its error rejects the send.
|
|
1489
|
+
* - **`close()`** removes this transport's input and output subscriptions, rejects every
|
|
1490
|
+
* pending send, and fires its `close`
|
|
1438
1491
|
* event (idempotent). It pauses the input only when the caller was not already reading
|
|
1439
1492
|
* it at `start` (`readableFlowing !== true`) AND no `data` listener remains once this
|
|
1440
1493
|
* transport's own is removed — so a process holding `process.stdin` can exit, and a
|
|
@@ -1457,6 +1510,19 @@ export declare class StdioServerTransport implements MCPClientTransportInterface
|
|
|
1457
1510
|
get session(): string | undefined;
|
|
1458
1511
|
get duplex(): boolean;
|
|
1459
1512
|
start(): Promise<void>;
|
|
1513
|
+
/**
|
|
1514
|
+
* Sends one newline-delimited JSON-RPC message through the caller-owned output stream.
|
|
1515
|
+
*
|
|
1516
|
+
* @remarks
|
|
1517
|
+
* The writable completion callback is the backpressure boundary. This method awaits that
|
|
1518
|
+
* callback rather than adding a `drain` listener. Closing the transport rejects every send
|
|
1519
|
+
* whose callback has not settled.
|
|
1520
|
+
*
|
|
1521
|
+
* @param message - The message to serialize and write
|
|
1522
|
+
* @returns Resolves when the output confirms the write
|
|
1523
|
+
* @throws Thrown with `stdio transport is not connected` after the transport closes
|
|
1524
|
+
* @throws Thrown with the output callback error or synchronous write failure
|
|
1525
|
+
*/
|
|
1460
1526
|
send(message: JSONRPCMessage_2): Promise<void>;
|
|
1461
1527
|
close(): Promise<void>;
|
|
1462
1528
|
}
|
|
@@ -1633,4 +1699,22 @@ export declare class WebSocketServerTransport implements MCPClientTransportInter
|
|
|
1633
1699
|
close(): Promise<void>;
|
|
1634
1700
|
}
|
|
1635
1701
|
|
|
1702
|
+
/**
|
|
1703
|
+
* Writes one line to a Node writable stream and waits for its completion callback.
|
|
1704
|
+
*
|
|
1705
|
+
* @remarks
|
|
1706
|
+
* The completion callback is the writable channel's backpressure boundary. A callback error and
|
|
1707
|
+
* a synchronous `write` throw reject the returned promise with the original value.
|
|
1708
|
+
*
|
|
1709
|
+
* @param output - The writable stream that receives the line
|
|
1710
|
+
* @param line - The complete line to write
|
|
1711
|
+
* @returns Resolves when the stream confirms the write; rejects when the write fails
|
|
1712
|
+
*
|
|
1713
|
+
* @example
|
|
1714
|
+
* ```ts
|
|
1715
|
+
* await writeLine(process.stdout, '{"jsonrpc":"2.0","method":"ping"}\n')
|
|
1716
|
+
* ```
|
|
1717
|
+
*/
|
|
1718
|
+
export declare function writeLine(output: NodeJS.WritableStream, line: string): Promise<void>;
|
|
1719
|
+
|
|
1636
1720
|
export { }
|
package/dist/src/server/index.js
CHANGED
|
@@ -84,6 +84,18 @@ var DEFAULT_MCP_SESSION_CAPACITY = 1024;
|
|
|
84
84
|
* this bounds the replay log paired with it.
|
|
85
85
|
*/
|
|
86
86
|
var DEFAULT_MCP_SESSION_TTL = 3e5;
|
|
87
|
+
/**
|
|
88
|
+
* The default bound in milliseconds on one unconfirmed write to a stdio client transport's
|
|
89
|
+
* child `stdin` — the `delivery` a `createStdioClientTransport` caller who supplies none gets.
|
|
90
|
+
*
|
|
91
|
+
* @remarks
|
|
92
|
+
* Ten seconds. The load-bearing property is the ordering, not the magnitude: this bound stays
|
|
93
|
+
* BELOW {@link import('@orkestrel/mcp').DEFAULT_MCP_REQUEST_TIMEOUT}, so a write the child never
|
|
94
|
+
* reads fails as an undeliverable message while the request that carried it is still open,
|
|
95
|
+
* rather than being masked by that request's own deadline expiring first. Override per
|
|
96
|
+
* transport with `delivery`; an explicit `0` there removes the bound.
|
|
97
|
+
*/
|
|
98
|
+
var DEFAULT_MCP_DELIVERY = 1e4;
|
|
87
99
|
//#endregion
|
|
88
100
|
//#region src/server/helpers.ts
|
|
89
101
|
/**
|
|
@@ -352,6 +364,34 @@ function extractLines(buffer, chunk) {
|
|
|
352
364
|
};
|
|
353
365
|
}
|
|
354
366
|
/**
|
|
367
|
+
* Writes one line to a Node writable stream and waits for its completion callback.
|
|
368
|
+
*
|
|
369
|
+
* @remarks
|
|
370
|
+
* The completion callback is the writable channel's backpressure boundary. A callback error and
|
|
371
|
+
* a synchronous `write` throw reject the returned promise with the original value.
|
|
372
|
+
*
|
|
373
|
+
* @param output - The writable stream that receives the line
|
|
374
|
+
* @param line - The complete line to write
|
|
375
|
+
* @returns Resolves when the stream confirms the write; rejects when the write fails
|
|
376
|
+
*
|
|
377
|
+
* @example
|
|
378
|
+
* ```ts
|
|
379
|
+
* await writeLine(process.stdout, '{"jsonrpc":"2.0","method":"ping"}\n')
|
|
380
|
+
* ```
|
|
381
|
+
*/
|
|
382
|
+
function writeLine(output, line) {
|
|
383
|
+
return new Promise((resolve, reject) => {
|
|
384
|
+
try {
|
|
385
|
+
output.write(line, (error) => {
|
|
386
|
+
if (error === void 0 || error === null) resolve();
|
|
387
|
+
else reject(error);
|
|
388
|
+
});
|
|
389
|
+
} catch (error) {
|
|
390
|
+
reject(error);
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
355
395
|
* Decodes and delivers each complete newline-framed line onto a {@link
|
|
356
396
|
* MCPClientTransportEventMap} emitter — the shared per-chunk dispatch step both stdio
|
|
357
397
|
* transports run their framed lines through: the server transport frames with {@link
|
|
@@ -1380,9 +1420,10 @@ var WebSocketClientTransport = class {
|
|
|
1380
1420
|
* - **Outbound (`send`).** `send(message)` writes one newline-terminated `JSON.stringify`d line
|
|
1381
1421
|
* through the supervisor's `send` and AWAITS its answer, so this promise settles only after the
|
|
1382
1422
|
* host reports the line handled rather than the moment the write is queued. The supervisor never
|
|
1383
|
-
* rejects — it answers `false` for a channel that was closed, destroyed, or ended,
|
|
1384
|
-
* that failed
|
|
1385
|
-
*
|
|
1423
|
+
* rejects — it answers `false` for a channel that was closed, destroyed, or ended, for a write
|
|
1424
|
+
* that failed, or for one that remained unconfirmed through `delivery`. A call made without a
|
|
1425
|
+
* live child rejects as not connected; a `false` answer from a live child rejects as unable to
|
|
1426
|
+
* deliver. The supervisor does not disclose which cause produced that answer.
|
|
1386
1427
|
* - **`close()`** runs the supervisor's bounded termination and teardown, then fires `close` once
|
|
1387
1428
|
* (idempotent). That teardown reaches the child's TERMINAL MOMENT, where the supervisor freezes
|
|
1388
1429
|
* `evidence`, ends `lines`, and settles `exit` together, so this transport needs no release of
|
|
@@ -1422,6 +1463,7 @@ var StdioClientTransport = class {
|
|
|
1422
1463
|
#command;
|
|
1423
1464
|
#args;
|
|
1424
1465
|
#env;
|
|
1466
|
+
#delivery;
|
|
1425
1467
|
#process = void 0;
|
|
1426
1468
|
#closing = void 0;
|
|
1427
1469
|
#closed = false;
|
|
@@ -1430,6 +1472,7 @@ var StdioClientTransport = class {
|
|
|
1430
1472
|
this.#command = options.command;
|
|
1431
1473
|
this.#args = options.args ?? [];
|
|
1432
1474
|
this.#env = options.env;
|
|
1475
|
+
this.#delivery = options.delivery ?? 1e4;
|
|
1433
1476
|
}
|
|
1434
1477
|
get emitter() {
|
|
1435
1478
|
return this.#emitter;
|
|
@@ -1461,6 +1504,7 @@ var StdioClientTransport = class {
|
|
|
1461
1504
|
},
|
|
1462
1505
|
workspace: process.cwd(),
|
|
1463
1506
|
grace: PROCESS_GRACE,
|
|
1507
|
+
delivery: this.#delivery,
|
|
1464
1508
|
writable: true
|
|
1465
1509
|
});
|
|
1466
1510
|
this.#process = child;
|
|
@@ -1468,9 +1512,20 @@ var StdioClientTransport = class {
|
|
|
1468
1512
|
child.exit.then((exit) => this.#onExit(child, exit));
|
|
1469
1513
|
this.#pump(child);
|
|
1470
1514
|
}
|
|
1515
|
+
/**
|
|
1516
|
+
* Sends one newline-delimited JSON-RPC message to the live child.
|
|
1517
|
+
*
|
|
1518
|
+
* @param message - The message to write to the child's `stdin`
|
|
1519
|
+
* @returns Resolves when the supervisor confirms the write
|
|
1520
|
+
* @throws Thrown with `stdio transport is not connected` when no live child is available before
|
|
1521
|
+
* the write
|
|
1522
|
+
* @throws Thrown with `stdio transport could not deliver the message` when a live child's write
|
|
1523
|
+
* resolves `false`
|
|
1524
|
+
*/
|
|
1471
1525
|
async send(message) {
|
|
1472
1526
|
const child = this.#closed ? void 0 : this.#process;
|
|
1473
|
-
if (
|
|
1527
|
+
if (child === void 0) throw new Error("stdio transport is not connected");
|
|
1528
|
+
if (!await child.send(JSON.stringify(message))) throw new Error("stdio transport could not deliver the message");
|
|
1474
1529
|
}
|
|
1475
1530
|
async close() {
|
|
1476
1531
|
if (this.#closed && this.#closing === void 0) return;
|
|
@@ -1531,8 +1586,10 @@ var StdioClientTransport = class {
|
|
|
1531
1586
|
* emits `error` (never throws). `input`'s `close` bridges to this
|
|
1532
1587
|
* transport's `close`.
|
|
1533
1588
|
* - **Outbound (`send`).** `send(message)` writes one newline-terminated
|
|
1534
|
-
* `JSON.stringify`d line to `output
|
|
1535
|
-
*
|
|
1589
|
+
* `JSON.stringify`d line to `output` and awaits the writable completion callback. The
|
|
1590
|
+
* callback is the backpressure boundary and its error rejects the send.
|
|
1591
|
+
* - **`close()`** removes this transport's input and output subscriptions, rejects every
|
|
1592
|
+
* pending send, and fires its `close`
|
|
1536
1593
|
* event (idempotent). It pauses the input only when the caller was not already reading
|
|
1537
1594
|
* it at `start` (`readableFlowing !== true`) AND no `data` listener remains once this
|
|
1538
1595
|
* transport's own is removed — so a process holding `process.stdin` can exit, and a
|
|
@@ -1555,6 +1612,7 @@ var StdioServerTransport = class {
|
|
|
1555
1612
|
#data = (chunk) => this.#receive(chunk.toString());
|
|
1556
1613
|
#ending = () => this.#onClose();
|
|
1557
1614
|
#failure = (error) => this.#emitter.emit("error", error);
|
|
1615
|
+
#pending = /* @__PURE__ */ new Set();
|
|
1558
1616
|
#buffer = "";
|
|
1559
1617
|
#started = false;
|
|
1560
1618
|
#closed = false;
|
|
@@ -1578,9 +1636,30 @@ var StdioServerTransport = class {
|
|
|
1578
1636
|
this.#input.on("data", this.#data);
|
|
1579
1637
|
this.#input.on("close", this.#ending);
|
|
1580
1638
|
this.#input.on("error", this.#failure);
|
|
1639
|
+
this.#output.on("error", this.#failure);
|
|
1581
1640
|
}
|
|
1641
|
+
/**
|
|
1642
|
+
* Sends one newline-delimited JSON-RPC message through the caller-owned output stream.
|
|
1643
|
+
*
|
|
1644
|
+
* @remarks
|
|
1645
|
+
* The writable completion callback is the backpressure boundary. This method awaits that
|
|
1646
|
+
* callback rather than adding a `drain` listener. Closing the transport rejects every send
|
|
1647
|
+
* whose callback has not settled.
|
|
1648
|
+
*
|
|
1649
|
+
* @param message - The message to serialize and write
|
|
1650
|
+
* @returns Resolves when the output confirms the write
|
|
1651
|
+
* @throws Thrown with `stdio transport is not connected` after the transport closes
|
|
1652
|
+
* @throws Thrown with the output callback error or synchronous write failure
|
|
1653
|
+
*/
|
|
1582
1654
|
async send(message) {
|
|
1583
|
-
this.#
|
|
1655
|
+
if (this.#closed) throw new Error("stdio transport is not connected");
|
|
1656
|
+
const pending = Promise.withResolvers();
|
|
1657
|
+
this.#pending.add(pending);
|
|
1658
|
+
try {
|
|
1659
|
+
await Promise.race([writeLine(this.#output, `${JSON.stringify(message)}\n`), pending.promise]);
|
|
1660
|
+
} finally {
|
|
1661
|
+
this.#pending.delete(pending);
|
|
1662
|
+
}
|
|
1584
1663
|
}
|
|
1585
1664
|
async close() {
|
|
1586
1665
|
if (this.#closed) return;
|
|
@@ -1603,6 +1682,9 @@ var StdioServerTransport = class {
|
|
|
1603
1682
|
this.#input.removeListener("data", this.#data);
|
|
1604
1683
|
this.#input.removeListener("close", this.#ending);
|
|
1605
1684
|
this.#input.removeListener("error", this.#failure);
|
|
1685
|
+
this.#output.removeListener("error", this.#failure);
|
|
1686
|
+
for (const pending of this.#pending) pending.reject(/* @__PURE__ */ new Error("stdio transport is not connected"));
|
|
1687
|
+
this.#pending.clear();
|
|
1606
1688
|
if (!this.#flowing && this.#input.listenerCount("data") === 0) this.#input.pause();
|
|
1607
1689
|
}
|
|
1608
1690
|
};
|
|
@@ -1864,10 +1946,14 @@ function createWebSocketClientTransport(options) {
|
|
|
1864
1946
|
* inherits it. Each JSON-RPC message the client `send`s is written as one
|
|
1865
1947
|
* newline-terminated line to the child's `stdin`; each decoded reply line from the
|
|
1866
1948
|
* child's `stdout` is surfaced on the transport's `message` event for the client's
|
|
1867
|
-
* id correlation.
|
|
1949
|
+
* id correlation. That write is bounded: a child that stays alive without ever reading
|
|
1950
|
+
* its `stdin` fills the pipe, and `options.delivery` is how long the unconfirmed write
|
|
1951
|
+
* waits before the `send` rejects. An omitted `delivery` selects {@link
|
|
1952
|
+
* import('./constants.js').DEFAULT_MCP_DELIVERY}; an explicit `0` removes the bound.
|
|
1868
1953
|
*
|
|
1869
1954
|
* @param options - `command` (the executable to spawn; REQUIRED), optional `args`,
|
|
1870
|
-
* and optional `
|
|
1955
|
+
* optional `env`, and an optional `delivery` bound in milliseconds on an unconfirmed
|
|
1956
|
+
* `stdin` write; see {@link StdioClientTransportOptions}
|
|
1871
1957
|
* @returns A working {@link StdioClientTransportInterface} over a child process's stdio,
|
|
1872
1958
|
* whose `evidence` carries the supervised child's bounded stderr tail
|
|
1873
1959
|
*
|
|
@@ -2106,6 +2192,6 @@ function createMCPSession(options) {
|
|
|
2106
2192
|
};
|
|
2107
2193
|
}
|
|
2108
2194
|
//#endregion
|
|
2109
|
-
export { DEFAULT_MCP_KEEPALIVE_INTERVAL, DEFAULT_MCP_PATH, DEFAULT_MCP_SESSION_CAPACITY, DEFAULT_MCP_SESSION_TTL, HTTPClientTransport, HTTPDisconnect, MCPSession, MCP_METHOD_HEADER, MCP_NAME_HEADER, MCP_PROTOCOL_VERSION_HEADER, MCP_SESSION_HEADER, MCP_WEBSOCKET_SUBPROTOCOL, SSE_BUFFERING_DISABLED, SSE_BUFFERING_HEADER, SSE_KEEPALIVE_COMMENT, StdioClientTransport, StdioServerTransport, WebSocketClientTransport, WebSocketServerTransport, acceptsEventStream, allowsOrigin, bridgeMessageTransport, createHTTPClientTransport, createMCPContinuation, createMCPPostHandler, createMCPRoutes, createMCPSession, createReadableStream, createStdioClientTransport, createStdioServer, createWebSocketClientTransport, createWebSocketServer, decodeEvent, dispatchLines, extractLines, inferHeaderIssue, inferLegacyVersion, inferStatus, readEventStream, readLastEventId, readSessionHeader, rejectUnknownSession, sendEventStream, upgradeRequestPath };
|
|
2195
|
+
export { DEFAULT_MCP_DELIVERY, DEFAULT_MCP_KEEPALIVE_INTERVAL, DEFAULT_MCP_PATH, DEFAULT_MCP_SESSION_CAPACITY, DEFAULT_MCP_SESSION_TTL, HTTPClientTransport, HTTPDisconnect, MCPSession, MCP_METHOD_HEADER, MCP_NAME_HEADER, MCP_PROTOCOL_VERSION_HEADER, MCP_SESSION_HEADER, MCP_WEBSOCKET_SUBPROTOCOL, SSE_BUFFERING_DISABLED, SSE_BUFFERING_HEADER, SSE_KEEPALIVE_COMMENT, StdioClientTransport, StdioServerTransport, WebSocketClientTransport, WebSocketServerTransport, acceptsEventStream, allowsOrigin, bridgeMessageTransport, createHTTPClientTransport, createMCPContinuation, createMCPPostHandler, createMCPRoutes, createMCPSession, createReadableStream, createStdioClientTransport, createStdioServer, createWebSocketClientTransport, createWebSocketServer, decodeEvent, dispatchLines, extractLines, inferHeaderIssue, inferLegacyVersion, inferStatus, readEventStream, readLastEventId, readSessionHeader, rejectUnknownSession, sendEventStream, upgradeRequestPath, writeLine };
|
|
2110
2196
|
|
|
2111
2197
|
//# sourceMappingURL=index.js.map
|