@gemus/mcp-proxy 0.1.7 → 0.1.9

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,69 @@
1
+ import { Agent, Pool, fetch as undiciFetch } from 'undici'
2
+
3
+ const DEFAULT_ATTEMPT_TIMEOUT_MS = 1000
4
+ const MIN_ATTEMPT_TIMEOUT_MS = 10
5
+ const SHUTDOWN_TIMEOUT_MS = 2000
6
+
7
+ function attemptTimeoutFromEnvironment(value) {
8
+ const parsed = Number(value)
9
+ if (!value || !Number.isFinite(parsed) || parsed <= 0) return DEFAULT_ATTEMPT_TIMEOUT_MS
10
+ return Math.max(MIN_ATTEMPT_TIMEOUT_MS, Math.trunc(parsed))
11
+ }
12
+
13
+ function settleClose(closePromise) {
14
+ return new Promise((resolve) => {
15
+ const timer = setTimeout(() => resolve('timed_out'), SHUTDOWN_TIMEOUT_MS)
16
+ Promise.resolve(closePromise).then(
17
+ () => {
18
+ clearTimeout(timer)
19
+ resolve('settled')
20
+ },
21
+ () => {
22
+ clearTimeout(timer)
23
+ resolve('rejected')
24
+ },
25
+ )
26
+ })
27
+ }
28
+
29
+ /** Owns the MCP upstream dispatcher and its bounded shutdown. */
30
+ export function createUpstreamHttp() {
31
+ const attemptTimeoutMs = attemptTimeoutFromEnvironment(process.env.PROXY_CONNECT_ATTEMPT_TIMEOUT_MS)
32
+ const originDispatchers = new Set()
33
+ const dispatcher = new Agent({
34
+ factory(origin, options) {
35
+ const originDispatcher = new Pool(origin, options)
36
+ originDispatchers.add(originDispatcher)
37
+ return originDispatcher
38
+ },
39
+ connect: {
40
+ autoSelectFamily: true,
41
+ autoSelectFamilyAttemptTimeout: attemptTimeoutMs,
42
+ },
43
+ })
44
+ let shutdownPromise
45
+
46
+ function upstreamFetch(input, init) {
47
+ return undiciFetch(input, { ...init, dispatcher })
48
+ }
49
+
50
+ function shutdown() {
51
+ if (!shutdownPromise) {
52
+ shutdownPromise = (async () => {
53
+ const closePromise = dispatcher.close()
54
+ const outcome = await settleClose(closePromise)
55
+ if (outcome !== 'settled') {
56
+ const error = new Error('MCP upstream dispatcher shutdown timed out')
57
+ await Promise.allSettled([
58
+ dispatcher.destroy(error),
59
+ ...Array.from(originDispatchers, (originDispatcher) => originDispatcher.destroy(error)),
60
+ ])
61
+ }
62
+ originDispatchers.clear()
63
+ })()
64
+ }
65
+ return shutdownPromise
66
+ }
67
+
68
+ return { fetch: upstreamFetch, shutdown, attemptTimeoutMs }
69
+ }