@x-otto/mcp 0.1.0-alpha.19 → 0.1.0-alpha.22

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/index.d.ts CHANGED
@@ -274,6 +274,12 @@ interface McpTransport {
274
274
  onClose(handler: (reason?: string) => void): void;
275
275
  start(): Promise<void>;
276
276
  close(): Promise<void>;
277
+ /**
278
+ * 可选:注入"当前是否有在途请求"的探针。HTTP+SSE 传输用它判定"流里只有坏帧"是真故障
279
+ * (有请求在干等)还是良性噪声(响应走 POST、流里只是厂商保活帧)。
280
+ * 不实现该方法的传输(stdio / streamable HTTP)不受影响。
281
+ */
282
+ setPendingProbe?(probe: () => boolean): void;
277
283
  }
278
284
  /**
279
285
  * 校验 MCP server URL:协议白名单 http/https,拒绝 file:/ftp:/data:/javascript: 等。
@@ -340,7 +346,42 @@ declare class SseTransport implements McpTransport {
340
346
  private readonly requestTimeoutMs;
341
347
  private readonly headers;
342
348
  private readonly getAuthToken?;
349
+ /**
350
+ * 规范(MCP 2024-11-05 HTTP+SSE)要求:连接建立后服务端先发 `event: endpoint`,data 为
351
+ * 客户端**发消息专用**的 URI,"All subsequent client messages MUST be sent as HTTP POST
352
+ * requests to this endpoint"。此前实现不消费该事件、POST 一律打到 baseUrl——对 SSE 端点与
353
+ * POST 端点分离的网关(规范的标准形态)直接连不上,且 endpoint 事件的 data 因不是 JSON
354
+ * 被当"非 JSON 帧"忽略。此处持有解析后的绝对 URL(相对 URI 以 baseUrl 为基准解析)。
355
+ */
356
+ private messageEndpoint;
357
+ /** endpoint 事件先于首个 send 到达的等待闩:首个 send 最多等它一小会儿。 */
358
+ private endpointWaiters;
359
+ /**
360
+ * endpoint 归属已确定(收到事件,或主流已结束/出错证明不会再来)。置位后 send 不再等待——
361
+ * 不发 endpoint 事件的服务端(SSE 与 POST 同路径)必须零额外延迟地回落 baseUrl。
362
+ */
363
+ private endpointSettled;
364
+ /** 由 McpClient 注入:当前是否有在途请求在等应答(见 armViolationTimer 第 ④ 条件)。 */
365
+ private hasPendingRequests?;
343
366
  constructor(url: string, options?: SseTransportOptions);
367
+ /**
368
+ * POST 目标:优先用服务端经 `endpoint` 事件下发的地址;未下发则回落 baseUrl
369
+ * (兼容那些把 SSE 与 POST 合并在同一路径、不发 endpoint 事件的实现)。
370
+ */
371
+ private get postUrl();
372
+ /** 记录服务端下发的消息端点;相对 URI 以 baseUrl 解析,非法值忽略并告警。 */
373
+ private setMessageEndpoint;
374
+ /** 解除所有等待者:endpoint 已确定,或已确定不会再到(主流结束/出错/关闭)。 */
375
+ private settleEndpoint;
376
+ /**
377
+ * 首个 send 可能早于 endpoint 事件到达(GET 响应头一回来 start() 就 resolve,流体是异步的)。
378
+ * 等待窗口很短——等不到就按回落地址(baseUrl)发,绝不把请求拖到超时。
379
+ *
380
+ * 窗口必须**远小于**坏帧协议违例的宽限期:不发 endpoint 事件的服务端(SSE 与 POST 同
381
+ * 路径)很常见,若在此空等得太久,请求迟迟发不出去,反而会被违例判定当成"久等无应答"
382
+ * 而误杀健康连接(实测复现过)。200ms 足够覆盖"事件已在飞行途中"的正常情形。
383
+ */
384
+ private awaitMessageEndpoint;
344
385
  /** 解析本次请求的 headers:静态 headers + 动态 Bearer(最高优先)+ 内置协议头覆盖。 */
345
386
  private resolveHeaders;
346
387
  /**
@@ -352,6 +393,7 @@ declare class SseTransport implements McpTransport {
352
393
  private failRequest;
353
394
  onMessage(handler: (message: JsonRpcResponse | JsonRpcNotification) => void): void;
354
395
  onClose(handler: (reason?: string) => void): void;
396
+ setPendingProbe(probe: () => boolean): void;
355
397
  close(): Promise<void>;
356
398
  private consumeStream;
357
399
  }
@@ -382,6 +424,11 @@ declare class StreamableHttpTransport implements McpTransport {
382
424
  private resolveHeaders;
383
425
  start(): Promise<void>;
384
426
  send(message: JsonRpcRequest | JsonRpcNotification): Promise<void>;
427
+ /**
428
+ * 把传输层故障投递为在途请求的 JSON-RPC error 响应——让 `McpClient.request` 的 pending
429
+ * 立即 reject,而不是干等 requestTimeoutMs。通知(无 id)无在途请求,静默即可。
430
+ */
431
+ private failRequest;
385
432
  private consumeSseResponse;
386
433
  onMessage(handler: (message: JsonRpcResponse | JsonRpcNotification) => void): void;
387
434
  onClose(handler: (reason?: string) => void): void;
@@ -407,8 +454,15 @@ interface SseDataParser {
407
454
  /** 流结束时调用:派发任何未以空行收尾的累积事件。 */
408
455
  flush(): void;
409
456
  }
410
- /** 创建一个 SSE data 解析器;每个完整事件的 data(多行已 join)经 onData 回调。 */
411
- declare function createSseDataParser(onData: (data: string) => void): SseDataParser;
457
+ /**
458
+ * 创建一个 SSE 事件解析器;每个完整事件的 data(多行已 join)经 onData 回调。
459
+ *
460
+ * 第二个参数是事件名(`event:` 字段值,缺省 `'message'`)——MCP 2024-11-05 HTTP+SSE
461
+ * 规范要求服务端连接时先发一个 `event: endpoint` 事件告知 POST 端点,其 data 是 URI
462
+ * 而非 JSON,必须按事件名分流而不能当普通消息帧解析(否则被当成"非 JSON 帧"忽略)。
463
+ * 只关心 data 的调用方可继续用单参回调,签名向后兼容。
464
+ */
465
+ declare function createSseDataParser(onData: (data: string, event: string) => void): SseDataParser;
412
466
  //#endregion
413
467
  //#region src/mcp-client.d.ts
414
468
  /**
@@ -426,6 +480,14 @@ interface DisconnectInfo {
426
480
  interface McpClientOptions {
427
481
  /** 请求超时(毫秒),默认 30000 */
428
482
  requestTimeoutMs?: number;
483
+ /**
484
+ * 连接阶段超时(毫秒),默认 10000。覆盖 `connect()` 全程(transport.start + initialize
485
+ * + tools/list + 可选的 resources/prompts),超时即中止本次连接并抛 MCP_CONNECT_TIMEOUT。
486
+ *
487
+ * 与 requestTimeoutMs 分离:连接阶段卡死会拖住宿主装配(connectAll 被 await),而单次
488
+ * 业务请求慢是可接受的。设 0 表示不启用连接阶段超时(回到旧行为)。
489
+ */
490
+ connectTimeoutMs?: number;
429
491
  /** 自动重连(默认 true) */
430
492
  autoReconnect?: boolean;
431
493
  /** 最大重连次数(默认 3) */
