mcp-compress-router 1.5.6 → 1.6.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.
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Agent, fetch as undiciFetch } from 'undici';
|
|
2
|
+
/**
|
|
3
|
+
* Max concurrent connections per origin for the dedicated agent behind a
|
|
4
|
+
* Streamable HTTP transport. MUST be greater than one: the MCP streamable
|
|
5
|
+
* HTTP spec keeps a long-lived GET SSE stream open while POSTing
|
|
6
|
+
* messages, and a single-connection pool would deadlock — the SSE holds
|
|
7
|
+
* the only socket and every message POST queues behind it forever.
|
|
8
|
+
* Four connections cover the SSE stream plus concurrent message POSTs and
|
|
9
|
+
* the occasional session DELETE without sharing a pool with other
|
|
10
|
+
* servers.
|
|
11
|
+
*/
|
|
12
|
+
const DEDICATED_FETCH_CONNECTIONS = 4;
|
|
13
|
+
/**
|
|
14
|
+
* Idle timeout (ms) for sockets owned by a dedicated agent. Kept short so
|
|
15
|
+
* sockets from a closed transport drain within a second instead of
|
|
16
|
+
* holding the process alive at undici's default 4 s keep-alive.
|
|
17
|
+
*/
|
|
18
|
+
const DEDICATED_FETCH_KEEP_ALIVE_MS = 1_000;
|
|
19
|
+
/**
|
|
20
|
+
* Builds a fetch implementation backed by a dedicated undici `Agent`.
|
|
21
|
+
*
|
|
22
|
+
* Every `StreamableHTTPClientTransport` gets its own agent, so all of a
|
|
23
|
+
* downstream server's traffic — the SSE stream and the message POSTs —
|
|
24
|
+
* runs on connections drawn from a private pool for that transport
|
|
25
|
+
* instead of the shared default fetch pool. This isolates one server's
|
|
26
|
+
* connections from the OAuth metadata probes and from every other
|
|
27
|
+
* server: a probe or another server can never reuse a socket that
|
|
28
|
+
* belongs to this transport (and a connection-sensitive downstream or
|
|
29
|
+
* proxy never sees unrelated requests on the same TCP connection).
|
|
30
|
+
*
|
|
31
|
+
* The agent is intentionally left open-ended: it keeps per-origin
|
|
32
|
+
* keep-alive sockets that drain after {@link DEDICATED_FETCH_KEEP_ALIVE_MS}
|
|
33
|
+
* (the router force-exits on shutdown, so no explicit close is needed).
|
|
34
|
+
*
|
|
35
|
+
* @returns A fetch-compatible function for the caller's transport.
|
|
36
|
+
*/
|
|
37
|
+
export function createDedicatedFetch() {
|
|
38
|
+
const agent = new Agent({
|
|
39
|
+
connections: DEDICATED_FETCH_CONNECTIONS,
|
|
40
|
+
keepAliveTimeout: DEDICATED_FETCH_KEEP_ALIVE_MS,
|
|
41
|
+
});
|
|
42
|
+
return (url, init) => undiciFetch(url, {
|
|
43
|
+
// undici v8's `RequestInit`/`Response` and the global fetch types come
|
|
44
|
+
// from different type generations (TS 7 ArrayBuffer variance), so the
|
|
45
|
+
// bridge casts below are required; the runtime objects are identical.
|
|
46
|
+
...init,
|
|
47
|
+
dispatcher: agent,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
@@ -2,6 +2,7 @@ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
|
2
2
|
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
3
3
|
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
4
4
|
import { getDownstreamTimeoutMs } from '../utils/index.js';
|
|
5
|
+
import { createDedicatedFetch } from './dedicated-fetch.js';
|
|
5
6
|
/** JSON-RPC error code for "Method not found". */
|
|
6
7
|
const METHOD_NOT_FOUND = -32601;
|
|
7
8
|
/**
|
|
@@ -131,5 +132,8 @@ export function createTransport(server, getAuthProvider) {
|
|
|
131
132
|
return new StreamableHTTPClientTransport(new URL(server.url), {
|
|
132
133
|
requestInit: Object.keys(requestInit).length > 0 ? requestInit : undefined,
|
|
133
134
|
authProvider,
|
|
135
|
+
// Route all of this server's traffic through its own undici agent so
|
|
136
|
+
// it uses a private connection pool instead of the shared default one.
|
|
137
|
+
fetch: createDedicatedFetch(),
|
|
134
138
|
});
|
|
135
139
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-compress-router",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Compress all connected MCP servers into a single router MCP to save tokens",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
"dotenv": "17.4.2",
|
|
69
69
|
"jsonc-parser": "3.3.1",
|
|
70
70
|
"picomatch": "4.0.5",
|
|
71
|
+
"undici": "8.10.0",
|
|
71
72
|
"zod": "4.4.3"
|
|
72
73
|
}
|
|
73
74
|
}
|