@@ -487,10 +549,29 @@ declare class McpClient {
487
549
  */
488
550
  onNotification(callback: (method: string, params?: Record<string, unknown>) => void): void;
489
551
  connect(): Promise<void>;
552
+ /**
553
+ * 连接阶段总预算——把 `establish()`(transport.start + initialize + tools/list + 可选
554
+ * resources/prompts)整体包在一个短超时里。
555
+ *
556
+ * 为什么不是仅靠 requestTimeoutMs:那是**每个请求各自**的预算,且线上放宽到 30s;
557
+ * 一个挂起的 server 会让 `connectAll` 的 `Promise.allSettled` 等满 30s,把宿主装配
558
+ * (实测 0.4s)拖成 30s+。连接阶段单独给短预算,超时即放弃该 server,其余照常。
559
+ *
560
+ * 超时后必须 `transport.close()`——否则已建的连接/子进程会在后台继续跑(泄漏),
561
+ * 且其迟到的响应会打到一个已被判失败的 client 上。
562
+ */
563
+ private establishWithTimeout;
490
564
  private establish;
491
565
  private handleTransportClose;
492
566
  private scheduleReconnect;
493
567
  private attemptReconnect;
568
+ /**
569
+ * 是否存在"已等待超过 STALE_PENDING_MS 仍无应答"的在途请求。
570
+ *
571
+ * 传输层用它作为"流里只有坏帧"是否属真故障的判据:刚发出的请求正常也在途(响应可能
572
+ * 稍后经 POST 响应体返回),只有**久等不到**才说明网关在用错误体应答而非讲 MCP。
573
+ */
574
+ private hasStalePending;
494
575
  private failPending;
495
576
  refreshTools(): Promise<McpToolDefinition[]>;
496
577
  refreshResources(): Promise<McpResource[]>;
@@ -525,6 +606,12 @@ declare function createMcpClient(serverName: string, config: McpServerConfig, op
525
606
  interface McpManagerOptions {
526
607
  /** 每个 MCP 请求超时 */
527
608
  requestTimeoutMs?: number;
609
+ /**
610
+ * 连接阶段超时(ms,默认 10_000)。与 requestTimeoutMs 分离——见
611
+ * `McpClientOptions.connectTimeoutMs`。只做全局配置(同 reconnectDelayMs),
612
+ * `McpServerConfig` 暂不提供 per-server 覆盖。
613
+ */
614
+ connectTimeoutMs?: number;
528
615
  /** 连接失败时是否静默跳过(默认 true) */
529
616
  skipOnError?: boolean;
530
617
  /** 自动重连(默认 true) */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/transport.ts","../src/sse.ts","../src/mcp-client.ts","../src/mcp-manager.ts","../src/mcp-tool-adapter.ts","../src/oauth/discovery.ts","../src/oauth/registration.ts","../src/oauth/token.ts","../src/oauth/token-store.ts","../src/oauth/refresh-lock.ts","../src/oauth/login.ts","../src/dot-mcp-json.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/transport.ts","../src/sse.ts","../src/mcp-client.ts","../src/mcp-manager.ts","../src/mcp-tool-adapter.ts","../src/oauth/discovery.ts","../src/oauth/registration.ts","../src/oauth/token.ts","../src/oauth/token-store.ts","../src/oauth/refresh-lock.ts","../src/oauth/login.ts","../src/dot-mcp-json.ts"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import{spawn as e}from"node:child_process";import{API_IMAGE_DIMENSION_LIMIT_PX as t,McpError as n,OAuthError as r,PROVIDER_IMAGE_INLINE_MAX_BYTES as i,TypedEventEmitter as a,buildAllowedEnv as o,createLogger as s,createPkcePair as c,generateState as l,probeImageDimensions as u,startLoopbackServer as d,traceStartupPhase as f}from"@x-otto/shared";import{z as p}from"zod";import{REFRESH_LOCK_TIMEOUT_MS as m,createOverlayStore as h,createRefreshLock as g,deleteFileIfExists as _,ensurePrivateDir as ee,isExpiredAt as te,readJsonFile as ne,refreshUnderCrossProcessLock as re,writeJsonAtomic as ie}from"@x-otto/credentials";import{createHash as ae}from"node:crypto";import{readFile as oe,readdir as se}from"node:fs/promises";import{homedir as ce}from"node:os";import{join as v,resolve as le}from"node:path";import{isShadowModeEnabled as ue}from"@x-otto/env";import{existsSync as de,readFileSync as fe}from"node:fs";function y(e){let t=``,n=[],r=()=>{if(n.length===0)return;let t=n.join(`
2
- `);n=[],e(t)},i=e=>{let t=e.endsWith(`\r`)?e.slice(0,-1):e;if(t===``){r();return}if(!t.startsWith(`:`)&&t.startsWith(`data:`)){let e=t.slice(5);e.startsWith(` `)&&(e=e.slice(1)),n.push(e)}};return{feed(e){t+=e;let n=t.split(`
3
- `);t=n.pop()??``;for(let e of n)i(e)},flush(){t.length>0&&(i(t),t=``),r()}}}const b=s(`@x-otto/mcp:transport`),pe=3e4,me=32*1024*1024;function he(e){let t=[],n=e;for(;;){let e=n.indexOf(10);if(e===-1){n.length>me&&(b.warn(`MCP newline frame exceeds limit without terminator; resetting buffer`),n=Buffer.alloc(0));break}let r=n.subarray(0,e);r.length>0&&r[r.length-1]===13&&(r=r.subarray(0,r.length-1)),n=n.subarray(e+1);let i=r.toString(`utf-8`).trim();i&&t.push(i)}return{bodies:t,rest:n}}function x(e){let t;try{t=new URL(e)}catch{throw Error(`Invalid MCP server URL: ${e}`)}if(t.protocol!==`http:`&&t.protocol!==`https:`)throw Error(`Unsupported MCP server URL protocol: ${t.protocol} (use http/https)`);return t}var S=class{managedProcess=null;messageHandler=null;closeHandler=null;closing=!1;buffer=Buffer.alloc(0);command;args;env;processSpawnFactory;constructor(e,t=[],n={},r){this.command=e,this.args=t,this.env=n,this.processSpawnFactory=r}async start(){if(this.processSpawnFactory)this.managedProcess=this.processSpawnFactory(this.command,this.args,this.env);else{let t=e(this.command,this.args,{stdio:[`pipe`,`pipe`,`pipe`],env:o(this.env),detached:!0});this.managedProcess={pid:t.pid,stdin:t.stdin,stdout:t.stdout,stderr:t.stderr,kill:async()=>(t.stdin?.end(),new Promise(e=>{let n=setTimeout(()=>{t.kill(`SIGKILL`),e()},2e3);t.on(`exit`,()=>{clearTimeout(n),e()}),t.kill(`SIGTERM`)})),onError:e=>{t.on(`error`,e)},onExit:e=>{t.on(`exit`,()=>e())}}}let t=this.managedProcess,n=t.stdout;n&&n.on(`data`,e=>{this.pushChunk(Buffer.isBuffer(e)?e:Buffer.from(e))});let r=t.stderr;r&&r.on(`data`,e=>{let t=Buffer.isBuffer(e)?e.toString(`utf-8`).trimEnd():String(e).trimEnd();b.debug(`MCP stderr: %s`,t)}),t.onError(e=>{b.error(`MCP process error: %s`,e.message)}),t.onExit(()=>{b.debug(`MCP process exited`),this.closing||this.closeHandler?.(`process exited`),this.managedProcess=null})}send(e){let t=this.managedProcess?.stdin;if(!t?.writable)throw Error(`MCP stdio transport is not connected`);let n=JSON.stringify(e);t.write(n+`
4
- `)}onMessage(e){this.messageHandler=e}onClose(e){this.closeHandler=e}async close(){this.closing=!0,this.managedProcess&&=(await this.managedProcess.kill(),null)}pushChunk(e){if(e.length===0)return;let t=e.lastIndexOf(10);if(t===-1){if(this.buffer.length+e.length>me){b.warn(`MCP newline frame exceeds limit without terminator; resetting buffer`),this.buffer=Buffer.alloc(0);return}this.buffer=this.buffer.length===0?e:Buffer.concat([this.buffer,e]);return}let{bodies:n,rest:r}=he(this.buffer.length===0?e.subarray(0,t+1):Buffer.concat([this.buffer,e.subarray(0,t+1)])),i=e.subarray(t+1);r.length>0&&i.length>0?this.buffer=Buffer.concat([r,i]):r.length>0?this.buffer=r:this.buffer=i;for(let e of n)try{let t=JSON.parse(e);this.messageHandler?.(t)}catch(e){b.warn(`Failed to parse MCP message: %s`,e.message)}}},C=class{messageHandler=null;closeHandler=null;abortController=null;sessionId=null;closing=!1;baseUrl;fetchImpl;requestTimeoutMs;headers;getAuthToken;constructor(e,t={}){this.baseUrl=x(e).href,this.fetchImpl=t.fetchImpl??globalThis.fetch,this.requestTimeoutMs=t.requestTimeoutMs??pe,this.headers=t.headers??{},this.getAuthToken=t.getAuthToken}async resolveHeaders(...e){let t={...this.headers};if(this.getAuthToken){let e=await this.getAuthToken();e&&(t={...t,Authorization:`Bearer ${e}`})}for(let n of e)t={...t,...n};return t}async fetchWithAuthRetry(e,t,n){let r=e===`GET`?{Accept:`text/event-stream`}:{"Content-Type":`application/json`,...this.sessionId?{"Mcp-Session-Id":this.sessionId}:{}},i=await this.resolveHeaders(r),a=await this.fetchImpl(this.baseUrl,{method:e,headers:i,body:t,signal:n});if(a.status===401&&this.getAuthToken){if(b.debug(`MCP 401 on %s %s — attempting token refresh and retry`,e,this.baseUrl),await this.getAuthToken()){let i=await this.resolveHeaders(r);return this.fetchImpl(this.baseUrl,{method:e,headers:i,body:t,signal:n})}b.warn(`MCP token refresh returned no token for %s`,this.baseUrl)}return a}async start(){this.closing=!1,this.abortController=new AbortController;let e=await this.fetchWithAuthRetry(`GET`,void 0,this.abortController.signal);if(!e.ok)throw e.status===401?new n(`MCP server '${this.baseUrl}' requires authentication.`,{code:`MCP_UNAUTHORIZED`}):Error(`MCP SSE connection failed: ${e.status} ${e.statusText}`);let t=e.headers.get(`mcp-session-id`);t&&(this.sessionId=t),this.consumeStream(e,!0)}async send(e){let t=new AbortController,n=setTimeout(()=>{t.abort(new DOMException(`MCP request timeout`,`TimeoutError`))},this.requestTimeoutMs);n.unref?.();let r=this.abortController?AbortSignal.any([this.abortController.signal,t.signal]):t.signal;this.fetchWithAuthRetry(`POST`,JSON.stringify(e),r).then(async t=>{if(clearTimeout(n),!t.ok){if(t.status===401){b.warn(`MCP SSE POST 401: authentication required for %s`,this.baseUrl),this.failRequest(e,-32001,`MCP server requires authentication.`);return}b.warn(`MCP SSE POST failed: %s`,t.status),this.failRequest(e,-32e3,`MCP SSE POST failed: HTTP ${t.status}`);return}let r=t.headers.get(`mcp-session-id`);r&&(this.sessionId=r);let i=t.headers.get(`content-type`)??``;if(i.includes(`application/json`)){let e=await t.json();this.messageHandler?.(e)}else i.includes(`text/event-stream`)&&this.consumeStream(t,!1)}).catch(t=>{clearTimeout(n),t.name!==`AbortError`&&(b.warn(`MCP SSE send error: %s`,t.message),this.failRequest(e,-32e3,`MCP SSE send error: ${t.message}`))})}failRequest(e,t,n){`id`in e&&e.id!==void 0&&e.id!==null&&this.messageHandler?.({jsonrpc:`2.0`,id:e.id,error:{code:t,message:n}})}onMessage(e){this.messageHandler=e}onClose(e){this.closeHandler=e}async close(){this.closing=!0,this.abortController?.abort(),this.abortController=null}async consumeStream(e,t){let n=e.body?.getReader();if(!n){t&&!this.closing&&this.closeHandler?.(`SSE stream had no readable body`);return}let r=new TextDecoder,i=y(e=>{let t=e.trim();if(!(!t||t===`[DONE]`))try{let e=JSON.parse(t);this.messageHandler?.(e)}catch{b.debug(`Ignoring non-JSON SSE data`)}});try{for(;;){let{done:e,value:t}=await n.read();if(e)break;i.feed(r.decode(t,{stream:!0}))}i.flush(),t&&!this.closing&&this.closeHandler?.(`SSE stream ended`)}catch(e){e.name!==`AbortError`&&(b.warn(`MCP SSE stream error: %s`,e.message),t&&!this.closing&&this.closeHandler?.(`SSE stream error: ${e.message}`))}finally{n.releaseLock()}}},w=class{messageHandler=null;closeHandler=null;abortController=null;sessionId=null;closing=!1;baseUrl;fetchImpl;requestTimeoutMs;headers;getAuthToken;constructor(e,t={}){this.baseUrl=x(e).href,this.fetchImpl=t.fetchImpl??globalThis.fetch,this.requestTimeoutMs=t.requestTimeoutMs??pe,this.headers=t.headers??{},this.getAuthToken=t.getAuthToken}async resolveHeaders(...e){let t={...this.headers};if(this.getAuthToken){let e=await this.getAuthToken();e&&(t={...t,Authorization:`Bearer ${e}`})}for(let n of e)t={...t,...n};return t}async start(){this.closing=!1,this.abortController=new AbortController}async send(e){let t=new AbortController,n=setTimeout(()=>{t.abort(new DOMException(`MCP request timeout`,`TimeoutError`))},this.requestTimeoutMs);n.unref?.();let r=this.abortController?AbortSignal.any([this.abortController.signal,t.signal]):t.signal,i={"Content-Type":`application/json`,Accept:`application/json, text/event-stream`,...this.sessionId?{"Mcp-Session-Id":this.sessionId}:{}},a=JSON.stringify(e),o;try{o=await this.fetchImpl(this.baseUrl,{method:`POST`,headers:await this.resolveHeaders(i),body:a,signal:r}),o.status===401&&this.getAuthToken&&await this.getAuthToken()&&(o=await this.fetchImpl(this.baseUrl,{method:`POST`,headers:await this.resolveHeaders(i),body:a,signal:r}))}catch(e){clearTimeout(n),e.name!==`AbortError`&&!this.closing&&this.closeHandler?.(`HTTP POST failed: ${e.message}`);return}let s=o.headers.get(`mcp-session-id`);if(s&&(this.sessionId=s),!o.ok){if(clearTimeout(n),o.status===401){this.closing||this.closeHandler?.(`unauthorized`);return}o.status!==202&&!this.closing&&this.closeHandler?.(`HTTP ${o.status} ${o.statusText}`);return}if((o.headers.get(`content-type`)??``).toLowerCase().includes(`text/event-stream`)){await this.consumeSseResponse(o),clearTimeout(n);return}clearTimeout(n);let c=await o.text();if(c.trim())try{let e=JSON.parse(c);for(let t of Array.isArray(e)?e:[e])this.messageHandler?.(t)}catch(e){b.warn(`MCP streamable-http non-JSON response body: %s`,e.message)}}async consumeSseResponse(e){let t=e.body?.getReader();if(!t)return;let n=new TextDecoder,r=y(e=>{let t=e.trim();if(!(!t||t===`[DONE]`))try{this.messageHandler?.(JSON.parse(t))}catch{b.debug(`Ignoring non-JSON SSE data`)}});try{for(;;){let{done:e,value:i}=await t.read();if(e)break;r.feed(n.decode(i,{stream:!0}))}r.flush()}catch(e){e.name!==`AbortError`&&b.warn(`MCP streamable-http stream error: %s`,e.message)}finally{t.releaseLock()}}onMessage(e){this.messageHandler=e}onClose(e){this.closeHandler=e}async close(){this.closing=!0,this.abortController?.abort(),this.abortController=null}};const T=s(`@x-otto/mcp:client`);var E=class{serverName;transport=null;config;options;status=`disconnected`;serverInfo=null;capabilities=null;tools=[];resources=[];prompts=[];nextRequestId=1;pending=new Map;closing=!1;reconnectAttempts=0;reconnectTimer=null;toolsChangedCallback=null;resourcesChangedCallback=null;disconnectedCallback=null;notificationCallback=null;constructor(e,t,n={}){this.serverName=e,this.config=t,this.options=n}getStatus(){return this.status}getConfig(){return this.config}getTools(){return this.tools}getResources(){return this.resources}getPrompts(){return this.prompts}getCapabilities(){return this.capabilities}getServerInfo(){return this.serverInfo}onToolsChanged(e){this.toolsChangedCallback=e}onResourcesChanged(e){this.resourcesChangedCallback=e}onDisconnected(e){this.disconnectedCallback=e}onNotification(e){this.notificationCallback=e}async connect(){if(this.status!==`ready`){this.closing=!1,this.status=`connecting`;try{await this.establish(),this.reconnectAttempts=0,this.status=`ready`}catch(e){this.status=`error`;let t=e instanceof Error?e.message:String(e);T.error(`MCP server "%s" connection failed: %s`,this.serverName,t);let r=e instanceof n&&e.code===`MCP_UNAUTHORIZED`?`MCP_UNAUTHORIZED`:`MCP_CONNECT_ERROR`;throw new n(`Failed to connect to MCP server "${this.serverName}": ${t}`,{code:r,cause:e instanceof Error?e:void 0})}}}async establish(){let e=this.createTransport();this.transport=e,e.onMessage(e=>this.handleMessage(e)),e.onClose(t=>{this.transport===e&&this.handleTransportClose(t)});try{await e.start(),this.serverInfo=await this.request(`initialize`,{protocolVersion:`2024-11-05`,capabilities:{roots:{listChanged:!1}},clientInfo:{name:`otto-coding`,version:`0.0.1`}}),this.capabilities=this.serverInfo.capabilities,this.notify(`notifications/initialized`),T.info(`MCP server "%s" connected: %s (protocol %s)`,this.serverName,this.serverInfo.serverInfo.name,this.serverInfo.protocolVersion),await this.refreshTools(),this.capabilities?.resources&&await this.refreshResources(),this.capabilities?.prompts&&await this.refreshPrompts()}catch(t){throw this.transport===e&&(this.transport=null),await e.close().catch(()=>void 0),t}}handleTransportClose(e){if(this.closing||(this.failPending(new n(`MCP transport closed: ${e??`unknown`}`,{code:`MCP_DISCONNECTED`})),this.status===`connecting`))return;let t=this.options.autoReconnect??!0,r=this.options.maxReconnectAttempts??3;if(!t||this.reconnectAttempts>=r){this.status=`disconnected`,this.transport=null,this.disconnectedCallback?.({reason:e,kind:`crash`});return}this.scheduleReconnect()}scheduleReconnect(){this.reconnectAttempts++,this.status=`reconnecting`;let e=(this.options.reconnectDelayMs??500)*2**(this.reconnectAttempts-1);T.info(`MCP server "%s" reconnecting (attempt %d) in %dms`,this.serverName,this.reconnectAttempts,e),this.reconnectTimer=setTimeout(()=>{this.attemptReconnect()},e)}async attemptReconnect(){if(!this.closing)try{this.transport&&await this.transport.close().catch(()=>void 0),this.transport=null,await this.establish(),this.reconnectAttempts=0,this.status=`ready`,T.info(`MCP server "%s" reconnected`,this.serverName)}catch(e){T.warn(`MCP server "%s" reconnect attempt %d failed: %s`,this.serverName,this.reconnectAttempts,e.message);let t=this.options.maxReconnectAttempts??3;this.reconnectAttempts>=t?(this.status=`error`,this.transport=null,this.disconnectedCallback?.({reason:`reconnect failed after ${t} attempts`,kind:`crash`})):this.scheduleReconnect()}}failPending(e){for(let[t,n]of this.pending)clearTimeout(n.timer),n.reject(e),this.pending.delete(t)}async refreshTools(){return this.tools=(await this.request(`tools/list`)).tools??[],T.debug(`MCP server "%s" provides %d tools: %s`,this.serverName,this.tools.length,this.tools.map(e=>e.name).join(`, `)),this.tools}async refreshResources(){try{this.resources=(await this.request(`resources/list`)).resources??[],T.debug(`MCP server "%s" provides %d resources`,this.serverName,this.resources.length)}catch(e){T.debug(`MCP server "%s" resources/list failed: %s`,this.serverName,e.message),this.resources=[]}return this.resources}async readResource(e){return(await this.request(`resources/read`,{uri:e})).contents??[]}async refreshPrompts(){try{this.prompts=(await this.request(`prompts/list`)).prompts??[],T.debug(`MCP server "%s" provides %d prompts`,this.serverName,this.prompts.length)}catch(e){T.debug(`MCP server "%s" prompts/list failed: %s`,this.serverName,e.message),this.prompts=[]}return this.prompts}async getPrompt(e,t){return await this.request(`prompts/get`,{name:e,arguments:t})}async callTool(e,t){if(this.status!==`ready`)throw new n(`MCP server "${this.serverName}" is not ready (status: ${this.status})`,{code:`MCP_NOT_READY`});return await this.request(`tools/call`,e,t)}async callRaw(e,t,n){return this.request(e,t,n)}async disconnect(){if(this.closing=!0,this.reconnectTimer&&=(clearTimeout(this.reconnectTimer),null),this.transport){try{await this.transport.close()}catch(e){T.debug(`Error closing MCP transport: %s`,e.message)}this.transport=null}this.failPending(new n(`MCP client disconnected`,{code:`MCP_DISCONNECTED`})),this.status=`disconnected`,this.tools=[],this.resources=[],this.prompts=[],this.serverInfo=null,this.capabilities=null,this.disconnectedCallback?.({reason:`client disconnect`,kind:`manual`})}createTransport(){if(this.options.transportFactory)return this.options.transportFactory();let{type:e,url:t,command:r}=this.config,i=e===`http`||e===void 0&&t!==void 0,a=e===`sse`,o=e===`stdio`||e===void 0&&r!==void 0;if(i||a){if(!t)throw new n(`MCP server "${this.serverName}" transport '${e}' requires a url`,{code:`MCP_CONFIG_ERROR`});let r={requestTimeoutMs:this.config.requestTimeoutMs??this.options.requestTimeoutMs,headers:this.config.headers,getAuthToken:this.options.getAuthToken};return a?new C(t,r):new w(t,r)}if(o){if(!r)throw new n(`MCP server "${this.serverName}" transport 'stdio' requires a command`,{code:`MCP_CONFIG_ERROR`});return new S(r,this.config.args??[],this.config.env??{},this.options.processSpawnFactory)}throw new n(`MCP server "${this.serverName}" has no command or url configured`,{code:`MCP_CONFIG_ERROR`})}request(e,t,r){return new Promise((i,a)=>{if(r?.aborted){a(new n(`MCP request "${e}" aborted`,{code:`MCP_ABORTED`}));return}let o=this.nextRequestId++,s=this.config.requestTimeoutMs??this.options.requestTimeoutMs??3e4,c,l=()=>{c&&r&&r.removeEventListener(`abort`,c)},u=setTimeout(()=>{this.pending.delete(o),l(),a(new n(`MCP request "${e}" timed out after ${s}ms`,{code:`MCP_TIMEOUT`}))},s);this.pending.set(o,{resolve:e=>{l(),i(e)},reject:e=>{l(),a(e)},timer:u}),r&&(c=()=>{let t=this.pending.get(o);t&&(clearTimeout(t.timer),this.pending.delete(o),l(),a(new n(`MCP request "${e}" aborted`,{code:`MCP_ABORTED`})))},r.addEventListener(`abort`,c,{once:!0}));let d={jsonrpc:`2.0`,id:o,method:e,...t!==void 0&&{params:t}};try{this.transport.send(d)}catch(e){clearTimeout(u),this.pending.delete(o),l(),a(e)}})}notify(e,t){let n={jsonrpc:`2.0`,method:e,...t!==void 0&&{params:t}};try{this.transport.send(n)}catch(t){T.debug(`Failed to send MCP notification "%s": %s`,e,t.message)}}handleMessage(e){if(!(`id`in e)||e.id===void 0){this.handleNotification(e);return}let t=e,r=this.pending.get(t.id);if(!r){T.debug(`Received response for unknown request id: %s`,t.id);return}clearTimeout(r.timer),this.pending.delete(t.id),t.error?r.reject(new n(`MCP error: ${t.error.message} (code: ${t.error.code})`,{code:`MCP_SERVER_ERROR`})):r.resolve(t.result)}handleNotification(e){switch(e.method){case`notifications/tools/list_changed`:T.info(`MCP server "%s" notified tools list changed`,this.serverName),this.refreshTools().then(()=>{this.toolsChangedCallback?.()});break;case`notifications/resources/list_changed`:T.info(`MCP server "%s" notified resources list changed`,this.serverName),this.refreshResources().then(()=>{this.resourcesChangedCallback?.()});break;default:T.debug(`MCP notification: %s`,e.method)}this.notificationCallback?.(e.method,e.params)}};function D(e,t,n){return new E(e,t,n)}const ge=s(`@x-otto/mcp:adapter`);function _e(e){if(e.length===0)return null;if(e.every(e=>typeof e==`string`))return p.enum(e);let t=e.filter(e=>{let t=typeof e;return t===`string`||t===`number`||t===`boolean`}).map(e=>p.literal(e));return t.length===0?null:t.length===1?t[0]:p.union(t)}function O(e){if(e.oneOf&&Array.isArray(e.oneOf)&&e.oneOf.length>0){let t=e.oneOf.map(e=>O(e));return e.description?p.union(t).describe(e.description):p.union(t)}if(e.anyOf&&Array.isArray(e.anyOf)&&e.anyOf.length>0){let t=e.anyOf.map(e=>O(e));return e.description?p.union(t).describe(e.description):p.union(t)}if(e.allOf&&Array.isArray(e.allOf)&&e.allOf.length>0)return console.warn(`[mcp-tool-adapter] allOf schema degraded to last sub-schema (intersection unsupported)`),O(e.allOf[e.allOf.length-1]);if(typeof e.$ref==`string`){let t=ve(e.$ref,e);return t?O(t):(console.warn(`[mcp-tool-adapter] unresolvable $ref "${e.$ref}" degraded to z.unknown()`),p.unknown())}if(Array.isArray(e.enum)){let t=_e(e.enum);if(t)return e.description?t.describe(e.description):t}switch(e.type){case`string`:return e.description?p.string().describe(e.description):p.string();case`number`:case`integer`:{let t=e.type===`integer`?p.number().int():p.number(),n=p.preprocess(e=>typeof e==`string`?Number(e):e,t);return e.description?n.describe(e.description):n}case`boolean`:return e.description?p.boolean().describe(e.description):p.boolean();case`array`:{let t=e.items?O(e.items):p.unknown();return e.description?p.array(t).describe(e.description):p.array(t)}case`object`:if(e.properties){let t={},n=new Set(e.required??[]);for(let[r,i]of Object.entries(e.properties)){let e=O(i);t[r]=n.has(r)?e:e.optional()}return e.description?p.object(t).describe(e.description):p.object(t)}return e.description?p.record(p.string(),p.unknown()).describe(e.description):p.record(p.string(),p.unknown());default:return console.warn(`[mcp-tool-adapter] unsupported JSON schema type "${e.type}" degraded to z.unknown()`),p.unknown()}}function ve(e,t){let n=/^#\/(?:definitions|\$defs)\/([^/]+)$/.exec(e);if(!n)return;let r=n[1].replace(/~1/g,`/`).replace(/~0/g,`~`),i=t;return i.definitions?.[r]??i.$defs?.[r]}function k(e){let t=e.inputSchema.properties;if(!t||Object.keys(t).length===0)return p.object({});let n={},r=new Set(e.inputSchema.required??[]);for(let[e,i]of Object.entries(t)){let t=O(i);n[e]=r.has(e)?t:t.optional()}return p.object(n)}const A=i;function j(e){let t=e.endsWith(`==`)?2:e.endsWith(`=`)?1:0;return Math.max(0,Math.floor(e.length*3/4)-t)}function ye(e){if(e.text!==void 0)return{type:`text`,text:e.text};if(e.blob!==void 0){if(e.mimeType?.startsWith(`image/`)&&e.mimeType!==`image/svg+xml`){let n=j(e.blob);if(n>A)return{type:`text`,text:`[image omitted: ${n} bytes exceeds ${A} byte limit — ask the tool to capture a smaller region/resolution]`};let r=u(e.blob,e.mimeType);return r&&(r.width>t||r.height>t)?{type:`text`,text:`[image omitted: ${r.width}x${r.height}px exceeds Anthropic per-image dimension hard limit of ${t}px — ask the tool to capture a smaller region or lower resolution]`}:{type:`image`,mime:e.mimeType,source:`data:${e.mimeType};base64,${e.blob}`}}let n=e.mimeType?` (${e.mimeType})`:``;return{type:`text`,text:`[Resource: ${e.uri}${n}, ${j(e.blob)} bytes binary]`}}return{type:`text`,text:`[Resource: ${e.uri}]`}}function M(e){return e.map(e=>{switch(e.type){case`text`:return{type:`text`,text:e.text};case`image`:if(!e.data)return{type:`text`,text:`[image unavailable: no data]`};{let n=j(e.data);if(n>A)return{type:`text`,text:`[image omitted: ${n} bytes exceeds ${A} byte limit — ask the tool to capture a smaller region/resolution]`};let r=u(e.data,e.mimeType??``);if(r&&(r.width>t||r.height>t))return{type:`text`,text:`[image omitted: ${r.width}x${r.height}px exceeds Anthropic per-image dimension hard limit of ${t}px — ask the tool to capture a smaller region or lower resolution]`}}return{type:`image`,mime:e.mimeType,source:`data:${e.mimeType};base64,${e.data}`};case`resource`:return ye(e.resource);default:return{type:`text`,text:JSON.stringify(e)}}})}function be(e){let t=e.toLowerCase().replace(/[_\s-]/g,``);return[`source`,`destination`,`dest`,`src`,`cwd`,`location`].includes(t)?!0:t.includes(`path`)||t.includes(`file`)||t.includes(`dir`)||t.includes(`folder`)}function xe(e){let t=e.inputSchema.properties;if(!t)return[];let n=[];for(let[e,r]of Object.entries(t)){let t=r.type;(t===`string`||t===void 0)&&be(e)&&n.push(e)}return n}function N(e,t,n){let r=`mcp__${n}__${t.name}`,i=t.description?`[MCP: ${n}] ${t.description}`:`[MCP: ${n}] ${t.name}`,a=k(t),o=xe(t),s=t.annotations?.readOnlyHint===!0;return{name:r,description:i,parameters:a,...o.length>0?{pathParams:o}:{},...s?{readonly:!0}:{},exposure:`deferred`,async execute({params:r,signal:i}){ge.debug(`Calling MCP tool %s on server %s`,t.name,n);let a=await e.callTool({name:t.name,arguments:r},i),o=M(a.content);return{content:o.length>0?o:[{type:`text`,text:`(empty result)`}],isError:a.isError??!1,details:{mcpServer:n,mcpTool:t.name}}}}}function P(e,t){return e.getTools().map(n=>N(e,n,t))}function F(e){let t=e.split(`,`).map(e=>e.trim()).find(e=>e.toLowerCase().startsWith(`bearer `)||e.toLowerCase()===`bearer`);if(t)return t.match(/metadata_url\s*=\s*"([^"]+)"/i)?.[1]}async function I(e,t=fetch){let n=await t(e,{headers:{Accept:`application/json`}});if(!n.ok)throw Error(`Failed to fetch protected resource metadata from ${e}: ${n.status}`);return await n.json()}async function L(e,t=fetch){let n=`${e.replace(/\/$/,``)}/.well-known/oauth-authorization-server`,r=`${e.replace(/\/$/,``)}/.well-known/openid-configuration`,i=async e=>{let n=await t(e,{headers:{Accept:`application/json`}});if(!n.ok)throw Error(`Metadata fetch failed: ${e} → ${n.status}`);return await n.json()};try{return await i(n)}catch{return i(r)}}async function R(e,t={}){let n=t.fetch??fetch,r=F(t.wwwAuthenticate??``)??`${e.replace(/\/$/,``)}/.well-known/oauth-protected-resource`,i=await I(r,n),a=i.authorization_servers?.[0]??new URL(r).origin;return{protectedResource:i,authorizationServer:await L(a,n),issuer:a}}async function z(e,t,n={}){let r=n.fetch??fetch,i={"Content-Type":`application/json`,Accept:`application/json`};n.initialAccessToken&&(i.Authorization=`Bearer ${n.initialAccessToken}`);let a=await r(e,{method:`POST`,headers:i,body:JSON.stringify({client_name:t.client_name??`otto MCP Client`,redirect_uris:t.redirect_uris,grant_types:t.grant_types??[`authorization_code`,`refresh_token`],token_endpoint_auth_method:t.token_endpoint_auth_method??`none`})});if(!a.ok){let t=await a.text().catch(()=>``);throw Error(`DCR registration failed at ${e}: ${a.status}${t?` — ${t}`:``}`)}return await a.json()}async function B(e,t,n={}){let i=n.fetch??fetch,a=new URLSearchParams({grant_type:`authorization_code`,code:t.code,redirect_uri:t.redirectUri,code_verifier:t.codeVerifier,client_id:t.clientId});t.resource&&a.set(`resource`,t.resource);let o=await i(e,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`,Accept:`application/json`},body:a.toString()});if(!o.ok){let e=await o.text().catch(()=>``);throw new r(`Token exchange failed: ${o.status}${e?` — ${e}`:``}`,{code:`OAUTH_TOKEN_EXCHANGE_FAILED`})}return H(await o.json())}async function V(e,t,n={}){let i=n.fetch??fetch,a=new URLSearchParams({grant_type:`refresh_token`,refresh_token:t.refreshToken});t.clientId&&a.set(`client_id`,t.clientId),t.resource&&a.set(`resource`,t.resource);let o=await i(e,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`,Accept:`application/json`},body:a.toString()});if(!o.ok){let e=await o.text().catch(()=>``),t=Se(e);throw new r(`Token refresh failed: ${o.status}${e?` — ${e}`:``}`,{code:`OAUTH_REFRESH_FAILED`,...t?{errorType:t}:{}})}return H(await o.json(),t.refreshToken)}function H(e,t){return{accessToken:e.access_token,refreshToken:e.refresh_token??t,expiresAt:e.expires_in?(e.issued_at??Date.now())+e.expires_in*1e3:void 0,resource:e.resource}}function Se(e){try{let t=JSON.parse(e);return typeof t.error==`string`?t.error:void 0}catch{return}}function U(e,t=60){return te(e.expiresAt,t*1e3)}function W(e={}){let t=e.baseDir??v(ce(),`.otto`,`mcp`,`credentials`),n=e=>v(t,`${q(e)}.json`);return{refreshLockDir:t,async load(e){return ne(n(e),void 0)},async save(e,r){await ee(t),await ie(n(e),{...r,serverName:e})},async delete(e){await _(n(e))},async list(){try{let e=await se(t),n=[];for(let r of e)if(r.endsWith(`.json`))try{let e=we(await oe(v(t,r),`utf-8`));n.push(e??r.slice(0,-5))}catch{n.push(r.slice(0,-5))}return n}catch(e){if(e?.code===`ENOENT`)return[];throw e}}}}function Ce(){let e=new Map;return{async load(t){return e.get(t)},async save(t,n){e.set(t,n)},async delete(t){e.delete(t)},async list(){return[...e.keys()]}}}function G(e){let t=h(e);return{load:t.load,save:t.save,delete:t.delete,list:t.list,shadow:!0,refreshLockDir:void 0}}function K(e={}){let t=W(e);return ue()?G(t):t}function q(e){return`${e.replace(/[^a-zA-Z0-9._-]/g,`_`)}_${ae(`sha256`).update(e).digest(`hex`).slice(0,8)}`}function we(e){try{let t=JSON.parse(e);return typeof t.serverName==`string`?t.serverName:void 0}catch{return}}const J=`mcp-refresh`;async function Te(e,t,n=m){return g(e,J).acquire(q(t),n)}async function Ee(e,t){return g(e,J).release(q(t))}async function De(e,t,n=m){return g(e,J).waitForRelease(q(t),n)}async function Y(e,t,n,r,i={},a,o){return re({lock:g(e,J),key:q(t),load:a.load,isFresh:e=>!U(e),refresh:()=>V(n,r,i),save:a.save,strategy:o})}async function X(e){let{serverUrl:t,serverName:n,wwwAuthenticate:r,clientId:i,authorizationServer:a,tokenStore:o=K(),openBrowser:s=Ae,fetch:u=fetch,signal:f}=e;if(f?.aborted)throw Error(`Login cancelled`);let p=a??(await R(t,{wwwAuthenticate:r,fetch:u})).authorizationServer;if(!p.token_endpoint)throw Error(`Authorization server has no token_endpoint`);let m=c(),h=l(),g=await d({ports:[1455,1457,1459],expectedState:h,signal:f}),_=g.redirectUri;try{let e=i,r=!1;if(!e&&p.registration_endpoint&&(e=(await z(p.registration_endpoint,{redirect_uris:[_]},{fetch:u})).client_id,r=!0),!e)throw Error(`No client_id available. Configure client_id in MCP server settings or ensure the authorization server supports Dynamic Client Registration (registration_endpoint).`);let a=new URLSearchParams({response_type:`code`,client_id:e,redirect_uri:_,code_challenge:m.challenge,code_challenge_method:m.method,state:h});a.set(`resource`,t),await s(`${p.authorization_endpoint}?${a.toString()}`);let c=await g.waitForCallback(),l=await B(p.token_endpoint,{code:c.code,redirectUri:_,codeVerifier:m.verifier,resource:t,clientId:e},{fetch:u});return await o.save(n,{...l,clientId:e}),{credentials:l,registered:r,clientId:e}}finally{await g.close()}}function Oe(e){let{serverName:t,serverUrl:n,tokenStore:r=K(),clientId:i,authorizationServer:o,fetch:s}=e,c,l=o??void 0,u=e=>i?{...e,clientId:i}:e,d=new a;return{async getAccessToken(){if(c||=await r.load(t),c){if(U(c)&&c.refreshToken){if(r.shadow)return;try{l||=(await R(n,{fetch:s})).authorizationServer;let e={refreshToken:c.refreshToken,resource:n,clientId:c.clientId??i},a=r.refreshLockDir;a?(c=await Y(a,t,l.token_endpoint,e,{fetch:s},{load:()=>r.load(t),save:e=>r.save(t,u(e))},ke(t,r,u)),c=u(c),d.emit(`credential.changed`,{serverName:t,source:`refresh`})):(c=await V(l.token_endpoint,e,{fetch:s}),c=u(c),await r.save(t,c),d.emit(`credential.changed`,{serverName:t,source:`refresh`}))}catch{return}}return c.accessToken}},async login(e){return c=(await X({...e,tokenStore:r,clientId:i,authorizationServer:l})).credentials,l??=e.authorizationServer,d.emit(`credential.changed`,{serverName:t,source:`self`}),c.accessToken},async logout(){c=void 0,l=void 0,await r.delete(t),d.emit(`credential.changed`,{serverName:t,source:`self`})},async describe(){let e=c??await r.load(t);return e?{configured:!0,source:`oauth`,expiringSoon:U(e),shadow:r.shadow}:{configured:!1,shadow:r.shadow}},on(e,t){return d.on(e,t),this}}}function ke(e,t,n){let r=new Map;return{shouldFailFast(t){if(!t.refreshToken)return!1;let n=r.get(e);return!!n&&n.refreshToken===t.refreshToken},async recoverFromFailure(i){let a=await t.load(e);if(!(!a||!a.refreshToken)&&a.refreshToken!==i.refreshToken)return r.delete(e),n(a)},cacheFailure(t,n){t?.errorType===`invalid_grant`&&n.refreshToken&&r.set(e,{refreshToken:n.refreshToken,error:t})},onStep(t,n){process.env.OTTO_DEBUG&&t&&console.debug(`[mcp:refresh] ${e} ${t}${n?`: ${n}`:``}`)}}}async function Ae(t){let n=process.platform===`win32`,r=n?`cmd`:process.platform===`darwin`?`open`:`xdg-open`,i=n?[`/c`,`start`,``,t]:[t];return new Promise((t,n)=>{let a=e(r,i,{stdio:`ignore`,detached:!0});a.on(`error`,e=>{n(Error(`Failed to open browser: ${e.message}`))}),a.on(`close`,e=>{e===0||e===null?t():n(Error(`Browser command exited with code ${e}`))}),a.unref()})}const Z=s(`@x-otto/mcp:manager`);var je=class extends a{clients=new Map;options;disabledServers;constructor(e={},t=[]){super(),this.options=e,this.disabledServers=new Set(t)}async connectAll(e){let t=Object.entries(e);if(t.length===0)return{connected:0,failed:0};Z.info(`Connecting to %d MCP servers...`,t.length);let n=await Promise.allSettled(t.map(([e,t])=>f(`mcp:${e} connect`,()=>this.connect(e,t)))),r=0,i=0;for(let e of n)e.status===`fulfilled`?r++:i++;return Z.info(`MCP servers: %d connected, %d failed`,r,i),{connected:r,failed:i}}async connect(e,t){if(this.disabledServers.has(e)){Z.info(`MCP server "%s" is disabled, skipping`,e);return}this.clients.has(e)&&await this.disconnect(e);let r;if(t.url&&t.type!==`stdio`){let n=K(),i=await n.load(e);if(i){let a=Oe({serverName:e,serverUrl:t.url,tokenStore:n,clientId:i.clientId});r=()=>a.getAccessToken()}}let i=D(e,t,{requestTimeoutMs:t.requestTimeoutMs??this.options.requestTimeoutMs,autoReconnect:t.autoReconnect??this.options.autoReconnect,maxReconnectAttempts:t.maxReconnectAttempts??this.options.maxReconnectAttempts,reconnectDelayMs:this.options.reconnectDelayMs,getAuthToken:r,processSpawnFactory:this.options.processSpawnFactory,transportFactory:this.options.transportFactory});i.onToolsChanged(()=>{Z.info(`MCP server "%s" tools changed`,e),this.emit(`tools.changed`,{serverName:e,tools:i.getTools()})}),i.onResourcesChanged(()=>{Z.info(`MCP server "%s" resources changed`,e),this.emit(`resources.changed`,{serverName:e})}),i.onDisconnected(t=>{Z.info(`MCP server "%s" disconnected (%s): %s`,e,t.kind,t.reason??`unknown`),this.emit(`server.disconnected`,{name:e,reason:t.reason,kind:t.kind})}),i.onNotification((t,n)=>{this.emit(`server.notification`,{name:e,method:t,params:n})});try{await i.connect(),this.clients.set(e,i),this.emit(`server.connected`,{name:e,tools:i.getTools().length})}catch(t){let r=t.message,i=t instanceof n?t.code:void 0;if(this.emit(`server.error`,{name:e,error:r,code:i}),this.options.skipOnError!==!1)Z.warn(`MCP server "%s" connection failed, skipping: %s`,e,r);else throw t}}async disconnect(e){let t=this.clients.get(e);t&&(await t.disconnect(),this.clients.delete(e))}async disconnectAll(){let e=[...this.clients.keys()];await Promise.allSettled(e.map(e=>this.disconnect(e)))}getAllTools(){let e=[];for(let[t,n]of this.clients)n.getStatus()===`ready`&&e.push(...P(n,t));return e}getAllResources(){let e=[];for(let[t,n]of this.clients)if(n.getStatus()===`ready`)for(let r of n.getResources())e.push({...r,serverName:t});return e}getAllPrompts(){let e=[];for(let[t,n]of this.clients)if(n.getStatus()===`ready`)for(let r of n.getPrompts())e.push({...r,serverName:t});return e}getClient(e){return this.clients.get(e)}getServerInfos(){let e=[];for(let[t,n]of this.clients)e.push({name:t,config:n.getConfig(),status:n.getStatus(),tools:n.getTools(),resources:n.getResources(),prompts:n.getPrompts(),capabilities:n.getCapabilities()??void 0,error:n.getStatus()===`error`?`Connection failed`:void 0});for(let t of this.disabledServers)this.clients.has(t)||e.push({name:t,status:`disconnected`,tools:[]});return e}get connectedCount(){let e=0;for(let t of this.clients.values())t.getStatus()===`ready`&&e++;return e}get toolCount(){let e=0;for(let t of this.clients.values())t.getStatus()===`ready`&&(e+=t.getTools().length);return e}};function Q(e){return e.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)(?::-([^}]*))?\}/g,(e,t,n)=>{let r=process.env[t];return r!==void 0&&r!==``?r:n??``})}function Me(e){if(Array.isArray(e))return e.filter(e=>typeof e==`string`).map(Q)}function $(e){if(!e||typeof e!=`object`)return;let t={};for(let[n,r]of Object.entries(e))typeof r==`string`&&(t[n]=Q(r));return Object.keys(t).length>0?t:void 0}function Ne(e){if(!e||typeof e!=`object`)return null;let t=e,n={};typeof t.type==`string`&&(n.type=t.type),typeof t.command==`string`&&(n.command=Q(t.command));let r=Me(t.args);r&&(n.args=r);let i=$(t.env);i&&(n.env=i),typeof t.url==`string`&&(n.url=Q(t.url));let a=$(t.headers);return a&&(n.headers=a),typeof t.managed==`boolean`&&(n.managed=t.managed),!n.command&&!n.url?null:n}function Pe(e){let t=v(le(e),`.mcp.json`);if(!de(t))return{};let n;try{n=JSON.parse(fe(t,`utf-8`))}catch{return{}}let r=n,i=r?.mcp_servers??r?.mcpServers;if(!i||typeof i!=`object`)return{};let a={};for(let[e,t]of Object.entries(i)){let n=Ne(t);n&&(a[e]=n)}return a}export{E as McpClient,je as McpManager,C as SseTransport,S as StdioTransport,w as StreamableHttpTransport,Te as acquireRefreshLock,K as createDefaultTokenStore,W as createFileTokenStore,D as createMcpClient,N as createMcpToolAdapter,P as createMcpToolAdapters,Ce as createMemoryTokenStore,G as createOverlayTokenStore,y as createSseDataParser,Oe as createTokenProvider,R as discoverOAuth,B as exchangeCode,L as fetchAuthorizationServerMetadata,I as fetchProtectedResourceMetadata,U as isTokenExpired,O as jsonSchemaPropertyToZod,X as login,M as mcpContentToToolContent,k as mcpSchemaToZod,Pe as parseDotMcpJson,F as parseWwwAuthenticate,V as refreshAccessToken,Y as refreshWithCrossProcessLock,z as registerClient,Ee as releaseRefreshLock,x as validateMcpUrl,De as waitForRefreshLockRelease};
1
+ import{spawn as e}from"node:child_process";import{API_IMAGE_DIMENSION_LIMIT_PX as t,McpError as n,OAuthError as r,PROVIDER_IMAGE_INLINE_MAX_BYTES as i,TypedEventEmitter as a,buildAllowedEnv as o,createLogger as s,createPkcePair as c,generateState as l,probeImageDimensions as u,startLoopbackServer as d,traceStartupPhase as f}from"@x-otto/shared";import{z as p}from"zod";import{REFRESH_LOCK_TIMEOUT_MS as m,createOverlayStore as h,createRefreshLock as g,deleteFileIfExists as _,ensurePrivateDir as ee,isExpiredAt as te,readJsonFile as ne,refreshUnderCrossProcessLock as re,writeJsonAtomic as ie}from"@x-otto/credentials";import{createHash as ae}from"node:crypto";import{readFile as oe,readdir as se}from"node:fs/promises";import{homedir as ce}from"node:os";import{join as v,resolve as le}from"node:path";import{isShadowModeEnabled as ue}from"@x-otto/env";import{existsSync as de,readFileSync as fe}from"node:fs";function y(e){let t=``,n=[],r=``,i=()=>{if(n.length===0){r=``;return}let t=n.join(`
2
+ `),i=r||`message`;n=[],r=``,e(t,i)},a=e=>{let t=e.endsWith(`\r`)?e.slice(0,-1):e;if(t===``){i();return}if(!t.startsWith(`:`)){if(t.startsWith(`data:`)){let e=t.slice(5);e.startsWith(` `)&&(e=e.slice(1)),n.push(e);return}if(t.startsWith(`event:`)){let e=t.slice(6);e.startsWith(` `)&&(e=e.slice(1)),r=e}}};return{feed(e){t+=e;let n=t.split(`
3
+ `);t=n.pop()??``;for(let e of n)a(e)},flush(){t.length>0&&(a(t),t=``),i()}}}function b(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=e;if(t.jsonrpc!==`2.0`)return!1;if(`id`in t&&t.id!==void 0){let e=t.id;return typeof e!=`number`&&typeof e!=`string`&&e!==null?!1:`result`in t||`error`in t||typeof t.method==`string`}return typeof t.method==`string`}const x=s(`@x-otto/mcp:transport`),pe=3e4,me=32*1024*1024,S=-32e3,C=-32002;function w(e,t=200){let n=e.replace(/\s+/g,` `).trim();return n.length>t?`${n.slice(0,t)}…`:n}function he(e){let t=[],n=e;for(;;){let e=n.indexOf(10);if(e===-1){n.length>me&&(x.warn(`MCP newline frame exceeds limit without terminator; resetting buffer`),n=Buffer.alloc(0));break}let r=n.subarray(0,e);r.length>0&&r[r.length-1]===13&&(r=r.subarray(0,r.length-1)),n=n.subarray(e+1);let i=r.toString(`utf-8`).trim();i&&t.push(i)}return{bodies:t,rest:n}}function T(e){let t;try{t=new URL(e)}catch{throw Error(`Invalid MCP server URL: ${e}`)}if(t.protocol!==`http:`&&t.protocol!==`https:`)throw Error(`Unsupported MCP server URL protocol: ${t.protocol} (use http/https)`);return t}var E=class{managedProcess=null;messageHandler=null;closeHandler=null;closing=!1;buffer=Buffer.alloc(0);command;args;env;processSpawnFactory;constructor(e,t=[],n={},r){this.command=e,this.args=t,this.env=n,this.processSpawnFactory=r}async start(){if(this.processSpawnFactory)this.managedProcess=this.processSpawnFactory(this.command,this.args,this.env);else{let t=e(this.command,this.args,{stdio:[`pipe`,`pipe`,`pipe`],env:o(this.env),detached:!0});this.managedProcess={pid:t.pid,stdin:t.stdin,stdout:t.stdout,stderr:t.stderr,kill:async()=>(t.stdin?.end(),new Promise(e=>{let n=setTimeout(()=>{t.kill(`SIGKILL`),e()},2e3);t.on(`exit`,()=>{clearTimeout(n),e()}),t.kill(`SIGTERM`)})),onError:e=>{t.on(`error`,e)},onExit:e=>{t.on(`exit`,()=>e())}}}let t=this.managedProcess,n=t.stdout;n&&n.on(`data`,e=>{this.pushChunk(Buffer.isBuffer(e)?e:Buffer.from(e))});let r=t.stderr;r&&r.on(`data`,e=>{let t=Buffer.isBuffer(e)?e.toString(`utf-8`).trimEnd():String(e).trimEnd();x.debug(`MCP stderr: %s`,t)}),t.onError(e=>{x.error(`MCP process error: %s`,e.message)}),t.onExit(()=>{x.debug(`MCP process exited`),this.closing||this.closeHandler?.(`process exited`),this.managedProcess=null})}send(e){let t=this.managedProcess?.stdin;if(!t?.writable)throw Error(`MCP stdio transport is not connected`);let n=JSON.stringify(e);t.write(n+`
4
+ `)}onMessage(e){this.messageHandler=e}onClose(e){this.closeHandler=e}async close(){this.closing=!0,this.managedProcess&&=(await this.managedProcess.kill(),null)}pushChunk(e){if(e.length===0)return;let t=e.lastIndexOf(10);if(t===-1){if(this.buffer.length+e.length>me){x.warn(`MCP newline frame exceeds limit without terminator; resetting buffer`),this.buffer=Buffer.alloc(0);return}this.buffer=this.buffer.length===0?e:Buffer.concat([this.buffer,e]);return}let{bodies:n,rest:r}=he(this.buffer.length===0?e.subarray(0,t+1):Buffer.concat([this.buffer,e.subarray(0,t+1)])),i=e.subarray(t+1);r.length>0&&i.length>0?this.buffer=Buffer.concat([r,i]):r.length>0?this.buffer=r:this.buffer=i;for(let e of n)try{let t=JSON.parse(e);this.messageHandler?.(t)}catch(e){x.warn(`Failed to parse MCP message: %s`,e.message)}}},D=class{messageHandler=null;closeHandler=null;abortController=null;sessionId=null;closing=!1;baseUrl;fetchImpl;requestTimeoutMs;headers;getAuthToken;messageEndpoint=null;endpointWaiters=[];endpointSettled=!1;hasPendingRequests;constructor(e,t={}){this.baseUrl=T(e).href,this.fetchImpl=t.fetchImpl??globalThis.fetch,this.requestTimeoutMs=t.requestTimeoutMs??pe,this.headers=t.headers??{},this.getAuthToken=t.getAuthToken}get postUrl(){return this.messageEndpoint??this.baseUrl}setMessageEndpoint(e){let t=e.trim();if(!t)return;let n;try{n=new URL(t,this.baseUrl)}catch{x.warn(`MCP SSE endpoint event carried an unparsable URI: %s`,w(t));return}if(n.protocol!==`http:`&&n.protocol!==`https:`){x.warn(`MCP SSE endpoint event used unsupported protocol: %s`,n.protocol);return}this.messageEndpoint=n.href,x.debug(`MCP SSE message endpoint set to %s`,n.href),this.settleEndpoint()}settleEndpoint(){this.endpointSettled=!0;let e=this.endpointWaiters;this.endpointWaiters=[];for(let t of e)t()}async awaitMessageEndpoint(){if(this.messageEndpoint||this.endpointSettled||this.closing||!this.abortController)return;let e=Math.min(this.requestTimeoutMs,200);await new Promise(t=>{let n=setTimeout(()=>{this.settleEndpoint(),t()},e);n.unref?.(),this.endpointWaiters.push(()=>{clearTimeout(n),t()})})}async resolveHeaders(...e){let t={...this.headers};if(this.getAuthToken){let e=await this.getAuthToken();e&&(t={...t,Authorization:`Bearer ${e}`})}for(let n of e)t={...t,...n};return t}async fetchWithAuthRetry(e,t,n){let r=e===`GET`?{Accept:`text/event-stream`}:{"Content-Type":`application/json`,...this.sessionId?{"Mcp-Session-Id":this.sessionId}:{}},i=e===`GET`?this.baseUrl:this.postUrl,a=await this.resolveHeaders(r),o=await this.fetchImpl(i,{method:e,headers:a,body:t,signal:n});if(o.status===401&&this.getAuthToken){if(x.debug(`MCP 401 on %s %s — attempting token refresh and retry`,e,i),await this.getAuthToken()){let a=await this.resolveHeaders(r);return this.fetchImpl(i,{method:e,headers:a,body:t,signal:n})}x.warn(`MCP token refresh returned no token for %s`,i)}return o}async start(){this.closing=!1,this.messageEndpoint=null,this.endpointWaiters=[],this.endpointSettled=!1,this.abortController=new AbortController;let e=await this.fetchWithAuthRetry(`GET`,void 0,this.abortController.signal);if(!e.ok)throw e.status===401?new n(`MCP server '${this.baseUrl}' requires authentication.`,{code:`MCP_UNAUTHORIZED`}):Error(`MCP SSE connection failed: ${e.status} ${e.statusText}`);let t=e.headers.get(`mcp-session-id`);t&&(this.sessionId=t),this.consumeStream(e,!0)}async send(e){let t=new AbortController,n=setTimeout(()=>{t.abort(new DOMException(`MCP request timeout`,`TimeoutError`))},this.requestTimeoutMs);n.unref?.();let r=this.abortController?AbortSignal.any([this.abortController.signal,t.signal]):t.signal;await this.awaitMessageEndpoint(),this.fetchWithAuthRetry(`POST`,JSON.stringify(e),r).then(async t=>{if(clearTimeout(n),!t.ok){if(t.status===401){x.warn(`MCP SSE POST 401: authentication required for %s`,this.baseUrl),this.failRequest(e,-32001,`MCP server requires authentication.`);return}x.warn(`MCP SSE POST failed: %s`,t.status),this.failRequest(e,S,`MCP SSE POST failed: HTTP ${t.status}`);return}let r=t.headers.get(`mcp-session-id`);r&&(this.sessionId=r);let i=t.headers.get(`content-type`)??``;if(i.includes(`application/json`)){let n=await t.text();if(!n.trim())return;let r;try{r=JSON.parse(n)}catch{x.warn(`MCP SSE POST returned a non-JSON body: %s`,w(n)),this.failRequest(e,C,`MCP server returned a non-JSON body: ${w(n)}`);return}let i=Array.isArray(r)?r:[r];if(i.some(e=>!b(e))){x.warn(`MCP SSE POST returned a non-JSON-RPC payload: %s`,w(n)),this.failRequest(e,C,`MCP server returned a non-JSON-RPC payload: ${w(n)}`);return}for(let e of i)this.messageHandler?.(e)}else i.includes(`text/event-stream`)&&this.consumeStream(t,!1)}).catch(t=>{clearTimeout(n),t.name!==`AbortError`&&(x.warn(`MCP SSE send error: %s`,t.message),this.failRequest(e,S,`MCP SSE send error: ${t.message}`))})}failRequest(e,t,n){`id`in e&&e.id!==void 0&&e.id!==null&&this.messageHandler?.({jsonrpc:`2.0`,id:e.id,error:{code:t,message:n}})}onMessage(e){this.messageHandler=e}onClose(e){this.closeHandler=e}setPendingProbe(e){this.hasPendingRequests=e}async close(){this.closing=!0,this.settleEndpoint(),this.abortController?.abort(),this.abortController=null}async consumeStream(e,t){let n=e.body?.getReader();if(!n){t&&this.settleEndpoint(),t&&!this.closing&&this.closeHandler?.(`SSE stream had no readable body`);return}let r=new TextDecoder,i=0,a=``,o=0,s=null,c=()=>{s&&=(clearTimeout(s),null)},l=()=>{if(!t||s||o>0||!this.hasPendingRequests)return;let e=Math.min(Math.max(this.requestTimeoutMs/4,250),2e3),n=Date.now()+this.requestTimeoutMs,r=()=>{if(s=null,!(o>0||this.closing)){if(!this.hasPendingRequests?.()){if(Date.now()>=n)return;s=setTimeout(r,e),s.unref?.();return}x.warn(`MCP SSE stream produced %d unusable frame(s) and no valid MCP message; treating as protocol failure`,i),this.closeHandler?.(`SSE stream carried ${i} unusable frame(s) and no valid MCP message; first: ${a}`)}};s=setTimeout(r,e),s.unref?.()},u=y((e,t)=>{let n=e.trim();if(!n||n===`[DONE]`)return;if(t===`endpoint`){this.setMessageEndpoint(n);return}let r;try{r=JSON.parse(n)}catch{i++,a||=w(n),x.warn(`MCP SSE non-JSON frame ignored: %s`,w(n)),l();return}if(!b(r)){i++,a||=w(n),x.warn(`MCP SSE non-JSON-RPC frame ignored: %s`,w(n)),l();return}o++,c(),this.messageHandler?.(r)});try{for(;;){let{done:e,value:t}=await n.read();if(e)break;u.feed(r.decode(t,{stream:!0}))}u.flush(),t&&!this.closing&&this.closeHandler?.(i>0?`SSE stream ended after ${i} unusable frame(s); first: ${a}`:`SSE stream ended`)}catch(e){e.name!==`AbortError`&&(x.warn(`MCP SSE stream error: %s`,e.message),t&&!this.closing&&this.closeHandler?.(`SSE stream error: ${e.message}`))}finally{c(),t&&this.settleEndpoint(),n.releaseLock()}}},O=class{messageHandler=null;closeHandler=null;abortController=null;sessionId=null;closing=!1;baseUrl;fetchImpl;requestTimeoutMs;headers;getAuthToken;constructor(e,t={}){this.baseUrl=T(e).href,this.fetchImpl=t.fetchImpl??globalThis.fetch,this.requestTimeoutMs=t.requestTimeoutMs??pe,this.headers=t.headers??{},this.getAuthToken=t.getAuthToken}async resolveHeaders(...e){let t={...this.headers};if(this.getAuthToken){let e=await this.getAuthToken();e&&(t={...t,Authorization:`Bearer ${e}`})}for(let n of e)t={...t,...n};return t}async start(){this.closing=!1,this.abortController=new AbortController}async send(e){let t=new AbortController,n=setTimeout(()=>{t.abort(new DOMException(`MCP request timeout`,`TimeoutError`))},this.requestTimeoutMs);n.unref?.();let r=this.abortController?AbortSignal.any([this.abortController.signal,t.signal]):t.signal,i={"Content-Type":`application/json`,Accept:`application/json, text/event-stream`,...this.sessionId?{"Mcp-Session-Id":this.sessionId}:{}},a=JSON.stringify(e),o;try{o=await this.fetchImpl(this.baseUrl,{method:`POST`,headers:await this.resolveHeaders(i),body:a,signal:r}),o.status===401&&this.getAuthToken&&await this.getAuthToken()&&(o=await this.fetchImpl(this.baseUrl,{method:`POST`,headers:await this.resolveHeaders(i),body:a,signal:r}))}catch(e){clearTimeout(n),e.name!==`AbortError`&&!this.closing&&this.closeHandler?.(`HTTP POST failed: ${e.message}`);return}let s=o.headers.get(`mcp-session-id`);if(s&&(this.sessionId=s),!o.ok){if(clearTimeout(n),o.status===401){this.closing||this.closeHandler?.(`unauthorized`);return}o.status!==202&&!this.closing&&this.closeHandler?.(`HTTP ${o.status} ${o.statusText}`);return}if((o.headers.get(`content-type`)??``).toLowerCase().includes(`text/event-stream`)){await this.consumeSseResponse(o,e),clearTimeout(n);return}clearTimeout(n);let c=await o.text();if(!c.trim())return;let l;try{l=JSON.parse(c)}catch(t){x.warn(`MCP streamable-http non-JSON response body: %s`,t.message),this.failRequest(e,C,`MCP server returned a non-JSON body: ${w(c)}`);return}let u=Array.isArray(l)?l:[l],d=u.filter(e=>!b(e));if(d.length>0){x.warn(`MCP streamable-http response is not a JSON-RPC message (%d frame(s)): %s`,d.length,w(c)),this.failRequest(e,C,`MCP server returned a non-JSON-RPC payload: ${w(c)}`);return}for(let e of u)this.messageHandler?.(e)}failRequest(e,t,n){`id`in e&&e.id!==void 0&&e.id!==null&&this.messageHandler?.({jsonrpc:`2.0`,id:e.id,error:{code:t,message:n}})}async consumeSseResponse(e,t){let n=e.body?.getReader();if(!n)return;let r=new TextDecoder,i=0,a=``,o=`id`in t?t.id:void 0,s=o==null,c=y(e=>{let t=e.trim();if(!t||t===`[DONE]`)return;let n;try{n=JSON.parse(t)}catch{i++,a||=w(t),x.warn(`MCP streamable-http non-JSON SSE frame: %s`,w(t));return}if(!b(n)){i++,a||=w(t),x.warn(`MCP streamable-http non-JSON-RPC SSE frame: %s`,w(t));return}let r=n.id;!s&&r!==void 0&&r===o&&(s=!0),this.messageHandler?.(n)});try{for(;;){let{done:e,value:t}=await n.read();if(e)break;c.feed(r.decode(t,{stream:!0}))}c.flush(),s||this.failRequest(t,i>0?C:S,i>0?`MCP stream ended after ${i} unusable frame(s) without a response; first: ${a}`:`MCP stream ended without a response to this request`)}catch(e){e.name!==`AbortError`&&(x.warn(`MCP streamable-http stream error: %s`,e.message),this.failRequest(t,S,`MCP stream error: ${e.message}`))}finally{n.releaseLock()}}onMessage(e){this.messageHandler=e}onClose(e){this.closeHandler=e}async close(){this.closing=!0,this.abortController?.abort(),this.abortController=null}};const k=s(`@x-otto/mcp:client`);var A=class{serverName;transport=null;config;options;status=`disconnected`;serverInfo=null;capabilities=null;tools=[];resources=[];prompts=[];nextRequestId=1;pending=new Map;closing=!1;reconnectAttempts=0;reconnectTimer=null;toolsChangedCallback=null;resourcesChangedCallback=null;disconnectedCallback=null;notificationCallback=null;constructor(e,t,n={}){this.serverName=e,this.config=t,this.options=n}getStatus(){return this.status}getConfig(){return this.config}getTools(){return this.tools}getResources(){return this.resources}getPrompts(){return this.prompts}getCapabilities(){return this.capabilities}getServerInfo(){return this.serverInfo}onToolsChanged(e){this.toolsChangedCallback=e}onResourcesChanged(e){this.resourcesChangedCallback=e}onDisconnected(e){this.disconnectedCallback=e}onNotification(e){this.notificationCallback=e}async connect(){if(this.status!==`ready`){this.closing=!1,this.status=`connecting`;try{await this.establishWithTimeout(),this.reconnectAttempts=0,this.status=`ready`}catch(e){this.status=`error`;let t=e instanceof Error?e.message:String(e);k.error(`MCP server "%s" connection failed: %s`,this.serverName,t);let r=e instanceof n&&(e.code===`MCP_UNAUTHORIZED`||e.code===`MCP_CONNECT_TIMEOUT`)?e.code:`MCP_CONNECT_ERROR`;throw new n(`Failed to connect to MCP server "${this.serverName}": ${t}`,{code:r,cause:e instanceof Error?e:void 0})}}}async establishWithTimeout(){let e=this.options.connectTimeoutMs??1e4;if(!e||e<=0){await this.establish();return}let t,r=new Promise((r,i)=>{t=setTimeout(()=>{i(new n(`MCP server "${this.serverName}" did not finish connecting within ${e}ms`,{code:`MCP_CONNECT_TIMEOUT`}))},e),t.unref?.()});try{await Promise.race([this.establish(),r])}catch(e){let t=this.transport;throw t&&(this.transport=null,await t.close().catch(()=>void 0)),this.failPending(e instanceof Error?e:Error(String(e))),e}finally{clearTimeout(t)}}async establish(){let e=this.createTransport();this.transport=e,e.setPendingProbe?.(()=>this.hasStalePending()),e.onMessage(e=>this.handleMessage(e)),e.onClose(t=>{this.transport===e&&this.handleTransportClose(t)});try{await e.start(),this.serverInfo=await this.request(`initialize`,{protocolVersion:`2024-11-05`,capabilities:{roots:{listChanged:!1}},clientInfo:{name:`otto-coding`,version:`0.0.1`}}),this.capabilities=this.serverInfo.capabilities,this.notify(`notifications/initialized`),k.info(`MCP server "%s" connected: %s (protocol %s)`,this.serverName,this.serverInfo.serverInfo.name,this.serverInfo.protocolVersion),await this.refreshTools(),this.capabilities?.resources&&await this.refreshResources(),this.capabilities?.prompts&&await this.refreshPrompts()}catch(t){throw this.transport===e&&(this.transport=null),await e.close().catch(()=>void 0),t}}handleTransportClose(e){if(this.closing||(this.failPending(new n(`MCP transport closed: ${e??`unknown`}`,{code:`MCP_DISCONNECTED`})),this.status===`connecting`))return;let t=this.options.autoReconnect??!0,r=this.options.maxReconnectAttempts??3;if(!t||this.reconnectAttempts>=r){this.status=`disconnected`,this.transport=null,this.disconnectedCallback?.({reason:e,kind:`crash`});return}this.scheduleReconnect()}scheduleReconnect(){this.reconnectAttempts++,this.status=`reconnecting`;let e=(this.options.reconnectDelayMs??500)*2**(this.reconnectAttempts-1);k.info(`MCP server "%s" reconnecting (attempt %d) in %dms`,this.serverName,this.reconnectAttempts,e),this.reconnectTimer=setTimeout(()=>{this.attemptReconnect()},e)}async attemptReconnect(){if(!this.closing)try{this.transport&&await this.transport.close().catch(()=>void 0),this.transport=null,await this.establishWithTimeout(),this.reconnectAttempts=0,this.status=`ready`,k.info(`MCP server "%s" reconnected`,this.serverName)}catch(e){k.warn(`MCP server "%s" reconnect attempt %d failed: %s`,this.serverName,this.reconnectAttempts,e.message);let t=this.options.maxReconnectAttempts??3;this.reconnectAttempts>=t?(this.status=`error`,this.transport=null,this.disconnectedCallback?.({reason:`reconnect failed after ${t} attempts`,kind:`crash`})):this.scheduleReconnect()}}hasStalePending(){let e=Date.now();for(let t of this.pending.values())if(e-t.sentAt>=1500)return!0;return!1}failPending(e){for(let[t,n]of this.pending)clearTimeout(n.timer),n.reject(e),this.pending.delete(t)}async refreshTools(){return this.tools=(await this.request(`tools/list`)).tools??[],k.debug(`MCP server "%s" provides %d tools: %s`,this.serverName,this.tools.length,this.tools.map(e=>e.name).join(`, `)),this.tools}async refreshResources(){try{this.resources=(await this.request(`resources/list`)).resources??[],k.debug(`MCP server "%s" provides %d resources`,this.serverName,this.resources.length)}catch(e){k.debug(`MCP server "%s" resources/list failed: %s`,this.serverName,e.message),this.resources=[]}return this.resources}async readResource(e){return(await this.request(`resources/read`,{uri:e})).contents??[]}async refreshPrompts(){try{this.prompts=(await this.request(`prompts/list`)).prompts??[],k.debug(`MCP server "%s" provides %d prompts`,this.serverName,this.prompts.length)}catch(e){k.debug(`MCP server "%s" prompts/list failed: %s`,this.serverName,e.message),this.prompts=[]}return this.prompts}async getPrompt(e,t){return await this.request(`prompts/get`,{name:e,arguments:t})}async callTool(e,t){if(this.status!==`ready`)throw new n(`MCP server "${this.serverName}" is not ready (status: ${this.status})`,{code:`MCP_NOT_READY`});return await this.request(`tools/call`,e,t)}async callRaw(e,t,n){return this.request(e,t,n)}async disconnect(){if(this.closing=!0,this.reconnectTimer&&=(clearTimeout(this.reconnectTimer),null),this.transport){try{await this.transport.close()}catch(e){k.debug(`Error closing MCP transport: %s`,e.message)}this.transport=null}this.failPending(new n(`MCP client disconnected`,{code:`MCP_DISCONNECTED`})),this.status=`disconnected`,this.tools=[],this.resources=[],this.prompts=[],this.serverInfo=null,this.capabilities=null,this.disconnectedCallback?.({reason:`client disconnect`,kind:`manual`})}createTransport(){if(this.options.transportFactory)return this.options.transportFactory();let{type:e,url:t,command:r}=this.config,i=e===`http`||e===void 0&&t!==void 0,a=e===`sse`,o=e===`stdio`||e===void 0&&r!==void 0;if(i||a){if(!t)throw new n(`MCP server "${this.serverName}" transport '${e}' requires a url`,{code:`MCP_CONFIG_ERROR`});let r={requestTimeoutMs:this.config.requestTimeoutMs??this.options.requestTimeoutMs,headers:this.config.headers,getAuthToken:this.options.getAuthToken};return a?new D(t,r):new O(t,r)}if(o){if(!r)throw new n(`MCP server "${this.serverName}" transport 'stdio' requires a command`,{code:`MCP_CONFIG_ERROR`});return new E(r,this.config.args??[],this.config.env??{},this.options.processSpawnFactory)}throw new n(`MCP server "${this.serverName}" has no command or url configured`,{code:`MCP_CONFIG_ERROR`})}request(e,t,r){return new Promise((i,a)=>{if(r?.aborted){a(new n(`MCP request "${e}" aborted`,{code:`MCP_ABORTED`}));return}let o=this.nextRequestId++,s=this.config.requestTimeoutMs??this.options.requestTimeoutMs??3e4,c,l=()=>{c&&r&&r.removeEventListener(`abort`,c)},u=setTimeout(()=>{this.pending.delete(o),l(),a(new n(`MCP request "${e}" timed out after ${s}ms`,{code:`MCP_TIMEOUT`}))},s);this.pending.set(o,{sentAt:Date.now(),resolve:e=>{l(),i(e)},reject:e=>{l(),a(e)},timer:u}),r&&(c=()=>{let t=this.pending.get(o);t&&(clearTimeout(t.timer),this.pending.delete(o),l(),a(new n(`MCP request "${e}" aborted`,{code:`MCP_ABORTED`})))},r.addEventListener(`abort`,c,{once:!0}));let d={jsonrpc:`2.0`,id:o,method:e,...t!==void 0&&{params:t}};try{this.transport.send(d)}catch(e){clearTimeout(u),this.pending.delete(o),l(),a(e)}})}notify(e,t){let n={jsonrpc:`2.0`,method:e,...t!==void 0&&{params:t}};try{this.transport.send(n)}catch(t){k.debug(`Failed to send MCP notification "%s": %s`,e,t.message)}}handleMessage(e){if(!(`id`in e)||e.id===void 0){this.handleNotification(e);return}let t=e,r=this.pending.get(t.id);if(!r){k.debug(`Received response for unknown request id: %s`,t.id);return}clearTimeout(r.timer),this.pending.delete(t.id),t.error?r.reject(new n(`MCP error: ${t.error.message} (code: ${t.error.code})`,{code:`MCP_SERVER_ERROR`})):r.resolve(t.result)}handleNotification(e){switch(e.method){case`notifications/tools/list_changed`:k.info(`MCP server "%s" notified tools list changed`,this.serverName),this.refreshTools().then(()=>{this.toolsChangedCallback?.()});break;case`notifications/resources/list_changed`:k.info(`MCP server "%s" notified resources list changed`,this.serverName),this.refreshResources().then(()=>{this.resourcesChangedCallback?.()});break;default:k.debug(`MCP notification: %s`,e.method)}this.notificationCallback?.(e.method,e.params)}};function j(e,t,n){return new A(e,t,n)}const ge=s(`@x-otto/mcp:adapter`);function _e(e){if(e.length===0)return null;if(e.every(e=>typeof e==`string`))return p.enum(e);let t=e.filter(e=>{let t=typeof e;return t===`string`||t===`number`||t===`boolean`}).map(e=>p.literal(e));return t.length===0?null:t.length===1?t[0]:p.union(t)}function M(e){if(e.oneOf&&Array.isArray(e.oneOf)&&e.oneOf.length>0){let t=e.oneOf.map(e=>M(e));return e.description?p.union(t).describe(e.description):p.union(t)}if(e.anyOf&&Array.isArray(e.anyOf)&&e.anyOf.length>0){let t=e.anyOf.map(e=>M(e));return e.description?p.union(t).describe(e.description):p.union(t)}if(e.allOf&&Array.isArray(e.allOf)&&e.allOf.length>0)return console.warn(`[mcp-tool-adapter] allOf schema degraded to last sub-schema (intersection unsupported)`),M(e.allOf[e.allOf.length-1]);if(typeof e.$ref==`string`){let t=ve(e.$ref,e);return t?M(t):(console.warn(`[mcp-tool-adapter] unresolvable $ref "${e.$ref}" degraded to z.unknown()`),p.unknown())}if(Array.isArray(e.enum)){let t=_e(e.enum);if(t)return e.description?t.describe(e.description):t}switch(e.type){case`string`:return e.description?p.string().describe(e.description):p.string();case`number`:case`integer`:{let t=e.type===`integer`?p.number().int():p.number(),n=p.preprocess(e=>typeof e==`string`?Number(e):e,t);return e.description?n.describe(e.description):n}case`boolean`:return e.description?p.boolean().describe(e.description):p.boolean();case`array`:{let t=e.items?M(e.items):p.unknown();return e.description?p.array(t).describe(e.description):p.array(t)}case`object`:if(e.properties){let t={},n=new Set(e.required??[]);for(let[r,i]of Object.entries(e.properties)){let e=M(i);t[r]=n.has(r)?e:e.optional()}return e.description?p.object(t).describe(e.description):p.object(t)}return e.description?p.record(p.string(),p.unknown()).describe(e.description):p.record(p.string(),p.unknown());default:return console.warn(`[mcp-tool-adapter] unsupported JSON schema type "${e.type}" degraded to z.unknown()`),p.unknown()}}function ve(e,t){let n=/^#\/(?:definitions|\$defs)\/([^/]+)$/.exec(e);if(!n)return;let r=n[1].replace(/~1/g,`/`).replace(/~0/g,`~`),i=t;return i.definitions?.[r]??i.$defs?.[r]}function N(e){let t=e.inputSchema.properties;if(!t||Object.keys(t).length===0)return p.object({});let n={},r=new Set(e.inputSchema.required??[]);for(let[e,i]of Object.entries(t)){let t=M(i);n[e]=r.has(e)?t:t.optional()}return p.object(n)}const P=i;function F(e){let t=e.endsWith(`==`)?2:e.endsWith(`=`)?1:0;return Math.max(0,Math.floor(e.length*3/4)-t)}function ye(e){if(e.text!==void 0)return{type:`text`,text:e.text};if(e.blob!==void 0){if(e.mimeType?.startsWith(`image/`)&&e.mimeType!==`image/svg+xml`){let n=F(e.blob);if(n>P)return{type:`text`,text:`[image omitted: ${n} bytes exceeds ${P} byte limit — ask the tool to capture a smaller region/resolution]`};let r=u(e.blob,e.mimeType);return r&&(r.width>t||r.height>t)?{type:`text`,text:`[image omitted: ${r.width}x${r.height}px exceeds Anthropic per-image dimension hard limit of ${t}px — ask the tool to capture a smaller region or lower resolution]`}:{type:`image`,mime:e.mimeType,source:`data:${e.mimeType};base64,${e.blob}`}}let n=e.mimeType?` (${e.mimeType})`:``;return{type:`text`,text:`[Resource: ${e.uri}${n}, ${F(e.blob)} bytes binary]`}}return{type:`text`,text:`[Resource: ${e.uri}]`}}function I(e){return e.map(e=>{switch(e.type){case`text`:return{type:`text`,text:e.text};case`image`:if(!e.data)return{type:`text`,text:`[image unavailable: no data]`};{let n=F(e.data);if(n>P)return{type:`text`,text:`[image omitted: ${n} bytes exceeds ${P} byte limit — ask the tool to capture a smaller region/resolution]`};let r=u(e.data,e.mimeType??``);if(r&&(r.width>t||r.height>t))return{type:`text`,text:`[image omitted: ${r.width}x${r.height}px exceeds Anthropic per-image dimension hard limit of ${t}px — ask the tool to capture a smaller region or lower resolution]`}}return{type:`image`,mime:e.mimeType,source:`data:${e.mimeType};base64,${e.data}`};case`resource`:return ye(e.resource);default:return{type:`text`,text:JSON.stringify(e)}}})}function be(e){let t=e.toLowerCase().replace(/[_\s-]/g,``);return[`source`,`destination`,`dest`,`src`,`cwd`,`location`].includes(t)?!0:t.includes(`path`)||t.includes(`file`)||t.includes(`dir`)||t.includes(`folder`)}function xe(e){let t=e.inputSchema.properties;if(!t)return[];let n=[];for(let[e,r]of Object.entries(t)){let t=r.type;(t===`string`||t===void 0)&&be(e)&&n.push(e)}return n}function L(e,t,n){let r=`mcp__${n}__${t.name}`,i=t.description?`[MCP: ${n}] ${t.description}`:`[MCP: ${n}] ${t.name}`,a=N(t),o=xe(t),s=t.annotations?.readOnlyHint===!0;return{name:r,description:i,parameters:a,...o.length>0?{pathParams:o}:{},...s?{readonly:!0}:{},exposure:`deferred`,async execute({params:r,signal:i}){ge.debug(`Calling MCP tool %s on server %s`,t.name,n);let a=await e.callTool({name:t.name,arguments:r},i),o=I(a.content);return{content:o.length>0?o:[{type:`text`,text:`(empty result)`}],isError:a.isError??!1,details:{mcpServer:n,mcpTool:t.name}}}}}function R(e,t){return e.getTools().map(n=>L(e,n,t))}function z(e){let t=e.split(`,`).map(e=>e.trim()).find(e=>e.toLowerCase().startsWith(`bearer `)||e.toLowerCase()===`bearer`);if(t)return t.match(/metadata_url\s*=\s*"([^"]+)"/i)?.[1]}async function B(e,t=fetch){let n=await t(e,{headers:{Accept:`application/json`}});if(!n.ok)throw Error(`Failed to fetch protected resource metadata from ${e}: ${n.status}`);return await n.json()}async function Se(e,t=fetch){let n=`${e.replace(/\/$/,``)}/.well-known/oauth-authorization-server`,r=`${e.replace(/\/$/,``)}/.well-known/openid-configuration`,i=async e=>{let n=await t(e,{headers:{Accept:`application/json`}});if(!n.ok)throw Error(`Metadata fetch failed: ${e} → ${n.status}`);return await n.json()};try{return await i(n)}catch{return i(r)}}async function V(e,t={}){let n=t.fetch??fetch,r=z(t.wwwAuthenticate??``)??`${e.replace(/\/$/,``)}/.well-known/oauth-protected-resource`,i=await B(r,n),a=i.authorization_servers?.[0]??new URL(r).origin;return{protectedResource:i,authorizationServer:await Se(a,n),issuer:a}}async function H(e,t,n={}){let r=n.fetch??fetch,i={"Content-Type":`application/json`,Accept:`application/json`};n.initialAccessToken&&(i.Authorization=`Bearer ${n.initialAccessToken}`);let a=await r(e,{method:`POST`,headers:i,body:JSON.stringify({client_name:t.client_name??`otto MCP Client`,redirect_uris:t.redirect_uris,grant_types:t.grant_types??[`authorization_code`,`refresh_token`],token_endpoint_auth_method:t.token_endpoint_auth_method??`none`})});if(!a.ok){let t=await a.text().catch(()=>``);throw Error(`DCR registration failed at ${e}: ${a.status}${t?` — ${t}`:``}`)}return await a.json()}async function U(e,t,n={}){let i=n.fetch??fetch,a=new URLSearchParams({grant_type:`authorization_code`,code:t.code,redirect_uri:t.redirectUri,code_verifier:t.codeVerifier,client_id:t.clientId});t.resource&&a.set(`resource`,t.resource);let o=await i(e,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`,Accept:`application/json`},body:a.toString()});if(!o.ok){let e=await o.text().catch(()=>``);throw new r(`Token exchange failed: ${o.status}${e?` — ${e}`:``}`,{code:`OAUTH_TOKEN_EXCHANGE_FAILED`})}return G(await o.json())}async function W(e,t,n={}){let i=n.fetch??fetch,a=new URLSearchParams({grant_type:`refresh_token`,refresh_token:t.refreshToken});t.clientId&&a.set(`client_id`,t.clientId),t.resource&&a.set(`resource`,t.resource);let o=await i(e,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`,Accept:`application/json`},body:a.toString()});if(!o.ok){let e=await o.text().catch(()=>``),t=Ce(e);throw new r(`Token refresh failed: ${o.status}${e?` — ${e}`:``}`,{code:`OAUTH_REFRESH_FAILED`,...t?{errorType:t}:{}})}return G(await o.json(),t.refreshToken)}function G(e,t){return{accessToken:e.access_token,refreshToken:e.refresh_token??t,expiresAt:e.expires_in?(e.issued_at??Date.now())+e.expires_in*1e3:void 0,resource:e.resource}}function Ce(e){try{let t=JSON.parse(e);return typeof t.error==`string`?t.error:void 0}catch{return}}function K(e,t=60){return te(e.expiresAt,t*1e3)}function we(e={}){let t=e.baseDir??v(ce(),`.otto`,`mcp`,`credentials`),n=e=>v(t,`${J(e)}.json`);return{refreshLockDir:t,async load(e){return ne(n(e),void 0)},async save(e,r){await ee(t),await ie(n(e),{...r,serverName:e})},async delete(e){await _(n(e))},async list(){try{let e=await se(t),n=[];for(let r of e)if(r.endsWith(`.json`))try{let e=De(await oe(v(t,r),`utf-8`));n.push(e??r.slice(0,-5))}catch{n.push(r.slice(0,-5))}return n}catch(e){if(e?.code===`ENOENT`)return[];throw e}}}}function Te(){let e=new Map;return{async load(t){return e.get(t)},async save(t,n){e.set(t,n)},async delete(t){e.delete(t)},async list(){return[...e.keys()]}}}function Ee(e){let t=h(e);return{load:t.load,save:t.save,delete:t.delete,list:t.list,shadow:!0,refreshLockDir:void 0}}function q(e={}){let t=we(e);return ue()?Ee(t):t}function J(e){return`${e.replace(/[^a-zA-Z0-9._-]/g,`_`)}_${ae(`sha256`).update(e).digest(`hex`).slice(0,8)}`}function De(e){try{let t=JSON.parse(e);return typeof t.serverName==`string`?t.serverName:void 0}catch{return}}const Y=`mcp-refresh`;async function Oe(e,t,n=m){return g(e,Y).acquire(J(t),n)}async function ke(e,t){return g(e,Y).release(J(t))}async function Ae(e,t,n=m){return g(e,Y).waitForRelease(J(t),n)}async function X(e,t,n,r,i={},a,o){return re({lock:g(e,Y),key:J(t),load:a.load,isFresh:e=>!K(e),refresh:()=>W(n,r,i),save:a.save,strategy:o})}async function je(e){let{serverUrl:t,serverName:n,wwwAuthenticate:r,clientId:i,authorizationServer:a,tokenStore:o=q(),openBrowser:s=Pe,fetch:u=fetch,signal:f}=e;if(f?.aborted)throw Error(`Login cancelled`);let p=a??(await V(t,{wwwAuthenticate:r,fetch:u})).authorizationServer;if(!p.token_endpoint)throw Error(`Authorization server has no token_endpoint`);let m=c(),h=l(),g=await d({ports:[1455,1457,1459],expectedState:h,signal:f}),_=g.redirectUri;try{let e=i,r=!1;if(!e&&p.registration_endpoint&&(e=(await H(p.registration_endpoint,{redirect_uris:[_]},{fetch:u})).client_id,r=!0),!e)throw Error(`No client_id available. Configure client_id in MCP server settings or ensure the authorization server supports Dynamic Client Registration (registration_endpoint).`);let a=new URLSearchParams({response_type:`code`,client_id:e,redirect_uri:_,code_challenge:m.challenge,code_challenge_method:m.method,state:h});a.set(`resource`,t),await s(`${p.authorization_endpoint}?${a.toString()}`);let c=await g.waitForCallback(),l=await U(p.token_endpoint,{code:c.code,redirectUri:_,codeVerifier:m.verifier,resource:t,clientId:e},{fetch:u});return await o.save(n,{...l,clientId:e}),{credentials:l,registered:r,clientId:e}}finally{await g.close()}}function Me(e){let{serverName:t,serverUrl:n,tokenStore:r=q(),clientId:i,authorizationServer:o,fetch:s}=e,c,l=o??void 0,u=e=>i?{...e,clientId:i}:e,d=new a;return{async getAccessToken(){if(c||=await r.load(t),c){if(K(c)&&c.refreshToken){if(r.shadow)return;try{l||=(await V(n,{fetch:s})).authorizationServer;let e={refreshToken:c.refreshToken,resource:n,clientId:c.clientId??i},a=r.refreshLockDir;a?(c=await X(a,t,l.token_endpoint,e,{fetch:s},{load:()=>r.load(t),save:e=>r.save(t,u(e))},Ne(t,r,u)),c=u(c),d.emit(`credential.changed`,{serverName:t,source:`refresh`})):(c=await W(l.token_endpoint,e,{fetch:s}),c=u(c),await r.save(t,c),d.emit(`credential.changed`,{serverName:t,source:`refresh`}))}catch{return}}return c.accessToken}},async login(e){return c=(await je({...e,tokenStore:r,clientId:i,authorizationServer:l})).credentials,l??=e.authorizationServer,d.emit(`credential.changed`,{serverName:t,source:`self`}),c.accessToken},async logout(){c=void 0,l=void 0,await r.delete(t),d.emit(`credential.changed`,{serverName:t,source:`self`})},async describe(){let e=c??await r.load(t);return e?{configured:!0,source:`oauth`,expiringSoon:K(e),shadow:r.shadow}:{configured:!1,shadow:r.shadow}},on(e,t){return d.on(e,t),this}}}function Ne(e,t,n){let r=new Map;return{shouldFailFast(t){if(!t.refreshToken)return!1;let n=r.get(e);return!!n&&n.refreshToken===t.refreshToken},async recoverFromFailure(i){let a=await t.load(e);if(!(!a||!a.refreshToken)&&a.refreshToken!==i.refreshToken)return r.delete(e),n(a)},cacheFailure(t,n){t?.errorType===`invalid_grant`&&n.refreshToken&&r.set(e,{refreshToken:n.refreshToken,error:t})},onStep(t,n){process.env.OTTO_DEBUG&&t&&console.debug(`[mcp:refresh] ${e} ${t}${n?`: ${n}`:``}`)}}}async function Pe(t){let n=process.platform===`win32`,r=n?`cmd`:process.platform===`darwin`?`open`:`xdg-open`,i=n?[`/c`,`start`,``,t]:[t];return new Promise((t,n)=>{let a=e(r,i,{stdio:`ignore`,detached:!0});a.on(`error`,e=>{n(Error(`Failed to open browser: ${e.message}`))}),a.on(`close`,e=>{e===0||e===null?t():n(Error(`Browser command exited with code ${e}`))}),a.unref()})}const Z=s(`@x-otto/mcp:manager`);var Fe=class extends a{clients=new Map;options;disabledServers;constructor(e={},t=[]){super(),this.options=e,this.disabledServers=new Set(t)}async connectAll(e){let t=Object.entries(e);if(t.length===0)return{connected:0,failed:0};Z.info(`Connecting to %d MCP servers...`,t.length);let n=await Promise.allSettled(t.map(([e,t])=>f(`mcp:${e} connect`,()=>this.connect(e,t)))),r=0,i=0;for(let[e,a]of n.entries()){let n=t[e][0];if(this.disabledServers.has(n))continue;let o=this.clients.get(n);a.status===`fulfilled`&&o?.getStatus()===`ready`?r++:i++}return Z.info(`MCP servers: %d connected, %d failed`,r,i),{connected:r,failed:i}}async connect(e,t){if(this.disabledServers.has(e)){Z.info(`MCP server "%s" is disabled, skipping`,e);return}this.clients.has(e)&&await this.disconnect(e);let r;if(t.url&&t.type!==`stdio`){let n=q(),i=await n.load(e);if(i){let a=Me({serverName:e,serverUrl:t.url,tokenStore:n,clientId:i.clientId});r=()=>a.getAccessToken()}}let i=j(e,t,{requestTimeoutMs:t.requestTimeoutMs??this.options.requestTimeoutMs,autoReconnect:t.autoReconnect??this.options.autoReconnect,maxReconnectAttempts:t.maxReconnectAttempts??this.options.maxReconnectAttempts,reconnectDelayMs:this.options.reconnectDelayMs,connectTimeoutMs:this.options.connectTimeoutMs,getAuthToken:r,processSpawnFactory:this.options.processSpawnFactory,transportFactory:this.options.transportFactory});i.onToolsChanged(()=>{Z.info(`MCP server "%s" tools changed`,e),this.emit(`tools.changed`,{serverName:e,tools:i.getTools()})}),i.onResourcesChanged(()=>{Z.info(`MCP server "%s" resources changed`,e),this.emit(`resources.changed`,{serverName:e})}),i.onDisconnected(t=>{Z.info(`MCP server "%s" disconnected (%s): %s`,e,t.kind,t.reason??`unknown`),this.emit(`server.disconnected`,{name:e,reason:t.reason,kind:t.kind})}),i.onNotification((t,n)=>{this.emit(`server.notification`,{name:e,method:t,params:n})});try{await i.connect(),this.clients.set(e,i),this.emit(`server.connected`,{name:e,tools:i.getTools().length})}catch(t){let r=t.message,i=t instanceof n?t.code:void 0;if(this.emit(`server.error`,{name:e,error:r,code:i}),this.options.skipOnError!==!1)Z.warn(`MCP server "%s" connection failed, skipping: %s`,e,r);else throw t}}async disconnect(e){let t=this.clients.get(e);t&&(await t.disconnect(),this.clients.delete(e))}async disconnectAll(){let e=[...this.clients.keys()];await Promise.allSettled(e.map(e=>this.disconnect(e)))}getAllTools(){let e=[];for(let[t,n]of this.clients)n.getStatus()===`ready`&&e.push(...R(n,t));return e}getAllResources(){let e=[];for(let[t,n]of this.clients)if(n.getStatus()===`ready`)for(let r of n.getResources())e.push({...r,serverName:t});return e}getAllPrompts(){let e=[];for(let[t,n]of this.clients)if(n.getStatus()===`ready`)for(let r of n.getPrompts())e.push({...r,serverName:t});return e}getClient(e){return this.clients.get(e)}getServerInfos(){let e=[];for(let[t,n]of this.clients)e.push({name:t,config:n.getConfig(),status:n.getStatus(),tools:n.getTools(),resources:n.getResources(),prompts:n.getPrompts(),capabilities:n.getCapabilities()??void 0,error:n.getStatus()===`error`?`Connection failed`:void 0});for(let t of this.disabledServers)this.clients.has(t)||e.push({name:t,status:`disconnected`,tools:[]});return e}get connectedCount(){let e=0;for(let t of this.clients.values())t.getStatus()===`ready`&&e++;return e}get toolCount(){let e=0;for(let t of this.clients.values())t.getStatus()===`ready`&&(e+=t.getTools().length);return e}};function Q(e){return e.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)(?::-([^}]*))?\}/g,(e,t,n)=>{let r=process.env[t];return r!==void 0&&r!==``?r:n??``})}function Ie(e){if(Array.isArray(e))return e.filter(e=>typeof e==`string`).map(Q)}function $(e){if(!e||typeof e!=`object`)return;let t={};for(let[n,r]of Object.entries(e))typeof r==`string`&&(t[n]=Q(r));return Object.keys(t).length>0?t:void 0}function Le(e){if(!e||typeof e!=`object`)return null;let t=e,n={};typeof t.type==`string`&&(n.type=t.type),typeof t.command==`string`&&(n.command=Q(t.command));let r=Ie(t.args);r&&(n.args=r);let i=$(t.env);i&&(n.env=i),typeof t.url==`string`&&(n.url=Q(t.url));let a=$(t.headers);return a&&(n.headers=a),typeof t.managed==`boolean`&&(n.managed=t.managed),!n.command&&!n.url?null:n}function Re(e){let t=v(le(e),`.mcp.json`);if(!de(t))return{};let n;try{n=JSON.parse(fe(t,`utf-8`))}catch{return{}}let r=n,i=r?.mcp_servers??r?.mcpServers;if(!i||typeof i!=`object`)return{};let a={};for(let[e,t]of Object.entries(i)){let n=Le(t);n&&(a[e]=n)}return a}export{A as McpClient,Fe as McpManager,D as SseTransport,E as StdioTransport,O as StreamableHttpTransport,Oe as acquireRefreshLock,q as createDefaultTokenStore,we as createFileTokenStore,j as createMcpClient,L as createMcpToolAdapter,R as createMcpToolAdapters,Te as createMemoryTokenStore,Ee as createOverlayTokenStore,y as createSseDataParser,Me as createTokenProvider,V as discoverOAuth,U as exchangeCode,Se as fetchAuthorizationServerMetadata,B as fetchProtectedResourceMetadata,K as isTokenExpired,M as jsonSchemaPropertyToZod,je as login,I as mcpContentToToolContent,N as mcpSchemaToZod,Re as parseDotMcpJson,z as parseWwwAuthenticate,W as refreshAccessToken,X as refreshWithCrossProcessLock,H as registerClient,ke as releaseRefreshLock,T as validateMcpUrl,Ae as waitForRefreshLockRelease};
5
5
  //# sourceMappingURL=index.js.map