@agimon-ai/po-mcp-proxy 0.0.1-alpha.2 → 0.0.1-alpha.21

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,72 @@
1
+ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,s)=>(s=n==null?{}:e(i(n)),o(r||!n||!n.__esModule||!a.call(n,`default`)?t(s,`default`,{value:n,enumerable:!0}):s,n));let c=require("node:fs"),l=require("node:path");l=s(l,1);let u=require("node:crypto"),d=require("node:http"),f=require("node:fs/promises"),p=require("node:os"),m=require("proper-lockfile"),h=require("node:child_process"),g=require("node:url"),_=require("@agimon-ai/foundation-process-registry"),v=require("js-yaml");v=s(v,1);let y=require("zod"),b=require("@modelcontextprotocol/server"),x=require("@agimon-ai/foundation-port-registry"),S=require("@agimon-ai/po-logsink/telemetry/node"),C=require("node:timers/promises"),w=require("@modelcontextprotocol/client"),ee=require("@modelcontextprotocol/client/stdio"),te=require("node:async_hooks"),T=require("@modelcontextprotocol/client/validators/ajv"),E=require("node:events"),D=require("node:util"),ne=require("@hono/node-server"),re=require("@modelcontextprotocol/node"),ie=require("hono"),ae=require("liquidjs"),O=require("@agimon-ai/foundation-validator"),oe=require("@modelcontextprotocol/server/stdio");const se=[`pnpm-workspace.yaml`,`nx.json`,`.git`];function k(e=process.env.PROJECT_PATH||process.cwd()){let t=l.default.resolve(e);for(;;){for(let e of se)if((0,c.existsSync)(l.default.join(t,e)))return t;let n=l.default.dirname(t);if(n===t)return l.default.resolve(e);t=n}}const ce=`host.json`,A=`.reserved`,j=`.result`,le=6e4;function ue(e){try{return process.kill(e,0),!0}catch(e){return e.code===`EPERM`}}function de(e){return e.replace(/[^\x20-\x7E]/g,``).slice(0,200)}function fe(){return(0,l.join)((0,p.homedir)(),`.mcp-proxy`,`callbacks`)}var pe=class e{root;isPidAlive;constructor(e={}){this.root=e.root??fe(),this.isPidAlive=e.isPidAlive??ue}directoryFor(e){return(0,l.join)(this.root,String(e))}static keyFor(e){return(0,u.createHash)(`sha256`).update(e,`utf8`).digest(`hex`)}async ensureDirectory(e){let t=this.directoryFor(e);return await(0,f.mkdir)(t,{recursive:!0,mode:448}),t}async publish(e,t,n){let r=(0,l.join)(e,`.${t}.${(0,u.randomBytes)(6).toString(`hex`)}`);await(0,f.writeFile)(r,JSON.stringify(n),{encoding:`utf-8`,mode:384});try{await(0,f.rename)(r,(0,l.join)(e,t))}catch(e){throw await(0,f.rm)(r,{force:!0}).catch(()=>void 0),e}}async readJson(e){try{return JSON.parse(await(0,f.readFile)(e,`utf-8`))}catch{return}}async claimHost(e){let t=await this.ensureDirectory(e),n={pid:process.pid,startedAt:(/* @__PURE__ */ new Date()).toISOString()};await this.publish(t,ce,n)}async releaseHost(e){await(0,f.rm)((0,l.join)(this.directoryFor(e),ce),{force:!0}).catch(()=>void 0)}async readHost(e){let t=await this.readJson((0,l.join)(this.directoryFor(e),ce));if(t&&typeof t.pid==`number`)return this.isPidAlive(t.pid)?t:void 0}async reserve(t,n){let r=await this.ensureDirectory(t),i={pid:process.pid};await this.publish(r,`${e.keyFor(n)}${A}`,i)}async heartbeat(t,n){let r=(0,l.join)(this.directoryFor(t),`${e.keyFor(n)}${A}`),i=/* @__PURE__ */ new Date;await(0,f.utimes)(r,i,i).catch(()=>void 0)}async release(t,n){let r=e.keyFor(n),i=this.directoryFor(t);await Promise.all([(0,f.rm)((0,l.join)(i,`${r}${A}`),{force:!0}).catch(()=>void 0),(0,f.rm)((0,l.join)(i,`${r}${j}`),{force:!0}).catch(()=>void 0)])}async hasReservation(t,n){let r=(0,l.join)(this.directoryFor(t),`${e.keyFor(n)}${A}`);return this.isReservationLive(r)}async hasLiveReservations(e){let t=this.directoryFor(e),n;try{n=await(0,f.readdir)(t)}catch{return!1}for(let e of n)if(e.endsWith(A)&&await this.isReservationLive((0,l.join)(t,e)))return!0;return!1}async isReservationLive(e){let t=await this.readJson(e);if(!t||typeof t.pid!=`number`||!this.isPidAlive(t.pid))return!1;try{let t=await(0,f.stat)(e);return Date.now()-t.mtimeMs<le}catch{return!1}}async bank(t,n,r){let i=await this.ensureDirectory(t),a=r.status===`denied`?{status:`denied`,error:de(r.error)}:r;await this.publish(i,`${e.keyFor(n)}${j}`,a)}async takeResult(t,n){let r=(0,l.join)(this.directoryFor(t),`${e.keyFor(n)}${j}`),i=await this.readJson(r);if(i&&typeof i.status==`string`)return await(0,f.rm)(r,{force:!0}).catch(()=>void 0),i}async collectGarbage(e){let t=this.directoryFor(e),n;try{n=await(0,f.readdir)(t)}catch{return}for(let e of n){if(e.endsWith(A)){if(!await this.isReservationLive((0,l.join)(t,e))){await(0,f.rm)((0,l.join)(t,e),{force:!0}).catch(()=>void 0);let n=e.slice(0,-9);await(0,f.rm)((0,l.join)(t,`${n}${j}`),{force:!0}).catch(()=>void 0)}continue}if(!e.endsWith(j))continue;let n=e.slice(0,-7);await this.isReservationLive((0,l.join)(t,`${n}${A}`))||await(0,f.rm)((0,l.join)(t,e),{force:!0}).catch(()=>void 0)}}};const me=19876;function he(e){let t=(0,u.createHash)(`sha256`).update(e).digest();return me+t.readUInt16BE(0)%100}const ge=`/callback`,_e=3e5,M={"content-type":`text/html; charset=utf-8`};function ve(e){return`Authorization failed: ${e}`}function ye(e,t){return`<!doctype html><meta charset="utf-8"><title>${e}</title><body style="font-family:system-ui;padding:2rem"><h1>${e}</h1><p>${t}</p></body>`}function be(e){return e?.code===`EADDRINUSE`}function xe(e){return new Promise(t=>{setTimeout(t,e).unref?.()})}var Se=class{server;boundPort;requestedPort;guestPort;closing=!1;listening;pending=/* @__PURE__ */ new Map;path;rendezvous;pollIntervalMs;bindWaitMs;constructor(e=ge){let t=typeof e==`string`?{path:e}:e;this.path=t.path??`/callback`,this.rendezvous=t.rendezvous===!1?void 0:new pe(t),this.pollIntervalMs=t.pollIntervalMs??250,this.bindWaitMs=t.bindWaitMs??6e4}getPort(){return this.boundPort}getRedirectPort(){return this.boundPort??this.guestPort}hasPendingAuthorizations(){return this.pending.size>0}async listen(e){let t=this.listening;if(t){if(t.port===e)return t.promise;await t.promise.catch(()=>void 0)}let n=this.acquire(e);this.listening={port:e,promise:n};try{return await n}finally{this.listening?.promise===n&&(this.listening=void 0)}}async acquire(e){let t=this.getRedirectPort();if(t!==void 0){if(e!==0&&e!==t){if(this.hasPendingAuthorizations())throw Error(`OAuth callback server is bound to port ${t} with an authorization in progress; cannot rebind to ${e}.`);await this.close()}else if(this.server||this.guestPort!==void 0)return t}let n=Date.now()+this.bindWaitMs;for(;;)try{return await this.bind(e)}catch(t){if(e===0||!be(t))throw t;if(await this.rendezvous?.readHost(e))return this.guestPort=e,e;if(Date.now()>=n)throw Error(`OAuth callback port ${e} is held by another process that cannot forward callbacks. Waited ${Math.round(this.bindWaitMs/1e3)}s for it to be released. Finish or cancel the other authorization, or set this server's oauth.redirectUri to a different port.`);await xe(this.pollIntervalMs)}}async bind(e){let t=(0,d.createServer)((t,n)=>{this.handleRequest(t.url??`/`,e,n)});await new Promise((n,r)=>{t.once(`error`,r),t.listen(e,`127.0.0.1`,()=>{t.removeListener(`error`,r),n()})});let n=t.address();if(n===null||typeof n==`string`)throw t.close(),Error(`OAuth callback server failed to report a bound port.`);return t.unref(),this.server=t,this.boundPort=n.port,this.requestedPort=e,this.guestPort=void 0,e!==0&&(await this.rendezvous?.claimHost(this.boundPort).catch(()=>void 0),await this.rendezvous?.collectGarbage(this.boundPort).catch(()=>void 0),await this.adoptOwnReservations(this.boundPort)),this.boundPort}async adoptOwnReservations(e){for(let[t,n]of this.pending)n.guest&&(n.guest.poll&&clearTimeout(n.guest.poll),n.guest=void 0,await this.rendezvous?.release(e,t).catch(()=>void 0))}async handleRequest(e,t,n){let r=new URL(e,`http://localhost:${this.boundPort??t}`);if(r.pathname!==this.path){n.writeHead(404,M).end(ye(`Not found`,`Unexpected callback path.`));return}let i=r.searchParams.get(`state`)??``,a=r.searchParams.get(`error`),o=r.searchParams.get(`code`),s=r.searchParams.get(`iss`),c=a?{status:`denied`,error:a}:o?{status:`ok`,code:o,...s===null?{}:{iss:s}}:{status:`malformed`};if(this.pending.has(i)){this.settleOutcome(i,c),this.respond(n,c);return}let l=this.boundPort;l!==void 0&&i&&await this.rendezvous?.hasReservation(l,i)?(await this.rendezvous?.bank(l,i,c).catch(()=>void 0),this.respond(n,c)):n.writeHead(400,M).end(ye(`Invalid request`,`This authorization request is not recognised.`))}respond(e,t){if(t.status===`ok`){e.writeHead(200,M).end(ye(`Authorized`,`You can close this window and return to your terminal.`));return}let n=t.status===`denied`?`You can close this window.`:`No authorization code was returned.`;e.writeHead(400,M).end(ye(`Authorization failed`,n))}settleOutcome(e,t){if(t.status===`ok`){this.settle(e,{code:t.code,state:e,...t.iss===void 0?{}:{iss:t.iss}});return}let n=t.status===`denied`?ve(t.error):`Authorization response did not include a code.`;this.settle(e,void 0,Error(n))}async reserve(e,t=_e){if(this.pending.has(e))throw Error(`An authorization with this state is already pending.`);let n=this.server?void 0:this.guestPort;n!==void 0&&await this.rendezvous?.reserve(n,e);let r=this.register(e,t);n!==void 0&&(r.guest={port:n,poll:void 0},this.scheduleGuestPoll(e,r))}waitForCallback(e,t=_e){let n=this.pending.get(e);if(n)return n.claimed?Promise.reject(/* @__PURE__ */ Error(`An authorization with this state is already pending.`)):(n.claimed=!0,n.promise);if(!this.server&&this.guestPort!==void 0)return Promise.reject(/* @__PURE__ */ Error(`This process does not own the OAuth callback port; reserve the state before waiting on it.`));let r=this.register(e,t);return r.claimed=!0,r.promise}register(e,t){let n,r=new Promise((r,i)=>{let a=setTimeout(()=>{this.abandon(e,Error(this.timeoutMessage(e,t)))},t);a.unref?.(),n={resolve:r,reject:i,timer:a}});return n.promise=r,r.catch(()=>void 0),this.pending.set(e,n),n}timeoutMessage(e,t){let n=Math.round(t/1e3);return this.pending.get(e)?.guest?`Timed out after ${n}s waiting for the OAuth redirect. Another process was receiving it and may have exited; reload the redirect page in your browser or start the authorization again.`:`Timed out after ${n}s waiting for the OAuth redirect.`}cancel(e){this.abandon(e,/* @__PURE__ */ Error(`Authorization cancelled.`))}async abandon(e,t){let n=this.pending.get(e)?.guest;this.settle(e,void 0,t),n&&await this.rendezvous?.release(n.port,e).catch(()=>void 0)}settle(e,t,n){let r=this.pending.get(e);r&&(clearTimeout(r.timer),r.guest?.poll&&clearTimeout(r.guest.poll),this.pending.delete(e),n?r.reject(n):t&&r.resolve(t),this.releaseWhenIdle())}scheduleGuestPoll(e,t){let n=t.guest;if(!n)return;let r=setTimeout(()=>{this.pollAsGuest(e)},this.pollIntervalMs);r.unref?.(),n.poll=r}async tryPromote(e){if(this.server)return!0;let t=this.listening;if(t)return await t.promise.catch(()=>void 0),this.server!==void 0;let n=this.bind(e);this.listening={port:e,promise:n};try{return await n,!0}catch{return!1}finally{this.listening?.promise===n&&(this.listening=void 0)}}async pollAsGuest(e){let t=this.pending.get(e),n=t?.guest;if(!t||!n)return;let r=await this.rendezvous?.takeResult(n.port,e).catch(()=>void 0);r?(this.settleOutcome(e,r),await this.rendezvous?.release(n.port,e).catch(()=>void 0)):(await this.tryPromote(n.port),this.pending.get(e)?.guest&&(await this.rendezvous?.heartbeat(n.port,e).catch(()=>void 0),this.scheduleGuestPoll(e,t)))}async releaseWhenIdle(){if(this.closing||!this.server||this.pending.size>0||this.requestedPort===0)return;let e=this.boundPort;e!==void 0&&await this.rendezvous?.hasLiveReservations(e).catch(()=>!1)||this.closing||!this.server||this.pending.size>0||await this.close()}async close(){this.closing=!0;try{for(let e of Array.from(this.pending.keys()))await this.abandon(e,/* @__PURE__ */ Error(`OAuth callback server shut down.`));let e=this.server,t=this.boundPort;if(this.server=void 0,this.boundPort=void 0,this.requestedPort=void 0,this.guestPort=void 0,t!==void 0&&await this.rendezvous?.releaseHost(t).catch(()=>void 0),!e)return;await new Promise(t=>{e.close(()=>t())})}finally{this.closing=!1}}};let N,P=0;function Ce(){return N??=new Se,N}function we(){return P+=1,Ce()}async function Te(){P>0&&--P,!(P>0)&&(N?.hasPendingAuthorizations()||await Ee())}async function Ee(){let e=N;N=void 0,P=0,await e?.close()}const De=/* @__PURE__ */ new WeakMap;async function Oe(e,t,n,r){return e.withLock?e.withLock(t,n,r):ke(e,t,n,r)}async function ke(e,t,n,r){let i=De.get(e);i||De.set(e,i=/* @__PURE__ */ new Map);let a=i.get(t)??Promise.resolve(),o,s=new Promise(e=>{o=e});i.set(t,s),await a;try{return r?.throwIfAborted(),await n()}finally{o(),i.get(t)===s&&i.delete(t)}}function Ae(){return(0,l.join)((0,p.homedir)(),`.mcp-proxy`,`oauth`)}function je(e){return`sha256-${(0,u.createHash)(`sha256`).update(e,`utf8`).digest(`hex`)}`}function Me(e,t){let n=(0,u.randomBytes)(12),r=(0,u.createCipheriv)(`aes-256-gcm`,t,n),i=Buffer.concat([r.update(JSON.stringify(e),`utf8`),r.final()]);return{version:1,iv:n.toString(`base64`),tag:r.getAuthTag().toString(`base64`),ciphertext:i.toString(`base64`)}}function Ne(e,t){let n=JSON.parse(e);if(!n||typeof n!=`object`||!(`version`in n)||n.version!==1||!(`iv`in n)||typeof n.iv!=`string`||!(`tag`in n)||typeof n.tag!=`string`||!(`ciphertext`in n)||typeof n.ciphertext!=`string`)throw Error(`Invalid encrypted OAuth credential format.`);let r=Buffer.from(n.iv,`base64`),i=Buffer.from(n.tag,`base64`);if(r.length!==12||i.length!==16)throw Error(`Invalid OAuth credential nonce or tag.`);let a=(0,u.createDecipheriv)(`aes-256-gcm`,t,r);a.setAuthTag(i);let o=JSON.parse(Buffer.concat([a.update(Buffer.from(n.ciphertext,`base64`)),a.final()]).toString(`utf8`));if(!o||typeof o!=`object`||Array.isArray(o))throw Error(`Invalid OAuth credential entry.`);return o}var Pe=class{baseDir;fallback=new Fe;unavailable=!1;constructor(e=Ae()){this.baseDir=e}get isDegraded(){return this.unavailable}async withLock(e,t,n){return ke(this,e,async()=>{if(this.unavailable)return t();await this.key();let r=await(0,m.lock)(this.pathFor(e),{realpath:!1,retries:{retries:100,minTimeout:50,maxTimeout:100,factor:1},stale:3e4});try{return n?.throwIfAborted(),await t()}finally{await r()}},n)}pathFor(e){return(0,l.join)(this.baseDir,`${je(e)}.json`)}async key(){await(0,f.mkdir)(this.baseDir,{recursive:!0,mode:448});let e=await(0,f.lstat)(this.baseDir);if(!e.isDirectory()||e.uid!==process.getuid?.())throw Error(`OAuth credential directory is not owned by this user.`);await(0,f.chmod)(this.baseDir,448);let t=(0,l.join)(this.baseDir,`key.bin`),n;try{n=await(0,f.open)(t,`wx`,384),await n.writeFile((0,u.randomBytes)(32)),await n.close(),n=void 0}catch(e){if(n&&await n.close(),e.code!==`EEXIST`)throw e}let r=await(0,f.lstat)(t);if(!r.isFile()||r.isSymbolicLink()||r.uid!==process.getuid?.()||r.mode&63)throw Error(`OAuth encryption key is not an owner-only regular file.`);let i=await(0,f.readFile)(t);if(i.length!==32)throw Error(`Invalid OAuth encryption key.`);let a=await(0,f.lstat)(t);if(a.ino!==r.ino||a.mode&63)throw Error(`OAuth encryption key changed during read.`);return i}async read(e){let t=await this.fallback.read(e);if(t)return t;if(!this.unavailable)try{let t=await this.key(),n=this.pathFor(e),r=await(0,f.lstat)(n);if(!r.isFile()||r.isSymbolicLink()||r.uid!==process.getuid?.()||r.mode&63)throw Error(`OAuth credential file is not owner-only.`);let i=await(0,f.readFile)(n,`utf8`),a=await(0,f.lstat)(n);return a.ino!==r.ino||a.mode&63?void 0:Ne(i,t)}catch{return}}async write(e,t){if(this.unavailable)await this.fallback.write(e,t);else try{let n=await this.key(),r=this.pathFor(e),i=(0,l.join)(this.baseDir,`.${je(e)}-${(0,u.randomBytes)(12).toString(`hex`)}.tmp`),a=await(0,f.open)(i,`wx`,384);try{await a.writeFile(JSON.stringify(Me(t,n)))}catch(e){throw await a.close(),await(0,f.rm)(i,{force:!0}),e}await a.close();try{await(0,f.rename)(i,r)}catch(e){throw await(0,f.rm)(i,{force:!0}),e}await this.fallback.clear(e)}catch{console.warn(`[oauth] Secure credential storage is unavailable; credentials are memory-only for this process.`),this.unavailable=!0,await this.fallback.write(e,t)}}async clear(e){await this.fallback.clear(e),await(0,f.rm)(this.pathFor(e),{force:!0})}},Fe=class{isEphemeral=!0;entries=/* @__PURE__ */ new Map;async read(e){return this.entries.get(e)}async write(e,t){this.entries.set(e,t)}async clear(e){this.entries.delete(e)}};async function Ie(e,t,n){let r=await e.read(t);if(r&&r.serverUrl===n)return r}function Le(e){return e?.access_token}function F(e,t){return e.replace(/\/$/,``)===t.replace(/\/$/,``)}var Re=class{serverName;serverUrl;store;callbackServer;config;logger;callbackPort;callbackTimeoutMs;onAuthorizationUrl;pendingState;authorizationCancelled=!1;pendingCallback;flowCodeVerifier;flowClientInformation;flowDiscoveryState;flowTokenFingerprint;tokenGeneration;tokenFingerprint;interactiveGrant=!1;constructor(e){this.serverName=e.serverName,this.serverUrl=e.serverUrl,this.store=e.store,this.callbackServer=e.callbackServer,this.config=e.config??{},this.logger=e.logger,this.callbackPort=e.callbackPort??19876,this.callbackTimeoutMs=e.callbackTimeoutMs,this.onAuthorizationUrl=e.onAuthorizationUrl}async prepareCallback(){this.callbackPort===0&&await this.callbackServer.listen(0)}get redirectUrl(){return this.config.grantType===`client_credentials`?void 0:this.config.redirectUri?this.config.redirectUri:this.callbackServer.redirectUri?.()||`http://127.0.0.1:${this.callbackPort>0?this.callbackPort:this.callbackServer.getPort()??19876}${ge}`}get clientMetadata(){let e=this.config.grantType===`client_credentials`,t=e?[]:[this.redirectUrl];return{client_name:this.config.clientName??`mcp-proxy`,...this.config.clientUri?{client_uri:this.config.clientUri}:{},redirect_uris:t,grant_types:e?[`client_credentials`]:[`authorization_code`,`refresh_token`],response_types:e?[]:[`code`],token_endpoint_auth_method:this.config.clientSecret?`client_secret_post`:`none`,...this.config.scope?{scope:this.config.scope}:{}}}state(){return this.pendingState=(0,u.randomBytes)(32).toString(`hex`),this.pendingState}async clientInformation(e){if(this.config.clientId)return{client_id:this.config.clientId,...this.config.clientSecret?{client_secret:this.config.clientSecret}:{},...e?{issuer:e.issuer}:{}};if(this.flowClientInformation&&(!e||!this.flowClientInformation.issuer||F(this.flowClientInformation.issuer,e.issuer)))return this.flowClientInformation;let t=await this.readBoundEntry(),n=t?.tokens?.refresh_token&&!this.interactiveGrant||this.registrationMatchesRedirect(t??{})?t?.clientInformation:void 0;return e&&n?.issuer&&!F(n.issuer,e.issuer)?void 0:n}async saveClientInformation(e,t){if(t&&e.issuer&&!F(e.issuer,t.issuer))throw Error(`OAuth client information issuer does not match the discovered issuer.`);this.flowClientInformation=e,await this.mergeEntry({clientInformation:e})}async tokens(e){let t=await this.readBoundEntry(),n=t?.tokens;return this.tokenGeneration=t?.generation,this.tokenFingerprint=Le(n),e&&n?.issuer&&!F(n.issuer,e.issuer)?void 0:n}async saveTokens(e,t){if(t&&e.issuer&&!F(e.issuer,t.issuer))throw Error(`OAuth token issuer does not match the discovered issuer.`);this.flowCodeVerifier=void 0;let n=await this.readBoundEntry();if(n?.generation!==this.tokenGeneration||n?.tokens?.access_token!==this.tokenFingerprint)return;let r=e.expires_in;await this.mergeEntry({tokens:e,generation:(n?.generation??0)+1,expiresAt:typeof r==`number`&&Number.isFinite(r)&&r>0?Date.now()+r*1e3:void 0,codeVerifier:void 0}),this.tokenGeneration=(n?.generation??0)+1,this.tokenFingerprint=e.access_token,this.interactiveGrant=!1}async saveDiscoveryState(e){this.flowDiscoveryState=e,await this.mergeEntry({discoveryState:e})}async discoveryState(){return this.flowDiscoveryState??(await this.readBoundEntry())?.discoveryState}async saveCodeVerifier(e){this.flowCodeVerifier=e,await this.mergeEntry({codeVerifier:e})}async codeVerifier(){if(this.flowCodeVerifier)return this.flowCodeVerifier;let e=await this.readBoundEntry();if(!e?.codeVerifier)throw Error(`No PKCE code verifier stored for MCP server "${this.serverName}"; restart the authorization.`);return e.codeVerifier}async redirectToAuthorization(e){this.assertAuthorizationActive();let t=this.pendingState;if(!t)throw Error(`No authorization state was reserved for MCP server "${this.serverName}".`);try{if(this.flowTokenFingerprint=this.tokenFingerprint,this.assertAuthorizationActive(),await this.callbackServer.listen(this.callbackPort),this.assertAuthorizationActive(),await this.callbackServer.reserve(t,this.callbackTimeoutMs),this.authorizationCancelled&&this.callbackServer.cancel(t),this.assertAuthorizationActive(),this.pendingCallback=this.callbackServer.waitForCallback(t,this.callbackTimeoutMs),this.pendingCallback.catch(()=>void 0),this.onAuthorizationUrl){await this.onAuthorizationUrl(e,this.serverName),this.assertAuthorizationActive();return}this.logger?.info(`[oauth] Authorize MCP server "${this.serverName}" by visiting: ${e.toString()}`)}catch(e){throw this.cancelAuthorization(),e}}cancelAuthorization(){this.authorizationCancelled=!0,this.pendingState&&this.callbackServer.cancel(this.pendingState),this.pendingCallback=void 0,this.pendingState=void 0}assertAuthorizationActive(){if(this.authorizationCancelled)throw Error(`Authorization cancelled.`)}async waitForAuthorizationCode(){return(await this.waitForAuthorizationCallback()).get(`code`)}async waitForAuthorizationCallback(){let e=this.pendingCallback,t=this.pendingState;if(!e)throw Error(`No authorization is in progress for MCP server "${this.serverName}".`);let n=this.watchForPeerAuthorization();try{let r=await Promise.race([e,n.result]);if(r.state!==t)throw Error(`OAuth callback state mismatch.`);let i=new URLSearchParams({code:r.code,state:r.state});return r.iss!==void 0&&i.set(`iss`,r.iss),i}catch(e){throw t&&this.callbackServer.cancel(t),e}finally{n.stop(),this.pendingCallback=void 0,this.pendingState=void 0}}watchForPeerAuthorization(){let e,t=!1,n=()=>{t=!0,e&&clearTimeout(e)},r=new Promise((n,r)=>{let i=this.flowTokenFingerprint,a=async()=>{if(t)return;let e=Le((await this.readBoundEntry().catch(()=>void 0))?.tokens);e!==void 0&&e!==i?r(/* @__PURE__ */ Error(`MCP server "${this.serverName}" was authorized by another session; reconnect to use the shared credentials.`)):o()},o=()=>{t||(e=setTimeout(()=>void a(),1e3),e.unref?.())};o()});return r.catch(()=>void 0),{result:r,stop:n}}hasPendingAuthorization(){return this.pendingCallback!==void 0}prepareTokenRequest(e){if(this.config.grantType!==`client_credentials`)return;let t=new URLSearchParams({grant_type:`client_credentials`}),n=e??this.config.scope;return n&&t.set(`scope`,n),t}async invalidateCredentials(e){if(e===`all`||e===`client`)this.flowClientInformation=void 0,this.flowCodeVerifier=void 0,this.flowDiscoveryState=void 0,await this.store.clear(this.serverName);else if(e===`tokens`){let e=await this.readBoundEntry();if(e?.generation!==this.tokenGeneration||e?.tokens?.access_token!==this.tokenFingerprint)return;await this.mergeEntry({tokens:void 0,expiresAt:void 0})}else e===`verifier`&&(this.flowCodeVerifier=void 0,await this.mergeEntry({codeVerifier:void 0})),e===`discovery`&&(this.flowDiscoveryState=void 0,await this.mergeEntry({discoveryState:void 0}))}async readBoundEntry(){let e=await this.store.read(this.serverName);if(e){if(e.serverUrl!==this.serverUrl)this.logger?.warn(`[oauth] Stored credentials for "${this.serverName}" were issued for a different URL and were ignored.`);else return e}}registrationMatchesRedirect(e){let t=e.clientInformation&&`redirect_uris`in e.clientInformation?e.clientInformation.redirect_uris:void 0;if(!Array.isArray(t)||t.length===0)return!0;let n=this.redirectUrl;return n===void 0||t.includes(n)}async mergeEntry(e){let t=await this.readBoundEntry()??{};await this.store.write(this.serverName,{...t,...e,serverUrl:this.serverUrl,updatedAt:Date.now()})}readCredential(){return this.readBoundEntry()}prepareInteractiveGrant(){this.interactiveGrant=!0,this.flowClientInformation=void 0}withCredentialLock(e,t){return Oe(this.store,this.serverName,e,t)}};let ze;function Be(e){return typeof e.auth==`object`&&e.auth?.type===`api-key`?`api-key`:e.auth===!1||e.oauth===!1?e.bearerToken||e.bearerTokenEnv?`bearer`:`none`:e.auth===`bearer`||e.bearerToken||e.bearerTokenEnv?`bearer`:e.auth===`oauth`?`oauth`:Object.keys(e.headers??{}).some(e=>Ve.test(e))?`none`:`oauth`}const Ve=/authorization|api[-_]?key|token|secret|cookie/i;function He(e){return e.bearerTokenEnv?process.env[e.bearerTokenEnv]:e.bearerToken}function Ue(e){if(Be(e.config)!==`oauth`)return;let t=e.config.oauth===!1?void 0:e.config.oauth;return new Re({serverName:e.serverName,serverUrl:e.config.url,store:e.store??new Pe,callbackServer:e.callbackServer??(e.store?.isEphemeral?ze??=new Se({rendezvous:!1}):Ce()),config:t,logger:e.logger,callbackPort:e.store?.isEphemeral&&!t?.redirectUri?0:We(e.config,e.workspaceRoot),callbackTimeoutMs:e.callbackTimeoutMs,onAuthorizationUrl:e.onAuthorizationUrl})}function We(e,t=k()){let n=e.oauth===!1?void 0:e.oauth;if(n?.redirectUri){let e=Number.parseInt(new URL(n.redirectUri).port,10);return Number.isFinite(e)&&e>0?e:he(t)}return he(t)}function I(e,t=process.env){return e.replace(/\$\{([^}]+)\}/g,(e,n)=>{let r=t[n];return r===void 0?`\${${n}}`:r})}function L(e,t){if(typeof e==`string`)return I(e,t);if(Array.isArray(e))return e.map(e=>L(e,t));if(typeof e==`object`&&e){let n={};for(let[r,i]of Object.entries(e))n[r]=L(i,t);return n}return e}const Ge=[/^127\./,/^10\./,/^172\.(1[6-9]|2\d|3[01])\./,/^192\.168\./,/^169\.254\./,/^0\./,/^224\./,/^240\./,/^localhost$/i,/^.*\.localhost$/i,/^\[::\]/,/^\[::1\]/,/^\[0:0:0:0:0:0:0:1\]/,/^\[0{1,4}:0{1,4}:0{1,4}:0{1,4}:0{1,4}:0{1,4}:0{1,4}:1\]/i,/^\[fe80:/i,/^\[fc00:/i,/^\[fd00:/i,/^\[::ffff:127\./i,/^\[::ffff:7f[0-9a-f]{2}:/i,/^\[::ffff:10\./i,/^\[::ffff:a[0-9a-f]{2}:/i,/^\[::ffff:172\.(1[6-9]|2\d|3[01])\./i,/^\[::ffff:ac1[0-9a-f]:/i,/^\[::ffff:192\.168\./i,/^\[::ffff:c0a8:/i,/^\[::ffff:169\.254\./i,/^\[::ffff:a9fe:/i,/^\[::ffff:0\./i,/^\[::127\./i,/^\[::7f[0-9a-f]{2}:/i,/^\[::10\./i,/^\[::a[0-9a-f]{2}:/i,/^\[::192\.168\./i,/^\[::c0a8:/i];function Ke(e,t){let n=t?.allowPrivateIPs??!1,r=t?.enforceHttps??!0,i;try{i=new URL(e)}catch{throw Error(`Invalid URL format: ${e}`)}let a=i.protocol.replace(`:`,``);if(r&&a!==`https`)throw Error(`HTTPS is required for security. URL uses '${a}://'. Set security.enforceHttps: false to allow HTTP.`);if(a!==`http`&&a!==`https`)throw Error(`Invalid URL protocol '${a}://'. Only http:// and https:// are allowed.`);if(!n){let e=i.hostname.toLowerCase();if(Ge.some(t=>t.test(e)))throw Error(`Private IP addresses and localhost are blocked for security (${e}). Set security.allowPrivateIPs: true to allow internal networks.`)}}function qe(e,t=process.env){let n=I(e.url,t);if(Ke(n,e.security),e.validation){if(e.validation.url&&!new RegExp(e.validation.url).test(n))throw Error(`Remote config URL "${n}" does not match validation pattern: ${e.validation.url}`);if(e.validation.headers&&Object.keys(e.validation.headers).length>0){if(!e.headers){let t=Object.keys(e.validation.headers);throw Error(`Remote config is missing required headers: ${t.join(`, `)}`)}for(let[n,r]of Object.entries(e.validation.headers)){if(!(n in e.headers))throw Error(`Remote config is missing required header: ${n}`);let i=I(e.headers[n],t);if(!new RegExp(r).test(i))throw Error(`Remote config header "${n}" value "${i}" does not match validation pattern: ${r}`)}}}}const Je=y.z.object({name:y.z.string(),description:y.z.string(),folder:y.z.string().optional()}),Ye=y.z.object({skill:Je.optional()}),Xe=y.z.object({instruction:y.z.string().optional(),toolBlacklist:y.z.array(y.z.string()).optional(),omitToolDescription:y.z.boolean().optional(),prompts:y.z.record(y.z.string(),Ye).optional()}).optional(),Ze=y.z.object({command:y.z.string(),args:y.z.array(y.z.string()).optional(),env:y.z.record(y.z.string(),y.z.string()).optional(),cwd:y.z.string().optional(),disabled:y.z.boolean().optional(),instruction:y.z.string().optional(),timeout:y.z.number().positive().optional(),requestTimeout:y.z.number().positive().optional(),config:Xe}),Qe=y.z.union([y.z.literal(!1),y.z.object({grantType:y.z.enum([`authorization_code`,`client_credentials`]).optional(),clientId:y.z.string().optional(),clientSecret:y.z.string().optional(),scope:y.z.string().optional(),redirectUri:y.z.string().optional(),clientName:y.z.string().optional(),clientUri:y.z.string().optional()})]).optional(),$e=y.z.discriminatedUnion(`mode`,[y.z.strictObject({type:y.z.literal(`api-key`),mode:y.z.literal(`bearer`)}),y.z.strictObject({type:y.z.literal(`api-key`),mode:y.z.literal(`header`),name:y.z.string().regex(/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/).max(128)})]),et={auth:y.z.union([y.z.literal(`oauth`),y.z.literal(`bearer`),y.z.literal(!1),$e]).optional(),bearerToken:y.z.string().optional(),bearerTokenEnv:y.z.string().optional(),oauth:Qe},tt=y.z.object({...et,url:y.z.string().url(),headers:y.z.record(y.z.string(),y.z.string()).optional(),type:y.z.enum([`http`,`sse`]).optional(),disabled:y.z.boolean().optional(),instruction:y.z.string().optional(),timeout:y.z.number().positive().optional(),requestTimeout:y.z.number().positive().optional(),config:Xe}),nt=y.z.union([Ze,tt]),rt=y.z.object({url:y.z.string().optional(),headers:y.z.record(y.z.string(),y.z.string()).optional()}).optional(),it=y.z.object({allowPrivateIPs:y.z.boolean().optional(),enforceHttps:y.z.boolean().optional()}).optional(),at=y.z.object({url:y.z.string(),headers:y.z.record(y.z.string(),y.z.string()).optional(),validation:rt,security:it,mergeStrategy:y.z.enum([`local-priority`,`remote-priority`,`merge-deep`]).optional()}),ot=y.z.object({paths:y.z.array(y.z.string())}),st=y.z.union([y.z.boolean(),y.z.object({maxBytes:y.z.number().int().positive().optional(),maxLines:y.z.number().int().positive().optional(),structuredMaxBytes:y.z.number().int().positive().optional()})]).optional(),ct=y.z.object({type:y.z.enum([`stdio`,`http`,`sse`,`stdio-http`]).optional(),port:y.z.number().int().positive().optional(),host:y.z.string().optional(),keepAlive:y.z.boolean().optional(),outputGuard:st}).optional(),lt=y.z.object({id:y.z.string().optional(),proxy:ct,mcpServers:y.z.record(y.z.string(),nt),remoteConfigs:y.z.array(at).optional(),skills:ot.optional()}),ut=y.z.object({command:y.z.string(),args:y.z.array(y.z.string()).optional(),env:y.z.record(y.z.string(),y.z.string()).optional(),cwd:y.z.string().optional()}),dt=y.z.object({...et,url:y.z.string().url(),headers:y.z.record(y.z.string(),y.z.string()).optional()}),ft=y.z.object({...et,url:y.z.string().url(),headers:y.z.record(y.z.string(),y.z.string()).optional()}),pt=y.z.object({name:y.z.string(),description:y.z.string(),folder:y.z.string().optional()}),mt=y.z.object({skill:pt.optional()}),ht=y.z.discriminatedUnion(`transport`,[y.z.object({name:y.z.string(),instruction:y.z.string().optional(),toolBlacklist:y.z.array(y.z.string()).optional(),omitToolDescription:y.z.boolean().optional(),prompts:y.z.record(y.z.string(),mt).optional(),timeout:y.z.number().positive().optional(),requestTimeout:y.z.number().positive().optional(),transport:y.z.literal(`stdio`),config:ut}),y.z.object({name:y.z.string(),instruction:y.z.string().optional(),toolBlacklist:y.z.array(y.z.string()).optional(),omitToolDescription:y.z.boolean().optional(),prompts:y.z.record(y.z.string(),mt).optional(),timeout:y.z.number().positive().optional(),requestTimeout:y.z.number().positive().optional(),transport:y.z.literal(`http`),config:dt}),y.z.object({name:y.z.string(),instruction:y.z.string().optional(),toolBlacklist:y.z.array(y.z.string()).optional(),omitToolDescription:y.z.boolean().optional(),prompts:y.z.record(y.z.string(),mt).optional(),timeout:y.z.number().positive().optional(),requestTimeout:y.z.number().positive().optional(),transport:y.z.literal(`sse`),config:ft})]),gt=y.z.object({id:y.z.string().optional(),proxy:ct,mcpServers:y.z.record(y.z.string(),ht),skills:ot.optional()});function _t(e,t=process.env){let n={};for(let[r,i]of Object.entries(e.mcpServers))if(!(`disabled`in i&&i.disabled===!0)){if(`command`in i){let e=i,a=I(e.command,t),o=e.args?.map(e=>I(e,t)),s=e.env?L(e.env,t):void 0,c=e.cwd?I(e.cwd,t):void 0;n[r]={name:r,instruction:e.instruction||e.config?.instruction,toolBlacklist:e.config?.toolBlacklist,omitToolDescription:e.config?.omitToolDescription,prompts:e.config?.prompts,timeout:e.timeout,requestTimeout:e.requestTimeout,transport:`stdio`,config:{command:a,args:o,env:s,cwd:c}}}else if(`url`in i){let e=i,a=e.type===`sse`?`sse`:`http`,o=I(e.url,t),s=e.headers?L(e.headers,t):void 0;n[r]={name:r,instruction:e.instruction||e.config?.instruction,toolBlacklist:e.config?.toolBlacklist,omitToolDescription:e.config?.omitToolDescription,prompts:e.config?.prompts,timeout:e.timeout,requestTimeout:e.requestTimeout,transport:a,config:{url:o,headers:s,...e.auth===void 0?{}:{auth:e.auth},...e.bearerToken?{bearerToken:I(e.bearerToken,t)}:{},...e.bearerTokenEnv?{bearerTokenEnv:e.bearerTokenEnv}:{},...e.oauth===void 0?{}:{oauth:e.oauth}}}}}return{id:e.id,proxy:e.proxy,mcpServers:n,skills:e.skills}}function vt(e,t=process.env){let n=_t(lt.parse(e),t);return gt.parse(n)}var yt=class{cacheDir;cacheTTL;readEnabled;writeEnabled;logger;constructor(e,t=console){this.cacheDir=(0,l.join)((0,p.tmpdir)(),`mcp-proxy-cache`,`remote-configs`),this.cacheTTL=e?.ttl||36e5,this.readEnabled=e?.readEnabled===void 0||e.readEnabled,this.writeEnabled=e?.writeEnabled===void 0||e.writeEnabled,this.logger=t}generateCacheKey(e){return(0,u.createHash)(`sha256`).update(e).digest(`hex`)}getCacheFilePath(e){return(0,l.join)(this.cacheDir,`${e}.json`)}async ensureCacheDir(){try{await(0,f.mkdir)(this.cacheDir,{recursive:!0})}catch(e){if(e?.code!==`EEXIST`)throw e}}async get(e){if(!this.readEnabled)return null;try{await this.ensureCacheDir();let t=this.generateCacheKey(e),n=this.getCacheFilePath(t);if(!(0,c.existsSync)(n))return null;let r=await(0,f.readFile)(n,`utf-8`),i=JSON.parse(r),a=Date.now();if(a>i.expiresAt)return await(0,f.unlink)(n).catch(()=>{}),null;let o=Math.round((i.expiresAt-a)/1e3);return this.logger.debug(`Remote config cache hit for ${e} (expires in ${o}s)`),i.data}catch(t){return this.logger.warn(`Failed to read remote config cache for ${e}`,t),null}}async set(e,t){if(this.writeEnabled)try{await this.ensureCacheDir();let n=this.generateCacheKey(e),r=this.getCacheFilePath(n),i=Date.now(),a={data:t,timestamp:i,expiresAt:i+this.cacheTTL,url:e};await(0,f.writeFile)(r,JSON.stringify(a,null,2),`utf-8`),this.logger.debug(`Cached remote config for ${e} (TTL: ${Math.round(this.cacheTTL/1e3)}s)`)}catch(t){this.logger.warn(`Failed to write remote config cache for ${e}`,t)}}async clear(e){try{let t=this.generateCacheKey(e),n=this.getCacheFilePath(t);(0,c.existsSync)(n)&&(await(0,f.unlink)(n),this.logger.info(`Cleared remote config cache for ${e}`))}catch(t){this.logger.warn(`Failed to clear remote config cache for ${e}`,t)}}async clearAll(){try{if(!(0,c.existsSync)(this.cacheDir))return;let e=await(0,f.readdir)(this.cacheDir),t=e.filter(e=>e.endsWith(`.json`)).map(e=>(0,f.unlink)((0,l.join)(this.cacheDir,e)).catch(t=>{this.logger.debug(`Failed to delete remote config cache file ${e}`,t)}));await Promise.all(t),this.logger.info(`Cleared all remote config cache entries (${e.length} files)`)}catch(e){this.logger.warn(`Failed to clear all remote config cache`,e)}}async cleanExpired(){try{if(!(0,c.existsSync)(this.cacheDir))return;let e=Date.now(),t=(await(0,f.readdir)(this.cacheDir)).filter(e=>e.endsWith(`.json`)),n=(await Promise.all(t.map(async t=>{let n=(0,l.join)(this.cacheDir,t);try{let t=await(0,f.readFile)(n,`utf-8`),r=JSON.parse(t);return e>r.expiresAt&&(await(0,f.unlink)(n),!0)}catch(e){return await(0,f.unlink)(n).catch(()=>{this.logger.debug(`Failed to delete corrupt cache file ${n}`,e)}),this.logger.warn(`Removed unreadable remote config cache file ${n}`,e),!0}}))).filter(Boolean).length;n>0&&this.logger.info(`Cleaned up ${n} expired remote config cache entries`)}catch(e){this.logger.warn(`Failed to clean expired remote config cache`,e)}}async getStats(){try{if(!(0,c.existsSync)(this.cacheDir))return{totalEntries:0,totalSize:0};let e=(await(0,f.readdir)(this.cacheDir)).filter(e=>e.endsWith(`.json`)),t=(await Promise.all(e.map(async e=>{let t=(0,l.join)(this.cacheDir,e);try{let e=await(0,f.readFile)(t,`utf-8`);return Buffer.byteLength(e,`utf-8`)}catch{return 0}}))).reduce((e,t)=>e+t,0);return{totalEntries:e.length,totalSize:t}}catch(e){return this.logger.warn(`Failed to get remote config cache stats`,e),{totalEntries:0,totalSize:0}}}isReadEnabled(){return this.readEnabled}isWriteEnabled(){return this.writeEnabled}setReadEnabled(e){this.readEnabled=e}setWriteEnabled(e){this.writeEnabled=e}};function bt(e,t){let n=e?.url,r=t?.url;return typeof n==`string`&&typeof r==`string`&&n!==r}function R(e,t){return e?t?{...e,...t}:e:t}function xt(e){return e.configSources?.length?e.configSources:e.configFilePath?[{path:e.configFilePath}]:[]}var St=class{configSources;cacheTtlMs;cachedConfig=null;lastFetchTime=0;remoteConfigCache;logger;env;constructor(e,t=console){this.env=e.env??process.env,this.configSources=xt(e),this.cacheTtlMs=e.cacheTtlMs||6e4,this.logger=t;let n=e.useCache===void 0||e.useCache;if(this.remoteConfigCache=new yt({ttl:e.remoteCacheTtlMs||36e5,readEnabled:n,writeEnabled:!0},t),this.configSources.length===0)throw Error(`configFilePath or configSources must be provided`)}async fetchConfiguration(e=!1){let t=Date.now();if(!e&&this.cachedConfig&&t-this.lastFetchTime<this.cacheTtlMs)return this.cachedConfig;let n=null,r=[],i=[];for(let e of this.configSources){let t=await this.loadRawConfigFromSource(e);if(t===null){i.push(e.path);continue}if((e.format??`claude`)===`claude`){let e=t;e.remoteConfigs&&r.push(...e.remoteConfigs)}let a=await this.parseConfig(t,e);n=n===null?a:this.mergeConfigurations(n,a,e.mergeStrategy??`remote-priority`)}if(n===null)throw Error(`Config file not found or empty: ${i.join(`, `)}`);let a=r.map(async e=>{try{return qe(e,this.env),{config:await this.loadFromUrl(e),mergeStrategy:e.mergeStrategy||`local-priority`,url:e.url}}catch(t){return this.logger.warn(`Failed to fetch remote config from ${e.url}`,t),null}}),o=await Promise.all(a);for(let e of o)e!==null&&(n=this.mergeConfigurations(n,e.config,e.mergeStrategy));if(!n.mcpServers||typeof n.mcpServers!=`object`)throw Error(`Invalid MCP configuration: missing or invalid mcpServers`);return this.cachedConfig=n,this.lastFetchTime=t,n}async loadRawConfigFromSource(e){if(!(0,c.existsSync)(e.path)){if(e.optional)return null;throw Error(`Config file not found: ${e.path}`)}try{let t=await(0,f.readFile)(e.path,`utf-8`);if(t.trim()===``)return null;if(e.path.endsWith(`.yaml`)||e.path.endsWith(`.yml`)){let e=v.loadAll(t);if(e.length>1)throw new v.YAMLException(`expected a single document in the stream, but found more`);return e[0]??null}return JSON.parse(t)??null}catch(t){throw t instanceof Error?Error(`Failed to load config file ${e.path}: ${t.message}`):Error(`Failed to load config file ${e.path}: Unknown error`)}}async parseConfig(e,t){try{if((t.format??`claude`)===`internal`)return gt.parse(e);let{remoteConfigs:n,...r}=e;return vt(r,this.env)}catch(e){throw e instanceof Error?Error(`Failed to parse config: ${e.message}`):Error(`Failed to parse config: Unknown error`)}}async loadFromUrl(e){try{let t=this.interpolateEnvVars(e.url),n=await this.remoteConfigCache.get(t);if(n)return n;let r=e.headers?Object.fromEntries(Object.entries(e.headers).map(([e,t])=>[e,this.interpolateEnvVars(t)])):{},i=await fetch(t,{headers:r,signal:AbortSignal.timeout(3e4)});if(!i.ok)throw Error(`Failed to fetch remote config: ${i.status} ${i.statusText}`);let a=vt(await i.json());return await this.remoteConfigCache.set(t,a),a}catch(t){throw t instanceof Error?Error(`Failed to fetch remote config from ${e.url}: ${t.message}`,{cause:t}):Error(`Failed to fetch remote config from ${e.url}: Unknown error`)}}interpolateEnvVars(e){return e.replace(/\$\{([^}]+)\}/g,(e,t)=>{let n=this.env[t];return n===void 0?(this.logger.warn(`Environment variable ${t} is not defined, keeping placeholder`),`\${${t}}`):n})}mergeConfigurations(e,t,n){switch(n){case`local-priority`:return{id:e.id??t.id,proxy:R(t.proxy,e.proxy),mcpServers:{...t.mcpServers,...e.mcpServers},skills:R(t.skills,e.skills)};case`remote-priority`:return{id:t.id??e.id,proxy:R(e.proxy,t.proxy),mcpServers:{...e.mcpServers,...t.mcpServers},skills:R(e.skills,t.skills)};case`merge-deep`:{let n={...t.mcpServers};for(let[t,r]of Object.entries(e.mcpServers))if(n[t]){let e=n[t],i={...e.config,...r.config},a=`env`in e.config?e.config.env:void 0,o=`env`in r.config?r.config.env:void 0;(a||o)&&(i.env={...a,...o});let s=`headers`in e.config?e.config.headers:void 0,c=`headers`in r.config?r.config.headers:void 0;(s||c)&&(i.headers=bt(e.config,r.config)?{...c}:{...s,...c}),n[t]={...e,...r,config:i}}else n[t]=r;return{id:e.id??t.id,proxy:R(t.proxy,e.proxy),mcpServers:n,skills:R(t.skills,e.skills)}}default:throw Error(`Unknown merge strategy: ${String(n)}`)}}clearCache(){this.cachedConfig=null,this.lastFetchTime=0}isCacheValid(){let e=Date.now();return this.cachedConfig!==null&&e-this.lastFetchTime<this.cacheTtlMs}};const Ct=`[capability-discovery]`;function wt(e,t=[]){return[...t,e]}function Tt(e){return e?Array.isArray(e)?e:[e]:[]}function Et(e){return e.map(e=>({path:e}))}function Dt(){let e=[`mcp-config.yaml`,`mcp-config.yml`,`mcp-config.json`],t=process.env.PROJECT_PATH;if(t)for(let n of e){let e=(0,l.resolve)(t,n);if((0,c.existsSync)(e))return e}let n=process.cwd();for(let t=0;t<=3;t++){for(let t of e){let e=(0,l.join)(n,t);if((0,c.existsSync)(e))return e}let t=(0,l.dirname)(n);if(t===n)break;n=t}return null}function Ot(e=6){let t=``,n=e;for(;n>0;){let e=(0,u.randomBytes)(n);for(let r=0;r<e.length&&n>0;r++){let i=e[r];i>247||(t+=`23456789abcdefghjkmnpqrstuvwxyz`[i%31],n--)}}return t}function kt(e){let t=e.trimStart();if(!t.startsWith(`---`))return{frontMatter:null,content:e};let n=t.indexOf(`
2
+ ---`,3);if(n===-1)return{frontMatter:null,content:e};let r=t.slice(4,n).trim();if(!r)return{frontMatter:null,content:e};let i={},a=r.split(`
3
+ `),o=null,s=[],c=null,l=0,u=()=>{o&&s.length>0&&(c===`literal`?i[o]=s.join(`
4
+ `).trimEnd():c===`folded`?i[o]=s.join(` `).trim():i[o]=s.join(``).trim()),o=null,s=[],c=null,l=0};for(let e=0;e<a.length;e++){let t=a[e],n=t.trim(),r=t.indexOf(`:`);if(r!==-1&&!t.startsWith(` `)&&!t.startsWith(` `)){u();let n=t.slice(0,r).trim(),s=t.slice(r+1).trim();if(s===`|`||s===`|-`){if(o=n,c=`literal`,e+1<a.length){let t=a[e+1].match(/^(\s+)/);l=t?t[1].length:2}}else if(s===`>`||s===`>-`){if(o=n,c=`folded`,e+1<a.length){let t=a[e+1].match(/^(\s+)/);l=t?t[1].length:2}}else(s.startsWith(`"`)&&s.endsWith(`"`)||s.startsWith(`'`)&&s.endsWith(`'`))&&(s=s.slice(1,-1)),n&&s&&(i[n]=s)}else if(c&&o){let e=t.match(/^(\s*)/)?.[1].length||0;if(n===``)s.push(``);else if(e>=l){let e=t.slice(l);s.push(e)}else u()}}return u(),{frontMatter:i,content:t.slice(n+4).trimStart()}}function At(e){return e!==null&&typeof e.name==`string`&&e.name.length>0&&typeof e.description==`string`&&e.description.length>0}function jt(e){let{frontMatter:t,content:n}=kt(e);return t&&At(t)?{skill:{name:t.name,description:t.description},content:n}:null}function z(e){let t=e.indexOf(`__`);return t>0?{serverName:e.substring(0,t),actualToolName:e.substring(t+2)}:{actualToolName:e}}async function Mt(e,t){try{await t()}catch(t){console.error(`[mcp-proxy] ${e} cleanup failed: ${t instanceof Error?t.message:String(t)}`)}}async function Nt(){await Promise.all([Mt(`Process registry`,async()=>new _.ProcessRegistryService(process.env.PROCESS_REGISTRY_PATH).cleanupStaleProcesses()),Mt(`Port registry`,async()=>new x.PortRegistryService(process.env.PORT_REGISTRY_PATH).cleanupStaleAllocations())])}function Pt(e){return e.endsWith(`.yaml`)||e.endsWith(`.yml`)}function B(e){return e instanceof Error?e.message:String(e)}function Ft(e){return(e instanceof b.ProtocolError||typeof e==`object`&&!!e&&`code`in e)&&e.code===b.METHOD_NOT_FOUND}function It(e){let t=(0,l.resolve)(e),n=t.length>=2&&t[1]===`:`&&(t[0]>=`A`&&t[0]<=`Z`||t[0]>=`a`&&t[0]<=`z`)?`${t[0].toLowerCase()}${t.slice(1)}`:t,r=``,i=!1;for(let e of n)e>=`a`&&e<=`z`||e>=`A`&&e<=`Z`||e>=`0`&&e<=`9`||e===`.`||e===`_`||e===`-`?(r+=e,i=!1):i||=(r+=`_`,!0);let a=0,o=r.length;for(;a<o&&r[a]===`_`;)a+=1;for(;o>a&&r[o-1]===`_`;)--o;return r.slice(a,o)}function V(e){return{...e,failures:[...e.failures??[]],skills:(e.skills??[]).map(e=>({...e})),servers:Object.fromEntries(Object.entries(e.servers).map(([e,t])=>[e,{...t,tools:(t.tools??[]).map(e=>({...e})),resources:(t.resources??[]).map(e=>({...e})),prompts:(t.prompts??[]).map(e=>({...e,arguments:e.arguments?.map(e=>({...e}))})),promptSkills:(t.promptSkills??[]).map(e=>({...e,skill:{...e.skill}})),capabilityDiscovery:t.capabilityDiscovery?{resources:{...t.capabilityDiscovery.resources},prompts:{...t.capabilityDiscovery.prompts}}:void 0}]))}}var Lt=class extends Error{constructor(){super(`Definitions cache uses an incompatible format and must be refreshed`),this.name=`DefinitionsCacheVersionError`}},H=class e{clientManager;skillService;cacheData;liveDefinitionsPromise=null;mergedDefinitionsPromise=null;logger;constructor(t,n,r,i=console){this.clientManager=t,this.skillService=n,this.cacheData=r?.cacheData&&e.isCacheValid(r.cacheData,{})?r.cacheData:void 0,this.logger=i}static async readFromFile(e){let t=await(0,f.readFile)(e,`utf-8`),n=Pt(e)?v.load(t):JSON.parse(t);if(!n||typeof n!=`object`)throw Error(`Definitions cache must be an object`);let r=n;if(r.version!==2)throw new Lt;if(!r.servers||typeof r.servers!=`object`||Array.isArray(r.servers))throw Error(`Definitions cache is missing required fields`);return{...r,failures:Array.isArray(r.failures)?r.failures:[],skills:Array.isArray(r.skills)?r.skills:[],servers:Object.fromEntries(Object.entries(r.servers).map(([e,t])=>[e,{...t,tools:Array.isArray(t.tools)?t.tools:[],resources:Array.isArray(t.resources)?t.resources:[],prompts:Array.isArray(t.prompts)?t.prompts:[],promptSkills:Array.isArray(t.promptSkills)?t.promptSkills:[]}]))}}static async inspectFile(t,n){try{let r=await e.readFromFile(t);return e.isCacheValid(r,n)?{state:`usable`,cachePath:t,cache:r}:{state:`invalid`,cachePath:t,reason:`metadata_mismatch`}}catch(e){return e.code===`ENOENT`?{state:`absent`,cachePath:t}:e instanceof Lt?{state:`invalid`,cachePath:t,reason:`incompatible_schema`}:{state:`invalid`,cachePath:t,reason:`unreadable`,error:B(e)}}}static async writeToFile(e,t){let n=Pt(e)?v.dump(t,{noRefs:!0}):JSON.stringify(t,null,2);await(0,f.mkdir)((0,l.dirname)(e),{recursive:!0}),await(0,f.writeFile)(e,n,`utf-8`)}static getDefaultCachePath(e){let t=Array.isArray(e)?e:[e];if(t.length===0)throw Error(`getDefaultCachePath requires at least one config path`);let n=It(t[0]);if(t.length===1)return(0,l.join)((0,p.homedir)(),`.mcp-proxy`,`${n}.definitions-cache.json`);let r=(0,u.createHash)(`sha256`).update(t.map(e=>(0,l.resolve)(e)).join(`\0`)).digest(`hex`).slice(0,12);return(0,l.join)((0,p.homedir)(),`.mcp-proxy`,`${n}.${r}.definitions-cache.json`)}static generateConfigHash(e){return(0,u.createHash)(`sha256`).update(JSON.stringify(e)).digest(`hex`)}static isCacheValid(e,t){return!(e.version!==2||t.configHash&&e.configHash!==t.configHash||t.oneMcpVersion&&e.oneMcpVersion!==t.oneMcpVersion)}static async clearFile(e){await(0,f.rm)(e,{force:!0})}clearLiveCache(){this.liveDefinitionsPromise=null,this.mergedDefinitionsPromise=null}setCacheData(t){this.cacheData=t&&e.isCacheValid(t,{})?t:void 0,this.mergedDefinitionsPromise=null}async collectForCache(e){let t=await this.collectLiveDefinitions(e);return this.setCacheData(t),this.liveDefinitionsPromise=Promise.resolve(V(t)),V(t)}logCapabilitySummary(e,t){let n=Object.values(e.servers).map(e=>({serverName:e.serverName,tools:e.tools.length,resources:{state:e.capabilityDiscovery?.resources.state??`unknown`,count:e.resources.length,error:e.capabilityDiscovery?.resources.error},prompts:{state:e.capabilityDiscovery?.prompts.state??`unknown`,count:e.prompts.length,error:e.capabilityDiscovery?.prompts.error}})),r=n.some(e=>e.resources.state===`degraded`||e.prompts.state===`degraded`),i={source:t,servers:n,failures:e.failures,degraded:r||e.failures.length>0};i.degraded?this.logger.warn(`${Ct} MCP server capability summary`,i):this.logger.info(`${Ct} MCP server capability summary`,i)}async getDefinitions(){return this.mergedDefinitionsPromise||=(async()=>{let e=this.clientManager.getAllClients();if(!this.cacheData)return this.getLiveDefinitions();let t=e.map(e=>e.serverName).filter(e=>!this.cacheData?.servers[e]);if(t.length===0)return V(this.cacheData);let n=await this.getLiveDefinitions(),r=V(this.cacheData);for(let e of t){let t=n.servers[e];t&&(r.servers[e]=t)}let i=/* @__PURE__ */ new Map;for(let e of[...r.failures,...n.failures])i.set(e.serverName,e.error);return r.failures=Array.from(i.entries()).map(([e,t])=>({serverName:e,error:t})),r.skills.length===0&&n.skills.length>0&&(r.skills=n.skills.map(e=>({...e}))),r})(),this.mergedDefinitionsPromise}async getServerDefinitions(){let e=await this.getDefinitions(),t=this.clientManager.getKnownServerNames();return t.length===0?Object.values(e.servers):t.map(t=>e.servers[t]).filter(e=>e!==void 0)}async getServersForTool(e){return(await this.getServerDefinitions()).filter(t=>t.tools.some(t=>t.name===e)).map(e=>e.serverName)}async getToolSchema(e,t){return(await this.getDefinitions()).servers[e]?.tools.find(e=>e.name===t)?.inputSchema}async getServersForResource(e){return(await this.getServerDefinitions()).filter(t=>t.resources.some(t=>t.uri===e)).map(e=>e.serverName)}async getPromptSkillByName(e){let t=await this.getDefinitions();for(let[n,r]of Object.entries(t.servers))for(let t of r.promptSkills)if(t.skill.name===e)return{serverName:n,promptName:t.promptName,skill:t.skill,autoDetected:t.autoDetected}}async getCachedFileSkills(){return(await this.getDefinitions()).skills.map(e=>({...e}))}async getLiveDefinitions(){return this.liveDefinitionsPromise||=this.collectLiveDefinitions(),this.liveDefinitionsPromise}async collectLiveDefinitions(e){let t=this.clientManager.getAllClients().filter(t=>e?.serverNames===void 0||e.serverNames.includes(t.serverName)),n=[],r={},i=await Promise.all(t.map(async e=>{try{let t=await e.listTools(),n=e.getServerCapabilities?.(),r=await this.listResourcesSafe(e,n?n.resources!==void 0:void 0),i=await this.listPromptsSafe(e,n?n.prompts!==void 0:void 0),a=new Set(e.toolBlacklist||[]),o=t.filter(e=>!a.has(e.name)),s=await this.collectPromptSkillsForClient(e,i.items);return{serverName:e.serverName,serverInstruction:e.serverInstruction,omitToolDescription:e.omitToolDescription,toolBlacklist:e.toolBlacklist,tools:o.map(e=>({name:e.name,description:e.description,inputSchema:e.inputSchema,_meta:e._meta})),resources:r.items,prompts:i.items,promptSkills:s,capabilityDiscovery:{resources:{state:r.state,error:r.error},prompts:{state:i.state,error:i.error}}}}catch(t){return n.push({serverName:e.serverName,error:B(t)}),null}}));for(let e of i)e&&(r[e.serverName]=e);let a={version:2,oneMcpVersion:e?.oneMcpVersion,generatedAt:(/* @__PURE__ */ new Date()).toISOString(),configPath:e?.configPath,configHash:e?.configHash,serverId:e?.serverId,servers:r,skills:await this.collectFileSkills(),failures:n};return this.logCapabilitySummary(a,`live`),a}async collectFileSkills(){return this.skillService?(await this.skillService.getSkills()).map(e=>this.toCachedFileSkill(e)):[]}toCachedFileSkill(e){return{name:e.name,description:e.description,location:e.location,basePath:e.basePath}}async listPromptsSafe(e,t){if(t===!1)return{items:[],state:`unsupported`};try{return{state:`available`,items:(await e.listPrompts()).map(e=>({name:e.name,description:e.description,arguments:e.arguments?.map(e=>({...e}))}))}}catch(e){return Ft(e)?{items:[],state:`unsupported`}:{items:[],state:`degraded`,error:B(e)}}}async listResourcesSafe(e,t){if(t===!1)return{items:[],state:`unsupported`};try{return{state:`available`,items:(await e.listResources()).map(e=>({uri:e.uri,name:e.name,description:e.description,mimeType:e.mimeType}))}}catch(e){return Ft(e)?{items:[],state:`unsupported`}:{items:[],state:`degraded`,error:B(e)}}}async collectPromptSkillsForClient(e,t){let n=new Set(e.prompts?Object.keys(e.prompts):[]),r=[];if(e.prompts)for(let[t,n]of Object.entries(e.prompts))n.skill&&r.push({promptName:t,skill:{...n.skill}});let i=t.filter(e=>!n.has(e.name)).slice(0,50),a=await Promise.all(i.map(async t=>{try{let n=jt((await e.getPrompt(t.name)).messages?.map(e=>{let t=e.content;return typeof t==`string`?t:t&&typeof t==`object`&&`text`in t?String(t.text):``}).join(`
5
+ `)||``);return n?{promptName:t.name,skill:n.skill,autoDetected:!0}:null}catch(n){return this.logger.warn(`[skill-detection] Failed to fetch prompt '${t.name}' from ${e.serverName}: ${B(n)}`),null}}));for(let e of a)e&&r.push(e);return r}};function Rt(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function zt(e){if(typeof e==`string`||typeof e==`number`||typeof e==`boolean`||Array.isArray(e)&&e.every(e=>typeof e==`string`)||Array.isArray(e)&&e.every(e=>typeof e==`number`)||Array.isArray(e)&&e.every(e=>typeof e==`boolean`))return e;try{return JSON.stringify(e)??String(e)}catch{return String(e)}}function Bt(e){return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,zt(t)]))}function U(e){if(e!==void 0)return e instanceof Error?{exception:e}:Rt(e)&&(`attributes`in e||`exception`in e||`context`in e)?e:Rt(e)?{attributes:Bt(e)}:{attributes:{value:zt(e)}}}function Vt(e){let t=e.logger;return{backend:e.backend,enabled:e.enabled,endpoint:e.endpoint,tracesEndpoint:e.tracesEndpoint,logsEndpoint:e.logsEndpoint,endpointSource:e.endpointSource,filePath:e.filePath,trace(e,n){t.trace(e,U(n))},debug(e,n){t.debug(e,U(n))},info(e,n){t.info(e,U(n))},warn(e,n){t.warn(e,U(n))},error(e,n){t.error(e,U(n))},getTraceContext(){return e.getTraceContext()},runInSpan:(t,n,r)=>e.runInSpan(t,n,r),flush:()=>e.flush(),shutdown:()=>e.shutdown()}}async function Ht(e={}){return Vt(await(0,S.createNodeTelemetry)({env:e.env,workspaceRoot:e.workspaceRoot,packageName:e.packageName??`@agimon-ai/po-mcp-proxy`,serviceName:e.serviceName??`@agimon-ai/mcp-proxy`,serviceVersion:e.serviceVersion,logDir:e.logDir,logFileName:e.logFileName,maxFileSizeBytes:e.maxFileSizeBytes,maxFileCount:e.maxFileCount}))}var Ut=class{provider;serverUrl;signal;sentToken;retryAfter=0;challenge={};constructor(e,t,n){this.provider=e,this.serverUrl=t,this.signal=n}async authorize(e={},t=this.signal){t?.throwIfAborted(),await this.provider.tokens();let n=e.fetchFn??this.challenge.fetchFn??fetch,r=await(0,w.auth)(this.provider,{serverUrl:this.serverUrl,...this.challenge,...e,fetchFn:t?(e,r)=>n(e,{...r,signal:r?.signal?AbortSignal.any([t,r.signal]):t}):n});if(t?.throwIfAborted(),r!==`AUTHORIZED`)throw new w.UnauthorizedError}async token(){let e=await this.provider.readCredential(),t=e?.tokens?.expires_in,n=typeof t==`number`&&Number.isFinite(t)&&t>0?Math.min(6e4,t*500):0;if(e?.tokens?.refresh_token&&e.expiresAt!==void 0&&Number.isFinite(e.expiresAt)&&Date.now()>=e.expiresAt-n&&Date.now()>=this.retryAfter&&!this.provider.hasPendingAuthorization())try{await this.provider.withCredentialLock(async()=>{let e=await this.provider.readCredential();e?.expiresAt!==void 0&&Date.now()>=e.expiresAt-n&&await this.authorize()},this.signal)}catch(e){if(e instanceof w.UnauthorizedError||this.signal?.aborted)throw e;this.retryAfter=Date.now()+3e4}return this.sentToken=(await this.provider.tokens())?.access_token,this.sentToken}async onUnauthorized(e){let t=this.sentToken;this.challenge={...(0,w.extractWWWAuthenticateParams)(e.response),fetchFn:e.fetchFn},await this.provider.withCredentialLock(async()=>{let e=await this.provider.readCredential();if(!(e?.tokens?.access_token&&e.tokens.access_token!==t)){if(this.provider.hasPendingAuthorization())throw new w.UnauthorizedError;await this.authorize()}},this.signal)}async recover(e,t,n){if(t?.throwIfAborted(),e instanceof w.InsufficientScopeError&&await this.provider.withCredentialLock(async()=>{let n=await this.provider.tokens();this.provider.prepareInteractiveGrant(),this.challenge={...this.challenge,scope:(0,w.computeScopeUnion)(n?.scope,e.requiredScope),resourceMetadataUrl:e.resourceMetadataUrl,forceReauthorization:!0};try{await this.authorize({},t)}catch(e){if(!(e instanceof w.UnauthorizedError)||!this.provider.hasPendingAuthorization())throw e}},t),!this.provider.hasPendingAuthorization())return;let r=()=>this.provider.cancelAuthorization();t?.addEventListener(`abort`,r,{once:!0});try{let e=await this.provider.waitForAuthorizationCallback();t?.throwIfAborted(),n?.(),await this.provider.withCredentialLock(async()=>{let n=await this.provider.discoveryState(),r=n?.authorizationServerMetadata;(0,w.validateAuthorizationResponseIssuer)({iss:e.get(`iss`)??void 0,expectedIssuer:r?.issuer??n?.authorizationServerUrl,issParameterSupported:r?.authorization_response_iss_parameter_supported===!0}),await this.authorize({authorizationCode:e.get(`code`)??void 0,iss:e.get(`iss`)??void 0,forceReauthorization:!1},t)},t)}finally{t?.removeEventListener(`abort`,r)}}};function Wt(e){let t=typeof e==`object`&&e?e:void 0;return{enabled:on(`MCP_OUTPUT_GUARD`)??e!==!1,maxBytes:t?.maxBytes,maxLines:t?.maxLines,structuredMaxBytes:t?.structuredMaxBytes}}var W=class{enabled;maxBytes;maxLines;structuredMaxBytes;constructor(e={}){this.enabled=e.enabled??on(`MCP_OUTPUT_GUARD`)??!0,this.maxBytes=an(e.maxBytes)??51200,this.maxLines=an(e.maxLines)??2e3,this.structuredMaxBytes=an(e.structuredMaxBytes)??16384}isEnabled(){return this.enabled}async guard(e){if(!this.enabled)return e;let t=await this.guardContent(e);return await this.guardStructuredContent(t)}async guardContent(e){let t=Array.isArray(e.content)?e.content:[],n=t.filter(e=>e.type===`text`),r=t.filter(e=>e.type!==`text`),i=n.map(e=>typeof e.text==`string`?e.text:``).join(`
6
+ `),a=nn(i);if(a.bytes<=this.maxBytes&&a.lines<=this.maxLines)return e;let{path:o,error:s}=await $t(`output`,i),c=Jt(a,o,s),l=Gt(this.maxBytes,this.maxLines,c),u=`${Kt(i,l.maxBytes,l.maxLines)}\n\n${c}`,d=nn(u),f=r.filter(e=>e.type===`image`).length,p={truncated:!0,originalBytes:a.bytes,returnedBytes:d.bytes,originalLines:a.lines,returnedLines:d.lines,...f>0?{imageBlocksPassedThrough:f}:{},...o?{fullOutputPath:o}:{},...s?{writeError:s}:{}};return{...e,content:[{type:`text`,text:u},...r],_meta:{...e._meta,"agiflowai/outputGuard":p}}}async guardStructuredContent(e){if(e.structuredContent===void 0)return e;let t=tn(e.structuredContent),n=rn(t);if(n<=this.structuredMaxBytes)return e;let{path:r,error:i}=await $t(`structured-content`,t);return{...e,structuredContent:{omitted:!0,reason:`structuredContent exceeded the size limit and was replaced with this summary to keep the caller context bounded.`,rawBytes:n,summary:Yt(e.structuredContent),...r?{fullResultPath:r}:{},...i?{resultWriteError:i}:{}}}}};function Gt(e,t,n){let r=nn(`\n\n${n}`);return{maxBytes:Math.max(0,e-r.bytes),maxLines:Math.max(0,t-r.lines)}}function Kt(e,t,n){let r=e.split(`
7
+ `),i=[],a=0;for(let e of r){if(i.length>=n)break;let r=+(i.length>0),o=rn(e);if(a+r+o>t){let n=t-a-r;n>0&&i.push(qt(e,n));break}i.push(e),a+=r+o}return i.join(`
8
+ `)}function qt(e,t){if(rn(e)<=t)return e;let n=Buffer.from(e,`utf8`),r=Math.max(0,t);for(;r>0&&(n[r]&192)==128;)r--;return n.subarray(0,r).toString(`utf8`)}function Jt(e,t,n){let r=`[MCP tool output truncated: original ${e.lines.toLocaleString()} lines / ${sn(e.bytes)}.`;return t?`${r} Full text saved to: ${t}]`:`${r} Full output could not be saved: ${n??`unknown error`}]`}function Yt(e){let t=en(e);if(!t)return{type:e===null?`null`:typeof e,omitted:!0};let n=Object.keys(t);return{type:Array.isArray(e)?`array`:`object`,keyCount:Array.isArray(e)?e.length:n.length,keysPreview:n.slice(0,20).map(Xt),...Array.isArray(e)&&e.length>20?{itemsOmitted:e.length-20}:{},omitted:!0}}function Xt(e){return e.length<=120?e:`${e.slice(0,119)}…`}let Zt;function Qt(){return Zt??=(0,f.mkdtemp)((0,l.join)((0,p.tmpdir)(),`mcp-proxy-output-`)),Zt}async function $t(e,t){try{let n=await Qt(),r=(0,l.join)(n,`${e}-${(0,u.randomBytes)(8).toString(`hex`)}.txt`);return await(0,f.writeFile)(r,t,{encoding:`utf8`,mode:384}),{path:r}}catch(e){return Zt=void 0,{error:e instanceof Error?e.message:String(e)}}}function en(e){return typeof e==`object`&&e?e:void 0}function tn(e){try{return JSON.stringify(e)??``}catch{return``}}function nn(e){return{bytes:rn(e),lines:e.length===0?0:e.split(`
9
+ `).length}}function rn(e){return Buffer.byteLength(e,`utf8`)}function an(e){if(typeof e!=`number`||!Number.isFinite(e))return;let t=Math.floor(e);return t>0?t:void 0}function on(e){let t=process.env[e]?.trim().toLowerCase();if(t){if([`0`,`false`,`no`,`off`].includes(t))return!1;if([`1`,`true`,`yes`,`on`].includes(t))return!0}}function sn(e){return e<1024?`${e} B`:e<1048576?`${(e/1024).toFixed(1)} KiB`:`${(e/1048576).toFixed(1)} MiB`}const G=`x-mcp-proxy-original-output-schema`;function cn(e){return Array.from(e.slice(0,256)).filter(e=>{let t=e.charCodeAt(0);return t>=32&&t<=126||t>=160}).join(``)}var ln=class extends w.Client{serverName;compatibility;calls;constructor(e,t,n,r){let i=new te.AsyncLocalStorage,a=new T.AjvJsonSchemaValidator;super(e,{...t,jsonSchemaValidator:{getValidator:e=>t=>{let n=i.getStore()?.toolName,r=Object.hasOwn(e,G)?e[G]:e;try{!a.getValidator(r)(t).valid&&n&&this.warn(n,`tools/call`,`structuredContent`,`Structured output does not match its output schema.`)}catch{n&&this.warn(n,`tools/call`,`outputSchema`,`Output schema could not be compiled or evaluated.`)}return{valid:!0,data:t,errorMessage:void 0}}}}),this.serverName=n,this.compatibility=r,this.calls=i}warn(e,t,n,r){try{Promise.resolve(this.compatibility.onWarning({serverName:cn(this.serverName),toolName:cn(e),method:t,path:n,message:r})).catch(()=>{})}catch{}}request(e,t,n){if(t&&`~standard`in t)return super.request(e,t,n);if(e.method!==`tools/list`){let n=super.request(e,t);return e.method===`tools/call`?n.then(e=>{let t=this.calls.getStore();return t&&(t.result=e),e}):n}return super.request(e,{"~standard":{version:1,vendor:`mcp-proxy-output-compatibility`,validate:e=>this.validateListing(e)}},t)}validateListing(e){if(!e||typeof e!=`object`||!(`tools`in e)||!Array.isArray(e.tools))return{issues:[{message:`Invalid tools/list result`}]};let t=e.tools,n=t.map(e=>{if(!e||typeof e!=`object`)return e;let{outputSchema:t,...n}=e;return n}),r=this._wireCodec().validateResult(`tools/list`,{...e,tools:n});if(!r.ok)return{issues:[{message:`Invalid non-output tools/list descriptor`}]};for(let[e,n]of r.value.tools.entries()){let r=t[e];Object.hasOwn(r,`outputSchema`)&&(n.outputSchema={type:`object`,[G]:r.outputSchema},this._wireCodec().validateResult(`tools/list`,{tools:[r]}).ok||this.warn(n.name,`tools/list`,`tools/${e}/outputSchema`,`Output schema descriptor is not MCP-compatible.`))}return{value:r.value}}async listTools(e,t){let n=await super.listTools(e,t);return{...n,tools:n.tools.map(e=>e.outputSchema&&Object.hasOwn(e.outputSchema,G)?{...e,outputSchema:e.outputSchema[G]}:e)}}async callTool(e,t){let n={toolName:e.name,result:void 0};return this.calls.run(n,async()=>{try{return await super.callTool(e,t)}catch(t){if(!(t instanceof w.ProtocolError)||t.code!==w.ProtocolErrorCode.InvalidRequest||t.message!==`Tool ${e.name} has an output schema but did not return structured content`||!n.result||n.result.structuredContent!==void 0||n.result.isError)throw t;return this.warn(e.name,`tools/call`,`structuredContent`,`Tool omitted structured output required by its output schema.`),n.result}})}};const un=`mcp-proxy-client-manager`,dn=[0,100];function fn(e){return e===`reconnecting`?`connecting`:e}var pn=class extends Error{serverName;attempts;code=`MCP_SERVER_RECOVERY_EXHAUSTED`;constructor(e,t,n){super(`MCP server "${e}" did not recover after ${t} attempts.`,n),this.serverName=e,this.attempts=t,this.name=`McpServerRecoveryExhaustedError`}};async function mn(e){let t=await Promise.allSettled([Promise.resolve().then(()=>e.client.close()),Promise.resolve().then(()=>e.stdioTransport?.close())]);try{await e.processLease?.release({kill:!1,releasePort:!1})}catch(e){t.push({status:`rejected`,reason:e})}let n=t.flatMap(e=>e.status===`rejected`?[e.reason]:[]);if(n.length)throw AggregateError(n,`MCP connection cleanup failed`)}function hn(e){return bn(e).some(({message:e,code:t})=>{let n=e.toLowerCase(),r=vn(t);return n.includes(`unknown session`)||n.includes(`session not found`)||n.includes(`transport closed`)||n.includes(`connection closed`)||n.includes(`socket hang up`)||n.includes(`fetch failed`)||r===`econnreset`})}function gn(e){return e instanceof w.UnauthorizedError||bn(e).some(({message:e,code:t})=>{let n=e.toLowerCase();return t===`401`||n.includes(`unauthorized`)||n.includes(`http 401`)||n.includes(`invalid_token`)})}function _n(e){return bn(e).some(({message:e,code:t})=>{let n=e.toLowerCase(),r=vn(t);return n.includes(`transport closed`)||n.includes(`connection closed`)||n.includes(`premature close`)||n.includes(`socket hang up`)||n.includes(`write epipe`)||n.includes(`read econnreset`)||n.includes(`fetch failed`)||r===`epipe`||r===`econnreset`})}function vn(e){return typeof e==`string`?e.toLowerCase():void 0}function yn(e){if(typeof e==`string`)return e;if(typeof e==`symbol`)return e.toString();if(typeof e==`object`&&e)try{return JSON.stringify(e)??`Unknown error`}catch{return`Unknown error`}return String(e)}function bn(e){let t=/* @__PURE__ */ new Set,n=[],r=e;for(;r&&!t.has(r);)if(t.add(r),r instanceof Error){let e=r;n.push({message:r.message,code:e.code}),r=e.cause}else if(typeof r==`object`){let e=r;n.push({message:typeof e.message==`string`?e.message:yn(r),code:typeof e.code==`string`?e.code:void 0}),r=e.cause}else{n.push({message:yn(r)});break}return n}var xn=class{outputGuard;serverName;serverInstruction;toolBlacklist;omitToolDescription;prompts;transport;logger;client;stdioTransport;processLease;connected=!1;lifecycleState=`closed`;recoveryError;reconnectFn;reconnectPromise;recoverAuthorization;authorizationRecovery;pendingLeaseRelease;onDisconnected;onLifecycleChange;closing=!1;closePromise;lifetime=new AbortController;constructor(e,t,n,r,i,a){this.outputGuard=a,this.serverName=e,this.serverInstruction=i.instruction,this.toolBlacklist=i.toolBlacklist,this.omitToolDescription=i.omitToolDescription,this.prompts=i.prompts,this.transport=t,this.logger=r,this.client=n}setAuthorizationRecovery(e){this.recoverAuthorization=e}setStdioTransport(e){this.stdioTransport=e}setProcessLease(e){this.processLease=e}setConnected(e){this.connected=e,this.setLifecycleState(e?`connected`:`closed`),e&&(this.recoveryError=void 0)}getLifecycleState(){return this.lifecycleState}setLifecycleChangeCallback(e){this.onLifecycleChange=e}setLifecycleState(e,t){this.lifecycleState!==e&&(this.lifecycleState=e,this.onLifecycleChange?.(e,t))}async waitUntilReady(){await this.ensureReady()}getServerCapabilities(){return this.client.getServerCapabilities()}setReconnectFn(e){this.reconnectFn=e}setDisconnectedCallback(e){this.onDisconnected=e}handleStdioClosed(e){if(this.stdioTransport!==e||this.closing)return;let t=this.processLease;this.stdioTransport=void 0,this.processLease=void 0,this.connected=!1,this.recoveryError=void 0,this.setLifecycleState(`reconnecting`),this.pendingLeaseRelease=this.releaseProcessLease(t),!this.closing&&(this.logger.warn(`mcp_proxy.server.disconnected`,{"mcp.server.name":this.serverName,"mcp.server.transport":this.transport,"mcp.server.lifecycle":this.lifecycleState,"mcp.server.disconnect_reason":`stdio transport closed`,"mcp.server.recovery_mode":`proactive`}),this.onDisconnected?.(this),this.reconnectClient(`stdio transport closed`).catch(()=>{}))}async releaseProcessLease(e){try{await e?.release({kill:!1,releasePort:!1})}catch(e){this.logger.warn(`Failed to release process lease for ${this.serverName}`,e)}}async releaseOwnedResources(e){let t=this.stdioTransport,n=this.processLease,r=this.pendingLeaseRelease;this.stdioTransport=void 0,this.processLease=void 0,this.pendingLeaseRelease=void 0;try{t&&e.killChild&&await t.close()}finally{await Promise.all([r,n?.release({kill:!1,releasePort:!1})])}}async reconnectClient(e=`recoverable transport error`){if(this.lifetime.signal.throwIfAborted(),!this.reconnectFn)throw Error(`No reconnect function configured for ${this.serverName}`);let t=this.reconnectFn;this.reconnectPromise||=(async()=>{this.connected=!1,this.setLifecycleState(`reconnecting`),this.recoveryError=void 0,await this.releaseOwnedResources({killChild:!0});try{await this.client.close()}catch(e){this.logger.warn(`Failed to close stale client for ${this.serverName}`,e)}let n;for(let[r,i]of dn.entries()){i>0&&await(0,C.setTimeout)(i,void 0,{signal:this.lifetime.signal}),this.lifetime.signal.throwIfAborted();try{let n=await t(this.lifetime.signal);this.closing&&(await mn(n),this.lifetime.signal.throwIfAborted()),this.client=n.client,this.recoverAuthorization=n.recoverAuthorization,n.stdioTransport&&(this.stdioTransport=n.stdioTransport),n.processLease&&(this.processLease=n.processLease),this.connected=!0,this.setLifecycleState(`connected`),this.logger.info(`mcp_proxy.server.recovered`,{"mcp.server.name":this.serverName,"mcp.server.transport":this.transport,"mcp.server.lifecycle":`connected`,"mcp.server.recovery_attempt":r+1,"mcp.server.recovery_trigger":e});return}catch(e){this.lifetime.signal.throwIfAborted(),n=e,this.logger.warn(`mcp_proxy.server.reconnect_failed`,{"mcp.server.name":this.serverName,"mcp.server.transport":this.transport,"mcp.server.recovery_attempt":r+1,"error.message":e instanceof Error?e.message:String(e)})}}throw this.connected=!1,this.recoveryError=new pn(this.serverName,dn.length,{cause:n}),this.setLifecycleState(`degraded`,this.recoveryError.message),this.logger.error(`mcp_proxy.server.degraded`,{"mcp.server.name":this.serverName,"mcp.server.transport":this.transport,"mcp.server.lifecycle":`degraded`,"mcp.server.recovery_attempts":dn.length,"error.message":n instanceof Error?n.message:String(n)}),this.recoveryError})();let n=this.reconnectPromise;try{await n}finally{this.reconnectPromise===n&&(this.reconnectPromise=void 0)}}async ensureReady(){if(this.lifetime.signal.throwIfAborted(),!this.connected){if(this.recoveryError)throw this.recoveryError;await this.reconnectClient(`operation requested while disconnected`)}}async withSessionRetry(e,t){t?.throwIfAborted(),await this.ensureReady(),t?.throwIfAborted();try{return await e()}catch(n){if(t?.throwIfAborted(),(n instanceof w.UnauthorizedError||n instanceof w.InsufficientScopeError)&&this.recoverAuthorization)return this.authorizationRecovery??=this.recoverAuthorization(n,t?AbortSignal.any([t,this.lifetime.signal]):this.lifetime.signal).then(()=>this.reconnectClient(`authorization recovered`)).finally(()=>{this.authorizationRecovery=void 0}),await this.authorizationRecovery,t?.throwIfAborted(),e();if(!this.reconnectFn||!hn(n)&&!_n(n))throw n;return this.logger.warn(`Session error for ${this.serverName}, reconnecting: ${n instanceof Error?n.message:String(n)}`),await this.reconnectClient(n instanceof Error?n.message:String(n)),t?.throwIfAborted(),await e()}}async listTools(){return this.withSessionRetry(async()=>(await this.client.listTools()).tools)}async listResources(){return this.withSessionRetry(async()=>(await this.client.listResources()).resources)}async listPrompts(){return this.withSessionRetry(async()=>(await this.client.listPrompts()).prompts)}async callTool(e,t,n){let r=n?.signal?AbortSignal.any([n.signal,this.lifetime.signal]):this.lifetime.signal,i=await this.withSessionRetry(async()=>{let i={signal:r,...n?.timeout===void 0?{}:{timeout:n.timeout}},a=await this.client.callTool({name:e,arguments:t},i);if(!(0,w.isCallToolResult)(a))throw Error(`Unexpected interactive response from MCP tool '${e}': this call requires a context-aware relay`);return a},r);if(r.throwIfAborted(),n?.onResult)try{await n.onResult(structuredClone(i))}catch(t){this.logger.warn(`MCP result observer failed for ${this.serverName}.${e}`,t)}return r.throwIfAborted(),this.outputGuard?await this.outputGuard.guard(i):i}async readResource(e,t){let n=t?.signal?AbortSignal.any([t.signal,this.lifetime.signal]):this.lifetime.signal,r=await this.withSessionRetry(async()=>await this.client.readResource({uri:e},{signal:n,...t?.timeout===void 0?{}:{timeout:t.timeout}}),n);return n.throwIfAborted(),r}async getPrompt(e,t){return this.withSessionRetry(async()=>await this.client.getPrompt({name:e,arguments:t}))}close(){return this.closePromise||=(this.closing=!0,this.lifetime.abort(/* @__PURE__ */ Error(`MCP client '${this.serverName}' is closed`)),this.connected=!1,this.setLifecycleState(`closed`),(async()=>{let e=(await Promise.allSettled([this.releaseOwnedResources({killChild:!0}),Promise.resolve().then(()=>this.client.close())])).flatMap(e=>e.status===`rejected`?[e.reason]:[]);if(e.length)throw AggregateError(e,`Failed to close MCP client '${this.serverName}'`)})()),this.closePromise}},Sn=class{outputSchemaValidation;clientCapabilities;clients=/* @__PURE__ */ new Map;serverConfigs=/* @__PURE__ */ new Map;connectionPromises=/* @__PURE__ */ new Map;connectionControllers=/* @__PURE__ */ new Map;disposed=!1;disposePromise;logger;repositoryPath;workspaceRoot;executionCwd;env;processOwnerId=(0,u.randomUUID)();outputGuard;stateListeners=/* @__PURE__ */ new Set;serverStates=/* @__PURE__ */ new Map;tokenStore;serverTokenStores=/* @__PURE__ */ new Map;serverRemovals=/* @__PURE__ */ new Map;onAuthorizationUrl;callbackTimeoutMs;callbackServer;resolveUrlCredentials;constructor(e=console,t=process.cwd(),n=new W,r={},i,a,o,s,c={}){this.outputSchemaValidation=s,this.clientCapabilities=c,this.logger=e,this.repositoryPath=t,this.workspaceRoot=i,this.executionCwd=o,this.env=a,this.outputGuard=n,this.tokenStore=r.tokenStore,this.onAuthorizationUrl=r.onAuthorizationUrl,this.callbackTimeoutMs=r.callbackTimeoutMs,this.callbackServer=r.callbackServer,this.resolveUrlCredentials=r.resolveUrlCredentials}onServerStateChange(e){this.stateListeners.add(e);for(let[t,n]of this.serverStates)this.notifyListener(e,{...n,serverName:t});return()=>{this.stateListeners.delete(e)}}getServerState(e){return this.serverStates.get(e)?.state}emitServerState(e){this.serverStates.set(e.serverName,e);for(let t of this.stateListeners)this.notifyListener(t,e)}notifyListener(e,t){try{e(t)}catch(e){this.logger.warn(`[mcp-proxy] Server state listener threw for ${t.serverName}: ${e instanceof Error?e.message:String(e)}`)}}setOutputGuard(e){this.outputGuard=e}async cleanupChildProcesses(){await this.disconnectAll()}async connectToServer(e,t,n){if(await this.serverRemovals.get(e),n?.signal?.throwIfAborted(),this.disposed)throw Error(`The MCP client manager is disposed`);n?.tokenStore&&this.serverTokenStores.set(e,n.tokenStore),this.serverConfigs.set(e,t);let r=()=>{this.removeServer(e).catch(()=>this.logger.warn(`Failed to remove cancelled MCP server '${e}'.`))};n?.signal?.addEventListener(`abort`,r,{once:!0});try{await this.ensureConnected(e),n?.signal?.throwIfAborted()}finally{n?.signal?.removeEventListener(`abort`,r)}}async removeServer(e){let t=this.serverRemovals.get(e);if(t)return t;let n=this.serverTokenStores.get(e);this.serverConfigs.delete(e);let r=(async()=>{try{await this.disconnectServer(e)}finally{this.serverTokenStores.get(e)===n&&this.serverTokenStores.delete(e),await n?.clear(e),this.serverStates.delete(e)}})();this.serverRemovals.set(e,r);try{await r}finally{this.serverRemovals.get(e)===r&&this.serverRemovals.delete(e)}}registerServerConfigs(e){for(let[t,n]of Object.entries(e))this.serverConfigs.set(t,n)}getKnownServerNames(){return Array.from(this.serverConfigs.keys())}getServerRequestTimeout(e){return this.serverConfigs.get(e)?.requestTimeout}async ensureConnected(e){if(this.disposed)throw Error(`The MCP client manager is disposed`);let t=this.clients.get(e);if(t)return await t.waitUntilReady(),t;let n=this.connectionPromises.get(e);if(n)return await n;let r=this.serverConfigs.get(e);if(!r)throw Error(`No configuration found for server "${e}"`);let i=this.createConnection(e,r);this.connectionPromises.set(e,i);try{return await i}finally{this.connectionPromises.get(e)===i&&this.connectionPromises.delete(e)}}async createConnection(e,t){let n=t.timeout??3e4,r=new AbortController;this.connectionControllers.set(e,r),this.emitServerState({serverName:e,state:`connecting`});let i,a=new Promise((e,t)=>{i=()=>t(r.signal.reason),r.signal.addEventListener(`abort`,i,{once:!0}),r.signal.aborted&&i()}),o,s,c=new Promise((e,t)=>{s=e=>{clearTimeout(o),!(e||r.signal.aborted)&&(o=setTimeout(()=>{let e=/* @__PURE__ */ Error(`Connection timeout after ${n}ms`);r.abort(e),t(e)},n))},s(!1)}),l;try{l=await Promise.race([this.createSdkClientConnection(e,t,r.signal,e=>s?.(e)),c,a])}catch(n){let i=t.transport===`http`||t.transport===`sse`?t.config.auth:void 0,a=typeof i==`object`&&i?.type===`api-key`,o=n instanceof Error&&[`Invalid MCP API-key configuration.`,`MCP API-key credential is unavailable.`,`MCP credential destination was rejected.`].includes(n.message),s=a&&!o?/* @__PURE__ */ Error(`MCP API-key connection failed.`):n;throw this.emitServerState({serverName:e,state:this.disposed||r.signal.aborted&&!String(r.signal.reason).includes(`timeout`)?`closed`:gn(s)?`needs-auth`:`failed`,error:s instanceof Error?s.message:String(s)}),s}finally{s=void 0,clearTimeout(o),r.signal.removeEventListener(`abort`,i),this.connectionControllers.get(e)===r&&this.connectionControllers.delete(e)}let u=new xn(e,t.transport,l.client,this.logger,{instruction:t.instruction,toolBlacklist:t.toolBlacklist,omitToolDescription:t.omitToolDescription,prompts:t.prompts},this.outputGuard);u.setDisconnectedCallback(()=>void 0),u.setAuthorizationRecovery(l.recoverAuthorization),u.setLifecycleChangeCallback((t,n)=>{this.emitServerState({serverName:e,state:fn(t),...n?{error:n}:{}})});try{if(l.stdioTransport&&u.setStdioTransport(l.stdioTransport),l.processLease&&u.setProcessLease(l.processLease),r.signal.throwIfAborted(),this.disposed)throw Error(`The MCP client manager is disposed`);if(u.setConnected(!0),u.setReconnectFn(async n=>{try{if(this.disposed)throw Error(`The MCP client manager is disposed`);return await this.createSdkClientConnection(e,t,n)}catch(t){throw this.logger.warn(`Failed to reconnect to ${e}`,t),t}}),!u.serverInstruction)try{let e=u.client.getInstructions();e&&(u.serverInstruction=e)}catch(t){this.logger.warn(`Failed to get server instruction from ${e}`,t)}return this.clients.set(e,u),u}catch(e){throw await u.close(),e}}createSdkClient(e,t=`auto`){let n={name:`@agimon-ai/po-mcp-proxy-client`,version:`0.1.0`},r={capabilities:structuredClone(this.clientCapabilities),versionNegotiation:t===`legacy`?{mode:`legacy`}:{mode:`auto`,probe:{timeoutMs:1e4,maxRetries:0}}};return this.outputSchemaValidation?new ln(n,r,e,this.outputSchemaValidation):new w.Client(n,r)}async createSdkClientConnection(e,t,n,r){n?.throwIfAborted();let i;if(t.transport===`stdio`)i=await this.connectStdioSdkClient(e,this.createSdkClient(e),t.config,n);else if(t.transport===`http`||t.transport===`sse`)i=await this.connectUrlSdkClient(e,t.transport,t.config,!0,n,r);else{let{transport:e}=t;throw Error(`Unsupported transport type: ${e}`)}if(n?.aborted||this.disposed)throw await mn(i),n?.throwIfAborted(),Error(`The MCP client manager is disposed`);return i}async connectUrlSdkClient(e,t,n,r=!0,i,a){i?.throwIfAborted();let o=n.auth,s=typeof o==`object`&&o?.type===`api-key`?o:void 0,c=this.resolveAuthHeaders(n),l;if(s){let r=new URL(n.url),a=s.mode===`bearer`?`Authorization`:s.name;if(s.mode!==`bearer`&&s.mode!==`header`||!/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/.test(a)||s.mode===`header`&&(a.toLowerCase()===`authorization`||/^(?:host|cookie|set-cookie|connection|keep-alive|te|trailer|upgrade|transfer-encoding|content-length|accept|origin|referer|forwarded|x-forwarded-.*|proxy-.*|sec-.*|mcp-session-id)$/i.test(a))||r.username||r.password||r.protocol!==`https:`&&!(r.protocol===`http:`&&[`localhost`,`127.0.0.1`,`[::1]`].includes(r.hostname))||n.bearerToken||n.bearerTokenEnv||n.oauth!==void 0||Object.keys(c??{}).some(e=>[`authorization`,a.toLowerCase()].includes(e.toLowerCase())))throw Error(`Invalid MCP API-key configuration.`);let o;try{o=await this.resolveUrlCredentials?.({serverName:e,transport:t,url:r.href,auth:s,signal:i})}catch{throw Error(`MCP API-key credential is unavailable.`)}i?.throwIfAborted();let u=o?.[a];if(!u||Object.keys(o??{}).length!==1||Array.from(u).some(e=>e.charCodeAt(0)<=31||e.charCodeAt(0)===127)||s.mode===`bearer`&&!/^Bearer [^\s]+$/.test(u))throw Error(`MCP API-key credential is unavailable.`);c={...c,[a]:u},l=async(e,t)=>{let n=new URL(typeof e==`string`?e:e instanceof URL?e.href:e.url);if(n.origin!==r.origin||n.username||n.password)throw Error(`MCP credential destination was rejected.`);return fetch(e,{...t,redirect:`error`})}}let u=this.createSdkClient(e,t===`sse`?`legacy`:`auto`),d=c?{headers:c}:void 0,f=this.createAuthProvider(e,n);await f?.prepareCallback(),i?.throwIfAborted();let p=f?new Ut(f,n.url,i):void 0,m={requestInit:d,authProvider:p,...l?{fetch:l}:{}},h=t===`http`?new w.StreamableHTTPClientTransport(new URL(n.url),m):new w.SSEClientTransport(new URL(n.url),m),g=()=>{f?.cancelAuthorization(),u.close().catch(t=>this.logger.warn(`Failed to close cancelled client ${e}`,s?`API-key connection closed`:t))};i?.addEventListener(`abort`,g,{once:!0});let _=!1;try{return await u.connect(h),i?.throwIfAborted(),_=!0,{client:u,...p?{recoverAuthorization:(e,t)=>p.recover(e,t)}:{}}}catch(o){if(i?.throwIfAborted(),s)throw Error(`MCP API-key connection failed.`);if(!f||!p||!r||!(o instanceof w.InsufficientScopeError)&&(!gn(o)||!f.hasPendingAuthorization()))throw o;return this.logger.info(`[oauth] Waiting for authorization of MCP server "${e}"`),a?.(!0),await p.recover(o,i,()=>{a?.(!1),this.emitServerState({serverName:e,state:`connecting`})}),i?.throwIfAborted(),await this.connectUrlSdkClient(e,t,n,!1,i,a)}finally{i?.removeEventListener(`abort`,g),_||(f?.cancelAuthorization(),await u.close().catch(t=>this.logger.warn(`Failed to close client ${e}`,s?`API-key connection closed`:t)))}}resolveAuthHeaders(e){let t={...e.headers};if(Be(e)===`bearer`){let n=e.bearerTokenEnv?this.env?.[e.bearerTokenEnv]??He(e):He(e);n?t.Authorization=`Bearer ${n}`:this.logger.warn(`[oauth] Bearer auth configured for an MCP server but no token was resolved${e.bearerTokenEnv?` (env ${e.bearerTokenEnv} is unset)`:``}.`)}return Object.keys(t).length>0?t:void 0}createAuthProvider(e,t){return Ue({serverName:e,config:t,store:this.serverTokenStores.get(e)??this.tokenStore,logger:this.logger,callbackTimeoutMs:this.callbackTimeoutMs,workspaceRoot:this.repositoryPath,...this.callbackServer?{callbackServer:this.callbackServer}:{},onAuthorizationUrl:(e,t)=>{if(this.emitServerState({serverName:t,state:`needs-auth`}),this.onAuthorizationUrl)return this.onAuthorizationUrl(e,t);this.logger.info(`[oauth] Authorize MCP server "${t}" by visiting: ${e.toString()}`)}})}relayChildStderr(e,t){t&&(t.on(`data`,t=>{let n=t.toString(`utf8`).trimEnd();n&&this.logger.debug(`[${e}] ${n}`)}),t.on(`error`,()=>void 0))}async connectStdioSdkClient(e,t,n,r){let i=new ee.StdioClientTransport({command:n.command,args:n.args,cwd:this.executionCwd?(0,l.resolve)(this.executionCwd,n.cwd??`.`):this.workspaceRoot?(0,l.resolve)(this.workspaceRoot,n.cwd??`.`):n.cwd,env:{...process.env,...this.env,...n.env,PROJECT_PATH:this.repositoryPath,[_.PROCESS_REGISTRY_OWNER_KIND_ENV_VAR]:un,[_.PROCESS_REGISTRY_OWNER_ID_ENV_VAR]:this.processOwnerId},stderr:`pipe`}),a=()=>{mn({client:t,stdioTransport:i}).catch(t=>this.logger.warn(`Failed to close cancelled stdio connection for ${e}`,t))};r?.addEventListener(`abort`,a,{once:!0});try{r?.throwIfAborted(),await t.connect(i),r?.throwIfAborted(),this.relayChildStderr(e,i.stderr);let a=i.pid;if(typeof a!=`number`||a<=0)throw Error(`Failed to capture pid for stdio child process on server "${e}"`);let o=await(0,_.createProcessLease)({repositoryPath:this.repositoryPath,serviceName:e,serviceType:`tool`,pid:a,command:n.command,args:n.args,metadata:{transport:`stdio`},ownerKind:un,ownerId:this.processOwnerId,resourceKey:e});return t.onclose=()=>{let t=this.clients.get(e);t instanceof xn&&t.handleStdioClosed(i)},{client:t,processLease:o,stdioTransport:i}}catch(n){try{await mn({client:t,stdioTransport:i})}catch(t){this.logger.warn(`Failed to clean up incomplete stdio connection for ${e}`,t)}throw n}finally{r?.removeEventListener(`abort`,a)}}getClient(e){return this.clients.get(e)}getAllClients(){return Array.from(this.clients.values())}async disconnectServer(e){this.connectionControllers.get(e)?.abort(/* @__PURE__ */ Error(`MCP connection '${e}' was closed`));let t=this.connectionPromises.get(e);this.connectionPromises.delete(e);let n=this.clients.get(e);this.clients.delete(e),await Promise.all([t?.catch(()=>void 0),n?.close()])}async disconnectAll(){let e=[...this.clients.values()],t=[...this.connectionPromises.values()];this.clients.clear(),this.connectionPromises.clear();for(let e of this.connectionControllers.values())e.abort(/* @__PURE__ */ Error(`MCP connections were closed`));this.connectionControllers.clear();let n=(await Promise.allSettled([...e.map(e=>e.close()),...t.map(e=>e.catch(()=>void 0))])).flatMap(e=>e.status===`rejected`?[e.reason]:[]);if(n.length)throw AggregateError(n,`Failed to close MCP connections`)}dispose(){return this.disposed=!0,this.disposePromise??=this.disconnectAll(),this.disposePromise}isConnected(e){return this.clients.get(e)?.getLifecycleState()===`connected`}getConnectionState(e){return this.clients.get(e)?.getLifecycleState()}};const Cn=`install`,wn=/^(@[a-zA-Z0-9_-]+\/)?[a-zA-Z0-9._-]+(@[a-zA-Z0-9._-]+)?$/,Tn=`pipe`;function En(e){return typeof e==`object`&&!!e&&`command`in e}var Dn=class{config;constructor(e){this.config=e}extractPackages(){let e=[],{mcpConfig:t,filter:n}=this.config;for(let[r,i]of Object.entries(t.mcpServers)){if(i.disabled||i.transport!==`stdio`||!En(i.config))continue;let t=this.extractPackageInfo(r,i.config);if(t){if(n&&t.packageManager!==n)continue;e.push(t)}}return e}async prefetch(){try{let e=this.extractPackages(),t=[];if(e.length===0)return{totalPackages:0,successful:0,failed:0,results:[]};if(this.config.parallel){let n=e.map(async e=>this.prefetchPackage(e));t.push(...await Promise.all(n))}else for(let n of e){let e=await this.prefetchPackage(n);t.push(e)}let n=t.filter(e=>e.success).length,r=t.filter(e=>!e.success).length;return{totalPackages:e.length,successful:n,failed:r,results:t}}catch(e){throw Error(`Failed to prefetch packages: ${e instanceof Error?e.message:String(e)}`)}}async prefetchPackage(e){try{let[t,...n]=e.fullCommand,r=await this.runCommand(t,n);return{package:e,success:r.success,output:r.output}}catch(t){return{package:e,success:!1,output:t instanceof Error?t.message:String(t)}}}isValidPackageName(e){return wn.test(e)}extractPackageInfo(e,t){let n=t.command.toLowerCase(),r=t.args||[];if(n===`npx`||n.endsWith(`/npx`)){let t=this.extractNpxPackage(r);if(t&&this.isValidPackageName(t))return{serverName:e,packageManager:`npx`,packageName:t,fullCommand:[`npm`,Cn,`-g`,t]}}if(n===`pnpx`||n.endsWith(`/pnpx`)){let t=this.extractNpxPackage(r);if(t&&this.isValidPackageName(t))return{serverName:e,packageManager:`pnpx`,packageName:t,fullCommand:[`pnpm`,`add`,`-g`,t]}}if(n===`uvx`||n.endsWith(`/uvx`)){let t=this.extractUvxPackage(r);if(t&&this.isValidPackageName(t))return{serverName:e,packageManager:`uvx`,packageName:t,fullCommand:[`uvx`,t]}}if((n===`uv`||n.endsWith(`/uv`))&&r.includes(`run`)){let t=this.extractUvRunPackage(r);if(t&&this.isValidPackageName(t))return{serverName:e,packageManager:`uv`,packageName:t,fullCommand:[`uv`,`tool`,Cn,t]}}return null}extractNpxPackage(e){for(let t=0;t<e.length;t++){let n=e[t];if(n.startsWith(`--package=`))return n.slice(10)||null;if(n===`--package`&&t+1<e.length){let n=e[t+1];if(!n.startsWith(`-`))return n}if(n===`-p`&&t+1<e.length){let n=e[t+1];if(!n.startsWith(`-`))return n}}for(let t of e)if(!t.startsWith(`-`))return t;return null}extractUvxPackage(e){for(let t of e)if(!t.startsWith(`-`))return t;return null}extractUvRunPackage(e){let t=e.indexOf(`run`);if(t===-1)return null;for(let n=t+1;n<e.length;n++){let t=e[n];if(!t.startsWith(`-`))return t}return null}runCommand(e,t){return new Promise(n=>{let r=(0,h.spawn)(e,t,{stdio:[`ignore`,Tn,Tn],shell:process.platform===`win32`}),i=``,a=``;r.stdout?.on(`data`,e=>{i+=e.toString()}),r.stderr?.on(`data`,e=>{a+=e.toString()}),r.on(`close`,e=>{n({success:e===0,output:i||a})}),r.on(`error`,e=>{n({success:!1,output:e.message})})})}};const On=`.runtime.json`;async function kn(e){await(0,f.mkdir)(e,{recursive:!0,mode:448});try{await(0,f.chmod)(e,448)}catch{}}function An(e){return typeof e==`object`&&!!e}function jn(e){return An(e)?typeof e.serverId==`string`&&typeof e.host==`string`&&typeof e.port==`number`&&e.transport===`http`&&typeof e.shutdownToken==`string`&&typeof e.startedAt==`string`&&typeof e.pid==`number`&&(e.configPath===void 0||typeof e.configPath==`string`)&&(e.runtimeLifecycle===void 0||e.runtimeLifecycle===`manual`||e.runtimeLifecycle===`stdio-http-managed`):!1}function Mn(e){return e instanceof Error?e.message:String(e)}function Nn(e){try{return process.kill(e,0),!0}catch{return!1}}var K=class e{runtimeDir;logger;constructor(t,n=console){this.runtimeDir=t??e.getDefaultRuntimeDir(),this.logger=n}static getDefaultRuntimeDir(){return(0,l.join)((0,p.homedir)(),`.mcp-proxy`,`runtimes`)}getRecordPath(e){return(0,l.join)(this.runtimeDir,`${e}${On}`)}async write(e){await kn(this.runtimeDir);let t=this.getRecordPath(e.serverId);await(0,f.writeFile)(t,JSON.stringify(e,null,2),{encoding:`utf-8`,mode:384})}async read(e){let t=this.getRecordPath(e);try{let e=await(0,f.readFile)(t,`utf-8`),n=JSON.parse(e);return jn(n)?n:null}catch(n){if(An(n)&&`code`in n&&n.code===`ENOENT`)return null;throw Error(`Failed to read runtime state for server '${e}' from '${t}': ${Mn(n)}`)}}async list(){try{let e=(await(0,f.readdir)(this.runtimeDir,{withFileTypes:!0})).filter(e=>e.isFile()&&e.name.endsWith(On));return(await Promise.all(e.map(async e=>{try{let t=await(0,f.readFile)((0,l.join)(this.runtimeDir,e.name),`utf-8`),n=JSON.parse(t);return jn(n)?n:null}catch(t){return this.logger.debug(`Skipping unreadable runtime state file ${e.name}`,t),null}}))).filter(e=>e!==null)}catch(e){if(An(e)&&`code`in e&&e.code===`ENOENT`)return[];throw Error(`Failed to list runtime states from '${this.runtimeDir}': ${Mn(e)}`)}}async listOrphans(e){return(await this.list()).filter(t=>!e.has(t.serverId))}async pruneStale(){let e=(await this.list()).filter(e=>!Nn(e.pid));return await Promise.all(e.map(async e=>this.remove(e.serverId))),e}async remove(e){await(0,f.rm)(this.getRecordPath(e),{force:!0})}},Pn=class extends Error{filePath;cause;constructor(e,t,n){super(e),this.filePath=t,this.cause=n,this.name=`SkillLoadError`}};async function Fn(e){try{return await(0,f.access)(e),!0}catch(t){if(t instanceof Error&&`code`in t&&t.code===`ENOENT`)return!1;throw Error(`Failed to check path existence for "${e}": ${t instanceof Error?t.message:`Unknown error`}`)}}var In=class{cwd;skillPaths;cachedSkills=null;skillsByName=null;watchers=[];pollingTimers=[];onCacheInvalidated;logger;constructor(e,t,n,r=console){this.cwd=e,this.skillPaths=t,this.onCacheInvalidated=n?.onCacheInvalidated,this.logger=r}async getSkills(){if(this.cachedSkills!==null)return this.cachedSkills;let e=[],t=/* @__PURE__ */ new Set,n=await Promise.all(this.skillPaths.map(async e=>{let t=(0,l.isAbsolute)(e)?e:(0,l.join)(this.cwd,e);return this.loadSkillsFromDirectory(t,`project`)}));for(let r of n)for(let n of r)t.has(n.name)||(e.push(n),t.add(n.name));return this.cachedSkills=e,this.skillsByName=new Map(e.map(e=>[e.name,e])),e}async getSkill(e){return this.skillsByName===null&&await this.getSkills(),this.skillsByName?.get(e)}clearCache(){this.cachedSkills=null,this.skillsByName=null}async startWatching(){this.stopWatching();let e=await Promise.all(this.skillPaths.map(async e=>{let t=(0,l.isAbsolute)(e)?e:(0,l.join)(this.cwd,e);return{skillsDir:t,exists:await Fn(t)}}));for(let{skillsDir:t,exists:n}of e){if(!n)continue;let e=new AbortController;this.watchers.push(e),this.watchDirectory(t,e.signal).catch(n=>{if(n?.name!==`AbortError`){if(this.isWatchResourceLimitError(n)){this.startPollingDirectory(t,e.signal);return}this.logger.warn(`[skill-watcher] Error watching ${t}: ${n instanceof Error?n.message:`Unknown error`}`)}})}}stopWatching(){for(let e of this.watchers)e.abort();this.watchers=[];for(let e of this.pollingTimers)clearInterval(e);this.pollingTimers=[]}async watchDirectory(e,t){let n=(0,f.watch)(e,{recursive:!0,signal:t});for await(let e of n)e.filename?.endsWith(`SKILL.md`)&&this.invalidateCache()}invalidateCache(){this.clearCache(),this.onCacheInvalidated?.()}isWatchResourceLimitError(e){return e instanceof Error&&`code`in e&&(e.code===`EMFILE`||e.code===`ENOSPC`)}startPollingDirectory(e,t){this.createSkillSnapshot(e).then(n=>{let r=n,i=setInterval(()=>{t.aborted?clearInterval(i):this.createSkillSnapshot(e).then(e=>{this.snapshotsEqual(r,e)||(r=e,this.invalidateCache())}).catch(t=>{this.logger.warn(`[skill-watcher] Polling failed for ${e}: ${t instanceof Error?t.message:`Unknown error`}`)})},3e3);this.pollingTimers.push(i),t.addEventListener(`abort`,()=>{clearInterval(i),this.pollingTimers=this.pollingTimers.filter(e=>e!==i)},{once:!0})})}async createSkillSnapshot(e){let t=/* @__PURE__ */ new Map;return await this.collectSkillSnapshots(e,t),t}async collectSkillSnapshots(e,t){let n;try{n=await(0,f.readdir)(e)}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;throw e}await Promise.all(n.map(async n=>{let r=(0,l.join)(e,n),i=await(0,f.stat)(r);i.isDirectory()?await this.collectSkillSnapshots(r,t):n===`SKILL.md`&&t.set(r,i.mtimeMs)}))}snapshotsEqual(e,t){if(e.size!==t.size)return!1;for(let[n,r]of e)if(t.get(n)!==r)return!1;return!0}async loadSkillsFromDirectory(e,t){let n=[];try{if(!await Fn(e))return n}catch(t){throw new Pn(`Cannot access skills directory: ${t instanceof Error?t.message:`Unknown error`}`,e,t instanceof Error?t:void 0)}let r;try{r=await(0,f.readdir)(e)}catch(t){throw new Pn(`Failed to read skills directory: ${t instanceof Error?t.message:`Unknown error`}`,e,t instanceof Error?t:void 0)}let i=await Promise.all(r.map(async t=>{let n=(0,l.join)(e,t);try{return{entry:t,entryPath:n,stat:await(0,f.stat)(n),error:null}}catch(e){return this.logger.warn(`Skipping entry ${n}: ${e instanceof Error?e.message:`Unknown error`}`),{entry:t,entryPath:n,stat:null,error:e}}})),a=[];for(let{entry:e,entryPath:t,stat:n}of i)if(n){if(n.isDirectory()){let e=(0,l.join)(t,`SKILL.md`);a.push({filePath:e,isRootLevel:!1})}else e===`SKILL.md`&&a.push({filePath:t,isRootLevel:!0})}let o=await Promise.all(a.map(async({filePath:e,isRootLevel:n})=>{try{return!n&&!await Fn(e)?null:await this.loadSkillFile(e,t)}catch(t){return this.logger.warn(`Skipping skill at ${e}: ${t instanceof Error?t.message:`Unknown error`}`),null}}));for(let e of o)e&&n.push(e);return n}async loadSkillFile(e,t){let n;try{n=await(0,f.readFile)(e,`utf-8`)}catch(t){throw new Pn(`Failed to read skill file: ${t instanceof Error?t.message:`Unknown error`}`,e,t instanceof Error?t:void 0)}let{frontMatter:r,content:i}=kt(n);return!r||!r.name||!r.description?null:{name:r.name,description:r.description,location:t,content:i,basePath:(0,l.dirname)(e)}}};const Ln=/* @__PURE__ */ new Set([`localhost`,`127.0.0.1`,`::1`]);function Rn(e){return e}function zn(e){if(typeof e!=`object`||!e)return!1;let t=Rn(e);return`status`in t&&t.status===`ok`&&`transport`in t&&t.transport===`http`&&(!(`serverId`in t)||t.serverId===void 0||typeof t.serverId==`string`)&&(!(`runtimeLifecycle`in t)||t.runtimeLifecycle===void 0||t.runtimeLifecycle===`manual`||t.runtimeLifecycle===`stdio-http-managed`)}function Bn(e){if(typeof e!=`object`||!e)return!1;let t=Rn(e);return`ok`in t&&typeof t.ok==`boolean`&&`message`in t&&typeof t.message==`string`&&(!(`serverId`in t)||t.serverId===void 0||typeof t.serverId==`string`)}function Vn(e,t){if(!Ln.has(e.host))throw Error(`Refusing to connect to non-loopback host '${e.host}'. Only ${Array.from(Ln).join(`, `)} are allowed.`);return`http://${e.host}:${e.port}${t}`}function Hn(e){return e instanceof Error?e.message:String(e)}function Un(e){return new Promise(t=>{setTimeout(t,e)})}var Wn=class{runtimeStateService;logger;constructor(e=new K,t=console){this.runtimeStateService=e,this.logger=t}async stop(e){let t=e.timeoutMs??5e3;await this.pruneStaleRuntimeRecords();let n=await this.resolveRuntime(e),r=await this.fetchHealth(n,t);if(!r.reachable)throw await this.runtimeStateService.remove(n.serverId),Error(`Runtime '${n.serverId}' is not reachable at http://${n.host}:${n.port}. Removed stale runtime record.`);if(!e.force&&r.payload?.serverId&&r.payload.serverId!==n.serverId)throw Error(`Refusing to stop runtime at http://${n.host}:${n.port}: expected server ID '${n.serverId}' but health endpoint reported '${r.payload.serverId}'. Use --force to override.`);let i=e.token??n.shutdownToken;if(!i)throw Error(`No shutdown token available for runtime '${n.serverId}'.`);let a=await this.requestShutdown(n,i,t);return await this.waitForShutdown(n,t),await this.runtimeStateService.remove(n.serverId),{ok:!0,serverId:n.serverId,host:n.host,port:n.port,message:a.message}}async resolveRuntime(e){if(e.serverId){let t=await this.runtimeStateService.read(e.serverId);if(!t)throw Error(`No runtime record found for server ID '${e.serverId}'. Start the server with 'po-mcp-proxy mcp-serve --type http' first.`);return t}if(e.host===void 0||e.port===void 0)throw Error(`Provide --id or both --host and --port to select a runtime.`);let t=(await this.runtimeStateService.list()).filter(t=>t.host===e.host&&t.port===e.port);if(t.length===0)throw Error(`No runtime record found for http://${e.host}:${e.port}. Start the server with 'po-mcp-proxy mcp-serve --type http' first.`);if(t.length>1)throw Error(`Multiple runtime records match http://${e.host}:${e.port}. Retry with --id to avoid stopping the wrong server.`);return t[0]}async pruneStaleRuntimeRecords(){if(this.runtimeStateService.pruneStale)try{await this.runtimeStateService.pruneStale()}catch(e){this.logger.debug(`Failed to prune stale runtime records before stop resolution`,e)}}async fetchHealth(e,t){try{let n=await this.fetchWithTimeout(Vn(e,`/health`),{method:`GET`},t);if(!n.ok)return{reachable:!1};let r=await n.json();if(!zn(r))throw Error(`Received invalid health response payload.`);return{reachable:!0,payload:r}}catch(t){return this.logger.debug(`Health check failed for ${e.serverId}`,t),{reachable:!1}}}async requestShutdown(e,t,n){let r=await this.fetchWithTimeout(Vn(e,`/admin/shutdown`),{method:`POST`,headers:{Authorization:`Bearer ${t}`}},n),i=await r.json();if(!Bn(i))throw Error(`Received invalid shutdown response payload.`);if(!r.ok||!i.ok)throw Error(i.message);return i}async waitForShutdown(e,t){let n=Date.now()+t;for(;Date.now()<n;){if(!(await this.fetchHealth(e,Math.max(250,n-Date.now()))).reachable)return;await Un(200)}throw Error(`Timed out waiting for runtime '${e.serverId}' to stop at http://${e.host}:${e.port}.`)}async fetchWithTimeout(e,t,n){let r=new AbortController,i=setTimeout(()=>{r.abort()},n);try{return await fetch(e,{...t,signal:r.signal})}catch(t){throw Error(`Request to '${e}' failed: ${Hn(t)}`)}finally{clearTimeout(i)}}};function q(e){return e instanceof Error?e.message:String(e)}function Gn(e,t){let n=Buffer.from(e,`utf-8`),r=Buffer.from(t,`utf-8`);return n.length===r.length&&(0,u.timingSafeEqual)(n,r)}var Kn=class{requests=/* @__PURE__ */ new Map;isAllowed(e){let t=Date.now()-6e4,n=(this.requests.get(e)??[]).filter(e=>e>t);return n.length>=5?(this.requests.set(e,n),!1):(n.push(Date.now()),this.requests.set(e,n),!0)}},qn=class{honoApp=new ie.Hono;adminRateLimiter=new Kn;config;mcpHandler;nodeMcpHandler;adminOptions;logger;server=null;lastRequestAt=Date.now();activeRequests=0;idleTimer=null;constructor(e,t,n,r=console){this.config={mode:t.mode,host:t.host??`localhost`,port:t.port},this.adminOptions=n,this.logger=r,this.mcpHandler=(0,b.createMcpHandler)(e,{legacy:`reject`,onerror:e=>this.logger.error(`MCP handler failed: ${e.message}`)}),this.nodeMcpHandler=(0,re.toNodeHandler)(this.mcpHandler,{onerror:e=>this.logger.error(`Failed to adapt MCP request: ${e.message}`)}),this.setupHonoRoutes()}setupHonoRoutes(){this.honoApp.get(`/health`,e=>{let t={status:`ok`,transport:`http`,serverId:this.adminOptions?.serverId,runtimeLifecycle:this.adminOptions?.runtimeLifecycle,protocolVersion:`2026-07-28`,runtimeEpoch:`modern-2026-07-28-v1`};return e.json(t)}),this.honoApp.post(`/admin/shutdown`,async e=>{try{let t=e.req.header(`x-forwarded-for`)??`unknown`;if(!this.adminRateLimiter.isAllowed(t)){let t={ok:!1,message:`Too many shutdown requests. Try again later.`,serverId:this.adminOptions?.serverId};return e.json(t,429)}return await this.handleAdminShutdownRequest(e)}catch(t){this.logger.error(`Failed to process shutdown request: ${q(t)}`);let n={ok:!1,message:`Failed to process shutdown request.`,serverId:this.adminOptions?.serverId};return e.json(n,500)}})}isAuthorizedShutdownRequest(e){let t=this.adminOptions?.shutdownToken;if(!t)return!1;let n=e.authorization;if(typeof n==`string`&&n.startsWith(`Bearer `))return Gn(n.slice(7),t);let r=e[`x-mcp-proxy-shutdown-token`];return typeof r==`string`&&Gn(r,t)}async handleAdminShutdownRequest(e){if(!this.adminOptions?.onShutdownRequested)return e.json({ok:!1,message:`Shutdown endpoint is not enabled for this server instance.`,serverId:this.adminOptions?.serverId},404);if(!this.isAuthorizedShutdownRequest({authorization:e.req.header(`authorization`),"x-mcp-proxy-shutdown-token":e.req.header(`x-mcp-proxy-shutdown-token`)}))return e.json({ok:!1,message:`Unauthorized shutdown request: invalid or missing shutdown token.`,serverId:this.adminOptions?.serverId},401);let t=e.json({ok:!0,message:`Shutdown request accepted. Stopping server gracefully.`,serverId:this.adminOptions?.serverId});return this.adminOptions.onShutdownRequested().catch(e=>{this.logger.error(`Shutdown request failed: ${q(e)}`)}),t}async handleMcpRequest(e,t){this.activeRequests+=1;try{await this.nodeMcpHandler(e,t)}catch(e){this.logger.error(`MCP request failed: ${q(e)}`),t.headersSent||(t.writeHead(500,{"Content-Type":`application/json`}),t.end(JSON.stringify({jsonrpc:`2.0`,error:{code:-32603,message:`MCP request failed.`},id:null})))}finally{--this.activeRequests,this.lastRequestAt=Date.now()}}startIdleShutdownMonitor(){let e=this.adminOptions?.idleShutdownMs??0;e<=0||this.idleTimer||(this.lastRequestAt=Date.now(),this.idleTimer=setInterval(()=>{this.shutdownWhenIdle(e)},Math.min(e,6e4)))}stopIdleShutdownMonitor(){this.idleTimer&&=(clearInterval(this.idleTimer),null)}async shutdownWhenIdle(e){let t=this.adminOptions?.onShutdownRequested;if(!(!t||this.activeRequests>0||Date.now()-this.lastRequestAt<e)){this.stopIdleShutdownMonitor(),this.logger.info(`Stopping idle HTTP runtime after ${e}ms without active requests`);try{await t()}catch(e){this.logger.error(`Failed to stop idle HTTP runtime: ${q(e)}`)}}}async start(){if(this.server)throw Error(`HTTP transport is already running`);let e=(0,ne.getRequestListener)(this.honoApp.fetch),t=(0,d.createServer)((t,n)=>{this.lastRequestAt=Date.now(),new URL(t.url??`/`,`http://${t.headers.host??this.config.host}`).pathname===`/mcp`?this.handleMcpRequest(t,n):e(t,n)});try{t.listen(this.config.port,this.config.host),await Promise.race([(0,E.once)(t,`listening`),(0,E.once)(t,`error`).then(([e])=>Promise.reject(e))]),this.server=t,this.startIdleShutdownMonitor(),this.logger.info(`@agimon-ai/po-mcp-proxy MCP server started on http://${this.config.host}:${this.config.port}/mcp`),this.logger.info(`Health check: http://${this.config.host}:${this.config.port}/health`)}catch(e){throw t.close(),Error(`Failed to start HTTP transport: ${q(e)}`,{cause:e})}}async stop(){this.stopIdleShutdownMonitor();let e=this.server;if(e){this.server=null,await this.mcpHandler.close();try{await(0,D.promisify)(e.close.bind(e))()}catch(e){throw Error(`Failed to stop HTTP transport: ${q(e)}`,{cause:e})}}}getPort(){let e=this.server?.address();return e&&typeof e==`object`?e.port:this.config.port}getHost(){return this.config.host}};const Jn=`localhost`,Yn=12e4,Xn=`MCP_PROXY_RUNTIME_DETACHED`;function Zn(){return process.env[Xn]===`1`}async function Qn(e){return(await new _.ProcessRegistryService(process.env.PROCESS_REGISTRY_PATH).listProcesses({repositoryPath:e,serviceName:`mcp-proxy-http`,liveOnly:!0})).filter(e=>!!(e.host&&e.port)).map(e=>{let t=e.metadata;return{host:e.host,port:e.port,serverId:t?.serverId??`unknown`,runtimeLifecycle:t?.runtimeLifecycle===`stdio-http-managed`||t?.runtimeLifecycle===`manual`?t.runtimeLifecycle:void 0,createdAt:e.createdAt}}).sort((e,t)=>(e.createdAt??``).localeCompare(t.createdAt??``))}async function $n(e){let t=await Qn(e);for(let e of t)if(er(await tr(e.host,e.port)))return e;return null}function er(e){return e.ok&&e.payload?.status===`ok`&&e.payload.transport===`http`&&e.payload.protocolVersion===`2026-07-28`&&e.payload.runtimeEpoch===`modern-2026-07-28-v1`}async function tr(e,t,n={}){let r=n.timeoutMs??1500,i=n.retries??2,a=n.retryDelayMs??150,o=i+1,s=`unknown error`;for(let n=1;n<=o;n+=1){try{let i=await fetch(`http://${e}:${t}/health`,{signal:AbortSignal.timeout(r)});if(i.ok)return{ok:!0,payload:await i.json().catch(()=>null)??void 0,attempts:n};s=`health endpoint returned status ${i.status}`}catch(e){s=e instanceof Error?e.message:String(e)}n<o&&await new Promise(e=>setTimeout(e,a))}return{ok:!1,error:s,attempts:o}}function nr(){let e=(0,g.fileURLToPath)(require("url").pathToFileURL(__filename).href),t=l.default.dirname(e),n=[l.default.resolve(t,`cli.mjs`),l.default.resolve(t,`..`,`dist`,`cli.mjs`),l.default.resolve(t,`..`,`..`,`dist`,`cli.mjs`)],r=[l.default.resolve(t,`..`,`cli.ts`),l.default.resolve(t,`..`,`..`,`src`,`cli.ts`)];for(let e of n)if((0,c.existsSync)(e))return{command:process.execPath,args:[e]};for(let e of r)if((0,c.existsSync)(e))return{command:process.execPath,args:[`--import`,`tsx`,e]};throw Error(`Unable to locate mcp-proxy CLI entrypoint`)}function rr(e){if(!e)return Yn;let t=Number.parseInt(e,10);if(!Number.isInteger(t)||t<=0)throw Error(`Invalid timeout value: ${e}`);return t}async function ir(e,t){let n=Date.now()+t;for(;Date.now()<n;){try{await(0,f.access)(e);return}catch{}await new Promise(e=>setTimeout(e,250))}throw Error(`Timed out waiting for runtime state file: ${e}`)}async function ar(e,t){let n=new K,r=Date.now()+t;for(;Date.now()<r;){let t=await n.read(e);if(t&&er(await tr(t.host,t.port,{retries:0})))return{host:t.host,port:t.port};await new Promise(e=>setTimeout(e,250))}throw Error(`Timed out waiting for HTTP runtime '${e}' to become healthy`)}function or(e,t,n){let{command:r,args:i}=nr(),a=(0,h.spawn)(r,[...i,...e],{detached:!0,cwd:n,stdio:`ignore`,env:t});return a.unref(),a}async function sr(e){let t=e.id||Ot(),n=rr(e.timeoutMs),r=e.registryPath||e.registryDir,i=k();await new K().pruneStale();let a=await $n(i);if(a)return{host:a.host,port:a.port,serverId:a.serverId,workspaceRoot:i,reusedExistingRuntime:!0,runtimeLifecycle:a.runtimeLifecycle??`manual`};let o=e.port,s=await Qn(i);if(e.id&&s.some(e=>e.serverId===t))throw Error(`Runtime ID '${t}' belongs to an incompatible HTTP runtime; choose a new ID`);if(o!==void 0&&s.some(t=>t.host===(e.host||Jn)&&t.port===o))throw Error(`Port ${o} belongs to a different HTTP runtime; choose a free port`);let c=o,u={...process.env,[Xn]:`1`,...e.runtimeLifecycle?{MCP_PROXY_RUNTIME_LIFECYCLE:e.runtimeLifecycle}:{},...r?{PORT_REGISTRY_PATH:r,PROCESS_REGISTRY_PATH:(0,_.resolveSiblingRegistryPath)(r,`processes.json`)}:{}},d=or([`mcp-serve`,`--type`,`http`,`--id`,t,`--host`,e.host||Jn,...c===void 0?[]:[`--port`,String(c)],...Tt(e.config).flatMap(e=>[`--config`,e]),...e.cache===!1?[`--no-cache`]:[],...e.definitionsCache?[`--definitions-cache`,e.definitionsCache]:[],...e.clearDefinitionsCache?[`--clear-definitions-cache`]:[],...e.idleShutdownMinutes===void 0?[]:[`--idle-shutdown-minutes`,String(e.idleShutdownMinutes)],`--proxy-mode`,e.proxyMode],u,i),f=new Promise((e,t)=>{d.once(`exit`,(e,n)=>{t(/* @__PURE__ */ Error(`Background runtime exited before becoming healthy (code=${e??`null`}, signal=${n??`null`})`))})}),p=l.default.join(K.getDefaultRuntimeDir(),`${t}.runtime.json`);try{await Promise.race([ir(p,n),f]);let{host:r,port:a}=await Promise.race([ar(t,n),f]);return{host:r,port:a,serverId:t,workspaceRoot:i,reusedExistingRuntime:!1,runtimeLifecycle:e.runtimeLifecycle??`manual`}}catch(e){throw Error(`Failed to prestart HTTP runtime '${t}': ${e instanceof Error?e.message:String(e)}`,{cause:e})}}function cr(e){process.stdout.write(`mcp-proxy HTTP runtime ready at http://${e.host}:${e.port} (${e.serverId})\n`),process.stdout.write(`runtimeId=${e.serverId}\n`),process.stdout.write(`runtimeUrl=http://${e.host}:${e.port}\n`),process.stdout.write(`workspaceRoot=${e.workspaceRoot}\n`)}var lr=`0.0.1-alpha.21`,ur=`<toolkit id="{{ serverId }}">
10
+ <instruction>
11
+ Before you use any capabilities below, you MUST call this tool with a list of names to learn how to use them properly; this includes:
12
+ - For tools: Arguments schema needed to pass to use_tool
13
+ - For skills: Detailed instructions that will expand when invoked (Prefer to be explored first when relevant)
14
+
15
+ This tool is optimized for batch queries - you can request multiple capabilities at once for better performance.
16
+
17
+ How to invoke:
18
+ - For MCP tools: Use use_tool with toolName and toolArgs based on the schema
19
+ - For skills: Use this tool with the skill name to get expanded instructions
20
+ </instruction>
21
+
22
+ <available_capabilities>
23
+ {% for server in servers -%}
24
+ <group original-mcp-server="{{ server.name }}">
25
+ {% if server.instruction -%}
26
+ <group_instruction>{{ server.instruction }}</group_instruction>
27
+ {% endif -%}
28
+ {% if server.omitToolDescription -%}
29
+ {% for toolName in server.toolNames -%}
30
+ <item name="{{ toolName }}"></item>
31
+ {% endfor -%}
32
+ {% else -%}
33
+ {% for tool in server.tools -%}
34
+ <item name="{{ tool.displayName }}"><description>{{ tool.description | default: "No description" }}</description></item>
35
+ {% endfor -%}
36
+ {% endif -%}
37
+ </group>
38
+ {% endfor -%}
39
+ {% if skills.size > 0 -%}
40
+ <group name="skills">
41
+ {% for skill in skills -%}
42
+ <item name="{{ skill.displayName }}"><description>{{ skill.description }}</description></item>
43
+ {% endfor -%}
44
+ </group>
45
+ {% endif -%}
46
+ </available_capabilities>
47
+ </toolkit>
48
+ `;function dr(e,t){return`<command-message>The "${e}" skill is loading</command-message>\n${t}`}const J=y.z.object({toolNames:y.z.array(y.z.string().min(1)).min(1).describe(`List of tool names to get detailed information about`)});var Y=class e{static TOOL_NAME=`describe_tools`;clientManager;skillService;definitionsCacheService;liquid=new ae.Liquid;serverId;constructor(e,t,n,r){this.clientManager=e,this.skillService=t,this.serverId=n||`unknown`,this.definitionsCacheService=r||new H(e,t)}clearAutoDetectedSkillsCache(){this.definitionsCacheService.clearLiveCache()}async collectPromptSkills(){let e=[],t=await this.definitionsCacheService.getServerDefinitions();for(let n of t)for(let t of n.promptSkills)e.push({name:t.skill.name,displayName:t.skill.name,description:t.skill.description});return e}async findPromptSkill(e){if(e)return await this.definitionsCacheService.getPromptSkillByName(e)}async getPromptSkillContent(e){let t=await this.findPromptSkill(e);if(t)try{let e=(await(await this.clientManager.ensureConnected(t.serverName)).getPrompt(t.promptName)).messages?.map(e=>{let t=e.content;return typeof t==`string`?t:t&&typeof t==`object`&&`text`in t?String(t.text):``}).join(`
49
+ `)||``;return{name:t.skill.name,location:t.skill.folder||`prompt:${t.serverName}/${t.promptName}`,instructions:dr(t.skill.name,e)}}catch(t){console.error(`Failed to get prompt-based skill '${e}': ${t instanceof Error?t.message:`Unknown error`}`);return}}async buildToolkitDescription(){let e=await this.definitionsCacheService.getServerDefinitions(),t=/* @__PURE__ */ new Map;for(let n of e)for(let e of n.tools)t.has(e.name)||t.set(e.name,[]),t.get(e.name)?.push(n.serverName);let n=(e,n)=>(t.get(e)||[]).length>1?`${n}__${e}`:e,r=/* @__PURE__ */ new Set,i=e.map(e=>{let t=e.tools.map(t=>({displayName:n(t.name,e.serverName),description:t.description}));for(let e of t)r.add(e.displayName);return{name:e.serverName,instruction:e.serverInstruction,omitToolDescription:e.omitToolDescription||!1,tools:t,toolNames:t.map(e=>e.displayName)}}),[a,o,s]=await Promise.all([this.skillService?this.skillService.getSkills():Promise.resolve([]),this.definitionsCacheService.getCachedFileSkills(),this.collectPromptSkills()]),c=/* @__PURE__ */ new Set,l=[];for(let e of a)c.has(e.name)||(c.add(e.name),l.push({name:e.name,displayName:e.name,description:e.description}));for(let e of o)c.has(e.name)||(c.add(e.name),l.push({name:e.name,displayName:e.name,description:e.description}));for(let e of s)c.has(e.name)||(c.add(e.name),l.push(e));let u=l.map(e=>{let t=r.has(e.name);return{name:e.name,displayName:t?`skill__${e.name}`:e.name,description:e.description}});return{content:await this.liquid.parseAndRender(ur,{servers:i,skills:u,serverId:this.serverId}),toolNames:r}}getInputSchema(){return J}async getDefinition(){let{content:t}=await this.buildToolkitDescription();return{name:e.TOOL_NAME,description:t,inputSchema:y.z.toJSONSchema(J,{reused:`inline`})}}async runLookups(e,t){let n=/* @__PURE__ */ new Map,r=/* @__PURE__ */ new Map;for(let e of t){let t=e.tools.map(e=>({name:e.name,description:e.description,inputSchema:e.inputSchema}));n.set(e.serverName,t);for(let n of t)r.has(n.name)||r.set(n.name,[]),r.get(n.name)?.push(e.serverName)}let i=await Promise.all(e.map(async e=>{let t={tools:[],skills:[],notFound:null};if(e.startsWith(`skill__`)){let n=e.slice(7);if(this.skillService){let e=await this.skillService.getSkill(n);if(e)return t.skills.push({name:e.name,location:e.basePath,instructions:dr(e.name,e.content)}),t}let r=await this.getPromptSkillContent(n);return r?(t.skills.push(r),t):(t.notFound=e,t)}let{serverName:i,actualToolName:a}=z(e);if(i){let r=n.get(i);if(!r){try{let n=(await(await this.clientManager.ensureConnected(i)).listTools()).find(e=>e.name===a);n?t.tools.push({server:i,tool:{name:n.name,description:n.description,inputSchema:n.inputSchema}}):t.notFound=e}catch{t.notFound=e}return t}let o=r.find(e=>e.name===a);return o?t.tools.push({server:i,tool:{name:o.name,description:o.description,inputSchema:o.inputSchema}}):t.notFound=e,t}let o=r.get(a);if(!o||o.length===0){if(this.skillService){let e=await this.skillService.getSkill(a);if(e)return t.skills.push({name:e.name,location:e.basePath,instructions:dr(e.name,e.content)}),t}let n=await this.getPromptSkillContent(a);return n?(t.skills.push(n),t):(t.notFound=e,t)}for(let e of o){let r=n.get(e).find(e=>e.name===a);t.tools.push({server:e,tool:{name:r.name,description:r.description,inputSchema:r.inputSchema}})}return t})),a=[],o=[],s=[];for(let e of i)a.push(...e.tools),o.push(...e.skills),e.notFound&&s.push(e.notFound);return{foundTools:a,foundSkills:o,notFoundItems:s}}async execute(e){try{let{toolNames:t}=J.parse(e);if(!t||t.length===0)return{content:[{type:`text`,text:`No tool names provided. Please specify at least one tool name.`}],isError:!0};let n=await this.runLookups(t,await this.definitionsCacheService.getServerDefinitions());n.notFoundItems.length>0&&(this.definitionsCacheService.clearLiveCache(),await this.definitionsCacheService.collectForCache(),n=await this.runLookups(t,await this.definitionsCacheService.getServerDefinitions()));let{foundTools:r,foundSkills:i,notFoundItems:a}=n;if(r.length===0&&i.length===0)return{content:[{type:`text`,text:`None of the requested tools/skills found.\nRequested: ${t.join(`, `)}\nUse describe_tools to see available tools and skills.`}],isError:!0};let o={},s=[];return r.length>0&&(o.tools=r,s.push(`For MCP tools: Use the use_tool function with toolName and toolArgs based on the inputSchema above.`)),i.length>0&&(o.skills=i,s.push(`For skill, just follow skill's description to continue.`)),s.length>0&&(o.nextSteps=s),a.length>0&&(o.notFound=a,o.warnings=[`Items not found: ${a.join(`, `)}`]),{content:[{type:`text`,text:JSON.stringify(o,null,2)}]}}catch(e){return{content:[{type:`text`,text:`Error describing tools: ${e instanceof Error?e.message:`Unknown error`}`}],isError:!0}}}};function fr(e){let t=e._meta?.[`agiflowai/capabilities`];return Array.isArray(t)?t.filter(e=>typeof e==`string`):[]}function pr(e){return Array.from(new Set(e.flatMap(e=>fr(e)))).sort()}const mr=y.z.object({capability:y.z.string().optional().describe(`Optional capability filter. Matches explicit capability tags first, then server summaries, server names, tool names, and tool descriptions.`),serverName:y.z.string().optional().describe(`Optional server name filter.`)});var hr=class e{_clientManager;definitionsCacheService;static TOOL_NAME=`list_tools`;constructor(e,t){this._clientManager=e,this.definitionsCacheService=t}formatToolName(e,t,n){return(n.get(e)||[]).length>1?`${t}__${e}`:e}getInputSchema(){return mr}async getDefinition(){let t=await this.definitionsCacheService.getServerDefinitions(),n=t.length>0?t.map(e=>{let t=pr(e.tools),n=t.length>0?t.join(`, `):e.serverInstruction||`No capability summary available`;return`${e.serverName}: ${n}`}).join(`
50
+ `):`No proxied servers available.`;return{name:e.TOOL_NAME,description:`Search proxied MCP tools by server capability summary.\n\nAvailable capabilities:\n${n}`,inputSchema:y.z.toJSONSchema(mr,{reused:`inline`})}}async execute(e){let t=mr.parse(e),n=await this.definitionsCacheService.getServerDefinitions(),r=t.capability?.trim().toLowerCase(),i=t.serverName?.trim().toLowerCase(),a=/* @__PURE__ */ new Map;for(let e of n)for(let t of e.tools)a.has(t.name)||a.set(t.name,[]),a.get(t.name)?.push(e.serverName);let o=n.filter(e=>i&&e.serverName.toLowerCase()!==i?!1:!r||(e.serverInstruction?.toLowerCase()||``).includes(r)||pr(e.tools).some(e=>e.toLowerCase().includes(r))?!0:e.tools.some(t=>{let n=this.formatToolName(t.name,e.serverName,a),i=fr(t);return n.toLowerCase().includes(r)||(t.description||``).toLowerCase().includes(r)||i.some(e=>e.toLowerCase().includes(r))})).map(e=>({server:e.serverName,capabilities:pr(e.tools),summary:e.serverInstruction,tools:e.tools.map(t=>({name:this.formatToolName(t.name,e.serverName,a),description:e.omitToolDescription?void 0:t.description,capabilities:fr(t)}))})).filter(e=>e.tools.length>0);return{content:[{type:`text`,text:JSON.stringify({servers:o},null,2)}],isError:o.length===0||void 0}}};const X=y.z.object({toolName:y.z.string().min(1).describe(`Name of the tool to execute`),toolArgs:y.z.record(y.z.string(),y.z.unknown()).optional().describe(`Arguments to pass to the tool, as discovered from describe_tools`)});var Z=class e{static TOOL_NAME=`use_tool`;clientManager;skillService;definitionsCacheService;serverId;constructor(e,t,n,r){this.clientManager=e,this.skillService=t,this.definitionsCacheService=r||new H(e,t),this.serverId=n||`unknown`}getInputSchema(){return X}getDefinition(){return{name:e.TOOL_NAME,description:`Execute an MCP tool (NOT Skill) with provided arguments. You MUST call describe_tools first to discover the tool's correct arguments. Then to use tool:
51
+ - Provide toolName and toolArgs based on the schema
52
+ - If multiple servers provide the same tool, specify serverName
53
+
54
+ IMPORTANT: Only use tools discovered from describe_tools with id="${this.serverId}".
55
+ `,inputSchema:y.z.toJSONSchema(X,{reused:`inline`})}}async coerceToolArgs(e,t,n){let r=await this.definitionsCacheService.getToolSchema(e,t);if(!r)return n;let i=(0,O.jsonSchemaToZod)(r);return(0,O.coerceArgs)(n,i)}executeSkill(e){return{content:[{type:`text`,text:`Skill "${e.name}" found. Skills provide instructions and should not be executed via use_tool.\n\nUse describe_tools to view the skill details at: ${e.basePath}\n\nThen follow the skill's instructions directly.`}]}}async findPromptSkill(e){if(e)return await this.definitionsCacheService.getPromptSkillByName(e)}executePromptSkill(e){let t=e.skill.folder||`prompt:${e.serverName}/${e.promptName}`;return{content:[{type:`text`,text:`Skill "${e.skill.name}" found. Skills provide instructions and should not be executed via use_tool.\n\nUse describe_tools to view the skill details at: ${t}\n\nThen follow the skill's instructions directly.`}]}}async execute(e){try{let{toolName:t,toolArgs:n={}}=X.parse(e);if(t.startsWith(`skill__`)){let e=t.slice(7);if(this.skillService){let t=await this.skillService.getSkill(e);if(t)return this.executeSkill(t)}let n=await this.findPromptSkill(e);return n?this.executePromptSkill(n):{content:[{type:`text`,text:`Skill "${e}" not found. Use describe_tools to see available skills.`}],isError:!0}}let r=this.clientManager.getKnownServerNames(),{serverName:i,actualToolName:a}=z(t);if(i)try{let e=await this.clientManager.ensureConnected(i);if(e.toolBlacklist?.includes(a))return{content:[{type:`text`,text:`Tool "${a}" is blacklisted on server "${i}" and cannot be executed.`}],isError:!0};let t=this.clientManager.getServerRequestTimeout(i),r=await this.coerceToolArgs(i,a,n);return await e.callTool(a,r,t?{timeout:t}:void 0)}catch(e){return{content:[{type:`text`,text:`Failed to call tool "${a}" on server "${i}". Available servers: ${r.join(`, `)}. ${e instanceof Error?e.message:`Unknown error`}`}],isError:!0}}let o=await this.definitionsCacheService.getServersForTool(a);if(o.length===0&&(this.definitionsCacheService.clearLiveCache(),await this.definitionsCacheService.collectForCache(),o=await this.definitionsCacheService.getServersForTool(a)),o.length===0){if(this.skillService){let e=await this.skillService.getSkill(a);if(e)return this.executeSkill(e)}let e=await this.findPromptSkill(a);return e?this.executePromptSkill(e):{content:[{type:`text`,text:`Tool or skill "${a}" not found. Use describe_tools to see available tools and skills.`}],isError:!0}}if(o.length>1)return{content:[{type:`text`,text:`Tool "${a}" found on multiple servers. Use prefixed format to specify: ${o.map(e=>`${e}__${a}`).join(`, `)}`}],isError:!0};try{let e=o[0],t=await this.clientManager.ensureConnected(e),r=this.clientManager.getServerRequestTimeout(e),i=await this.coerceToolArgs(e,a,n);return await t.callTool(a,i,r?{timeout:r}:void 0)}catch(e){return{content:[{type:`text`,text:`Failed to call tool "${a}": ${e instanceof Error?e.message:`Unknown error`}`}],isError:!0}}}catch(e){return{content:[{type:`text`,text:`Error executing tool: ${e instanceof Error?e.message:`Unknown error`}`}],isError:!0}}}},gr=class{server;handle=null;logger;constructor(e,t=console){this.server=e,this.logger=t}async start(){if(this.handle)throw Error(`MCP stdio server is already running`);this.handle=(0,oe.serveStdio)(()=>this.server,{legacy:`reject`}),this.logger.info(`@agimon-ai/po-mcp-proxy MCP server started on stdio`)}async stop(){let e=this.handle;e&&(this.handle=null,await e.close())}};const _r=[`econnrefused`,`econnreset`,`enotfound`,`connection refused`,`fetch failed`,`socket hang up`,`network error`,`failed to fetch`];function vr(e){if(!(e instanceof Error))return!1;let t=e.message.toLowerCase();return _r.some(e=>t.includes(e))}function yr(e){let t=/* @__PURE__ */ new Set,n=[],r=e;for(;r&&!t.has(r);)if(t.add(r),r instanceof Error){let e=r;n.push({message:r.message,code:e.code}),r=e.cause}else if(typeof r==`object`){let e=r;n.push({message:typeof e.message==`string`?e.message:(0,D.inspect)(r),code:typeof e.code==`string`?e.code:void 0}),r=e.cause}else{n.push({message:typeof r==`string`?r:(0,D.inspect)(r)});break}return n}function br(e){return yr(e).some(({message:e,code:t})=>{let n=e.toLowerCase(),r=xr(t);return n.includes(`unknown session`)||n.includes(`session not found`)||n.includes(`transport closed`)||n.includes(`connection closed`)||n.includes(`socket hang up`)||n.includes(`fetch failed`)||r===`econnreset`})}function xr(e){return typeof e==`string`?e.toLowerCase():void 0}var Sr=class{endpoint;resolveEndpoint;stdioProxyServer=null;stdioHandle=null;httpClient=null;logger;MAX_RECONNECT_ATTEMPTS=5;RECONNECT_BASE_MS=1e3;RECONNECT_MAX_MS=3e4;constructor(e,t=console){this.endpoint=e.endpoint,this.resolveEndpoint=e.resolveEndpoint,this.logger=t}async start(){try{let e=await this.createAndConnectClient();this.httpClient=e,this.stdioProxyServer=this.createProxyServer(),this.stdioHandle=(0,oe.serveStdio)(()=>this.stdioProxyServer,{legacy:`reject`}),this.logger.info(`@agimon-ai/po-mcp-proxy MCP stdio proxy connected to ${this.endpoint.toString()}`)}catch(e){throw await this.stop(),Error(`Failed to start stdio-http proxy transport: ${e instanceof Error?e.message:String(e)}`)}}async stop(){let e=this.stdioHandle,t=this.stdioProxyServer,n=this.httpClient;this.stdioHandle=null,this.stdioProxyServer=null,this.httpClient=null;let r=[];if(await Promise.all([(async()=>{try{e&&await e.close()}catch(e){r.push(`failed closing stdio transport: ${e instanceof Error?e.message:String(e)}`)}})(),(async()=>{try{t&&await t.close()}catch(e){r.push(`failed closing stdio proxy server: ${e instanceof Error?e.message:String(e)}`)}})(),(async()=>{try{n&&await n.close()}catch(e){r.push(`failed closing http client: ${e instanceof Error?e.message:String(e)}`)}})()]),r.length>0)throw Error(`Failed to stop stdio-http proxy transport: ${r.join(`; `)}`)}async createAndConnectClient(){let e=new w.StreamableHTTPClientTransport(this.endpoint),t=new w.Client({name:`@agimon-ai/po-mcp-proxy-stdio-http-proxy`,version:`0.1.0`},{capabilities:{},versionNegotiation:{mode:{pin:`2026-07-28`}}});return await t.connect(e),t}async reconnectWithBackoff(){for(let e=0;e<this.MAX_RECONNECT_ATTEMPTS;e++){let t=Math.min(this.RECONNECT_BASE_MS*2**e,this.RECONNECT_MAX_MS);await new Promise(e=>setTimeout(e,t));try{this.resolveEndpoint&&(this.endpoint=await this.resolveEndpoint()),await this.httpClient?.close().catch(()=>void 0);let t=await this.createAndConnectClient();this.httpClient=t,this.logger.info(`Reconnected to HTTP backend at ${this.endpoint.toString()} (attempt ${e+1})`);return}catch{this.logger.info(`Reconnect attempt ${e+1}/${this.MAX_RECONNECT_ATTEMPTS} to ${this.endpoint.toString()} failed`)}}throw Error(`Failed to reconnect to HTTP backend at ${this.endpoint.toString()} after ${this.MAX_RECONNECT_ATTEMPTS} attempts`)}async withReconnect(e,t=!0){if(!this.httpClient)throw Error(`HTTP client not connected`);try{return await e()}catch(n){if(vr(n)||br(n)){if(await this.reconnectWithBackoff(),t)return await e();throw Error(`The connection was recovered, but the prior tool call may have executed; refusing to replay it.`,{cause:n})}throw n}}createProxyServer(){let e=new b.Server({name:`@agimon-ai/po-mcp-proxy-stdio-http-proxy`,version:`0.1.0`},{capabilities:{tools:{},resources:{},prompts:{}}});return e.setRequestHandler(`tools/list`,async()=>{try{return await this.withReconnect(()=>this.httpClient.listTools())}catch(e){throw Error(`Failed forwarding tools/list to HTTP backend: ${e instanceof Error?e.message:String(e)}`)}}),e.setRequestHandler(`tools/call`,async e=>{try{return await this.withReconnect(()=>this.httpClient.callTool({name:e.params.name,arguments:e.params.arguments}),!1)}catch(t){throw Error(`Failed forwarding tools/call (${e.params.name}) to HTTP backend: ${t instanceof Error?t.message:String(t)}`)}}),e.setRequestHandler(`resources/list`,async()=>{try{return await this.withReconnect(()=>this.httpClient.listResources())}catch(e){throw Error(`Failed forwarding resources/list to HTTP backend: ${e instanceof Error?e.message:String(e)}`)}}),e.setRequestHandler(`resources/read`,async e=>{try{return await this.withReconnect(()=>this.httpClient.readResource({uri:e.params.uri}))}catch(t){throw Error(`Failed forwarding resources/read (${e.params.uri}) to HTTP backend: ${t instanceof Error?t.message:String(t)}`)}}),e.setRequestHandler(`prompts/list`,async()=>{try{return await this.withReconnect(()=>this.httpClient.listPrompts())}catch(e){throw Error(`Failed forwarding prompts/list to HTTP backend: ${e instanceof Error?e.message:String(e)}`)}}),e.setRequestHandler(`prompts/get`,async e=>{try{return await this.withReconnect(()=>this.httpClient.getPrompt({name:e.params.name,arguments:e.params.arguments}))}catch(t){throw Error(`Failed forwarding prompts/get (${e.params.name}) to HTTP backend: ${t instanceof Error?t.message:String(t)}`)}}),e}};function Q(e=console,t,n,r){return{createConfigFetcherService:t=>new St(t,e),createClientManagerService:(i,a,o,s)=>t||n||r?new Sn(e,k(t??r),new W(i),a,t?k(t):void 0,n,r,o,s):new Sn(e,k(),new W(i),a,void 0,void 0,void 0,o,s),createRuntimeStateService:t=>new K(t,e),createStopServerService:t=>new Wn(t,e),createSkillService:(t,n,r)=>new In(t,n,r,e),createDefinitionsCacheService:(t,n,r)=>new H(t,n,r,e),createPrefetchService:e=>new Dn(e),createDescribeToolsTool:(e,t,n,r)=>new Y(e,t,n,r),createUseToolTool:(e,t,n,r)=>new Z(e,t,n,r),createSearchListToolsTool:(e,t)=>new hr(e,t),createStdioTransportHandler:async t=>new gr(await t(),e),createHttpTransportHandler:(t,n,r)=>new qn(t,n,r,e),createStdioHttpTransportHandler:t=>new Sr({endpoint:t},e)}}async function Cr(e,t,n,r){try{return await e.createConfigFetcherService({configSources:t,useCache:!n,env:r}).fetchConfiguration(n)}catch(e){let n=t.map(e=>e.path);throw Error(`Failed to load MCP configuration from '${n.join(`, `)}': ${e instanceof Error?e.message:String(e)}`)}}async function wr(e,t,n){let r=[];return await Promise.all(Object.entries(t).map(async([t,i])=>{try{await e.connectToServer(t,i),n.info(`Connected to MCP server: ${t}`)}catch(e){let i=e instanceof Error?e:Error(String(e));r.push({serverName:t,error:i}),n.warn(`Failed to connect to ${t}`,e)}})),r}async function Tr(e){let t=e?.workspaceRoot,n=e?.executionCwd;if(n!==void 0&&!l.default.isAbsolute(n))throw Error(`executionCwd must be an absolute directory`);let r=e?.environment?{...process.env,...e.environment}:void 0,i=k(t??n),a=await Ht({workspaceRoot:i,serviceName:`@agimon-ai/mcp-proxy`,env:r}),o=a,s=Q(o,t?i:void 0,e?.environment,n),c=[],u=!1,d,f=()=>d||(u=!0,d=(async()=>{let e=await Promise.allSettled(c.map(e=>Promise.resolve().then(e)));try{await a.shutdown()}catch(t){e.push({status:`rejected`,reason:t})}let t=e.flatMap(e=>e.status===`rejected`?[e.reason]:[]);if(t.length)throw AggregateError(t,`MCP proxy disposal failed`)})(),d);try{let a,d,p,m,h=!1,g,_=e?.startupMode??`blocking`,v,y=Tt(e?.configFilePath),b=(e?.configSources?.length?e.configSources:Et(y)).map(e=>t?{...e,path:l.default.resolve(i,e.path)}:e),x=b.map(e=>e.path),S=b.length>0?await Cr(s,b,e?.noCache===!0,r):void 0,C=s.createClientManagerService(Wt(S?.proxy?.outputGuard),e?.auth,e?.outputSchemaValidation,e?.clientCapabilities);if(c.push(()=>C.dispose()),S){if(a=S.skills,d=S.id,p=H.generateConfigHash(S),m=e?.definitionsCachePath||H.getDefaultCachePath(x),C.registerServerConfigs(S.mcpServers),e?.clearDefinitionsCache&&m&&(await H.clearFile(m),o.info(`[definitions-cache] Cleared ${m}`)),m){let e=await H.inspectFile(m,{configHash:p,oneMcpVersion:lr});e.state===`usable`?(g=e.cache,h=!0,o.info(`[definitions-cache] Cache is usable`,{"definitions_cache.state":e.state,"definitions_cache.path":e.cachePath,"definitions_cache.server_count":Object.keys(e.cache.servers).length})):e.state===`absent`?o.info(`[definitions-cache] Cache is absent; using live discovery`,{"definitions_cache.state":e.state,"definitions_cache.path":e.cachePath}):o.warn(`[definitions-cache] Cache is invalid; using live discovery`,{"definitions_cache.state":e.state,"definitions_cache.path":e.cachePath,"definitions_cache.reason":e.reason,"definitions_cache.error":e.error})}if(h&&o.info(`[definitions-cache] Using cached definitions from ${m}`),_===`background`)v=wr(C,S.mcpServers,o).then(e=>{e.length>0&&o.warn(`MCP server connections failed: ${e.map(e=>e.serverName).join(`, `)}`)},e=>{o.warn(`[mcp-proxy] Background connection pass failed: ${e instanceof Error?e.message:String(e)}`)});else if(_!==`lazy`&&!h){let e=Object.keys(S.mcpServers).length,t=await wr(C,S.mcpServers,o);if(t.length>0&&t.length<e&&o.warn(`Warning: Some MCP server connections failed: ${t.map(e=>e.serverName).join(`, `)}`),t.length>0&&t.length===e)throw Error(`All MCP server connections failed: ${t.map(e=>`${e.serverName}: ${e.error.message}`).join(`, `)}`)}}let w=e?.serverId||d||Ot();o.info(`[mcp-proxy] Server ID: ${w}`);let ee=(e?.skills||a)?.paths??[],te={describeTools:null},T=ee.length>0?s.createSkillService(n??(t?i:process.cwd()),ee,{onCacheInvalidated:()=>{te.describeTools?.clearAutoDetectedSkillsCache()}}):void 0,E=s.createDefinitionsCacheService(C,T,g?{cacheData:g}:void 0);g&&E.logCapabilitySummary(g,`cache`);let D=e?.proxyMode||`meta`,ne=s.createDescribeToolsTool(C,T,w,E),re=s.createUseToolTool(C,T,w,E),ie=s.createSearchListToolsTool(C,E);return te.describeTools=ne,T&&(c.push(()=>T.stopWatching()),T.startWatching().catch(e=>{o.warn(`[skill-watcher] File watcher failed (non-critical): ${e instanceof Error?e.message:`Unknown error`}`)})),_!==`lazy`&&!h&&m&&x.length>0&&(v??Promise.resolve()).then(()=>u?void 0:E.collectForCache({configPath:x[0],configHash:p,serverNames:Object.keys(S?.mcpServers??{}),oneMcpVersion:lr,serverId:w})).then(e=>u||e===void 0?void 0:H.writeToFile(m,e)).then(()=>{o.info(`[definitions-cache] Wrote ${m}`)}).catch(e=>{o.warn(`[definitions-cache] Failed to persist ${m}: ${e instanceof Error?e.message:`Unknown error`}`)}),we(),c.push(()=>Te()),{clientManager:C,definitionsCacheService:E,skillService:T,logger:o,describeTools:ne,useTool:re,searchListTools:ie,serverId:w,proxyMode:D,connectionsSettled:v??Promise.resolve(),dispose:f}}catch(e){try{await f()}catch(t){throw AggregateError([e,t],`MCP proxy startup and cleanup failed`)}throw e}}async function Er(e){let t=await e();return Q().createStdioTransportHandler(()=>Promise.resolve(t))}function Dr(e,t,n){return Q().createHttpTransportHandler(e,t,n)}function Or(e){return Q().createStdioHttpTransportHandler(e)}async function kr(e){return Tr(e)}function Ar(e){let t=e.tools.map(e=>e.name),n=pr(e.tools),r=n.length>0?`; capabilities: ${n.join(`, `)}`:``;return t.length===0?`${e.serverName} (no tools cached${r})`:`${e.serverName} (${t.join(`, `)})${r}`}function jr(e,t){let n=[`Proxied from server "${e.serverName}" as tool "${t.name}".`];e.serverInstruction&&n.push(`Server summary: ${e.serverInstruction}`),t.description&&!e.omitToolDescription&&n.push(t.description);let r=fr(t);return r.length>0&&n.push(`Capabilities: ${r.join(`, `)}`),n.join(`
56
+
57
+ `)}function Mr(e){let t=/* @__PURE__ */ new Map;for(let n of e)for(let e of n.tools)t.has(e.name)||t.set(e.name,[]),t.get(e.name)?.push(n.serverName);let n=[];for(let r of e)for(let e of r.tools){let i=(t.get(e.name)||[]).length>1;n.push({name:i?`${r.serverName}__${e.name}`:e.name,description:jr(r,e),inputSchema:e.inputSchema,_meta:e._meta})}return n}function $(e,t){return`${e}__${t}`}function Nr(e){let t=`__${Y.TOOL_NAME}`;if(e.endsWith(t)&&e.length>t.length)return{serverName:e.slice(0,-t.length),metaToolName:Y.TOOL_NAME};let n=`__${Z.TOOL_NAME}`;return e.endsWith(n)&&e.length>n.length?{serverName:e.slice(0,-n.length),metaToolName:Z.TOOL_NAME}:null}function Pr(e){let t=[`Get detailed schemas for tools proxied by server "${e.serverName}".`,`Call this before using the paired use_tool for this server.`];if(e.serverInstruction&&t.push(`Server summary: ${e.serverInstruction}`),e.tools.length===0)return t.push(`Available tools: none cached.`),t.join(`
58
+
59
+ `);let n=e.tools.map(t=>e.omitToolDescription?`- ${t.name}`:`- ${t.name}: ${t.description||`No description`}`);return t.push(`Available tools:\n${n.join(`
60
+ `)}`),t.join(`
61
+
62
+ `)}function Fr(e){let t=[];for(let n of e)t.push({name:$(n.serverName,Y.TOOL_NAME),description:Pr(n),inputSchema:y.z.toJSONSchema(J,{reused:`inline`})}),t.push({name:$(n.serverName,Z.TOOL_NAME),description:[`Execute an MCP tool proxied by server "${n.serverName}".`,`Call ${$(n.serverName,Y.TOOL_NAME)} first to discover tool schemas.`,`Pass the downstream tool name without a server prefix in toolName.`].join(`
63
+
64
+ `),inputSchema:y.z.toJSONSchema(X,{reused:`inline`})});return t}function Ir(e,t){if(!e)return{foundTools:[],notFoundItems:t};let n=[],r=[];for(let i of t){let t=e.tools.find(e=>e.name===i);t?n.push({name:t.name,description:t.description,inputSchema:t.inputSchema}):r.push(i)}return{foundTools:n,notFoundItems:r}}async function Lr(e,t){let[n,r]=await Promise.all([t?t.getSkills():e.getCachedFileSkills(),e.getServerDefinitions()]);return n.length>0||r.some(e=>e.promptSkills.length>0)}function Rr(e,t){let n=e.length>0?e.map(Ar).join(`; `):`No proxied servers available.`;return{name:Y.TOOL_NAME,description:`Get detailed skill instructions for file-based skills and prompt-based skills proxied by mcp-proxy.\n\nProxy summary: ${n}\n\nUse this when you need the full instructions for a skill. For MCP tools, call the flat tool names directly. Only use skills discovered from describe_tools with id="${t}".`,inputSchema:{type:`object`,properties:{toolNames:{type:`array`,items:{type:`string`,minLength:1},description:`List of skill names to get detailed information about`,minItems:1}},required:[`toolNames`],additionalProperties:!1}}}function zr(e,t){let n=e.length>0?e.map(Ar).join(`; `):`No proxied servers available.`;return{name:Y.TOOL_NAME,description:`Get detailed schemas and skill instructions for proxied MCP capabilities.\n\nProxy summary: ${n}\n\nUse list_tools first to search capability summaries and discover tool names. Then use describe_tools to fetch full schemas or skill instructions. Only use capabilities discovered from mcp-proxy id="${t}".`,inputSchema:{type:`object`,properties:{toolNames:{type:`array`,items:{type:`string`,minLength:1},description:`List of tool or skill names to get detailed information about`,minItems:1}},required:[`toolNames`],additionalProperties:!1}}}function Br(e,t,n){let r=e.length>0?e.map(Ar).join(`; `):`No proxied servers available.`;return t===`flat`?[`mcp-proxy proxies downstream MCP servers and exposes their tools and resources directly.`,`Proxied servers and tools: ${r}`,n?`Skills are still exposed through describe_tools when file-based skills or prompt-backed skills are configured.`:`No skills are currently exposed through describe_tools.`].join(`
65
+
66
+ `):t===`search`?[`mcp-proxy proxies downstream MCP servers in search mode.`,`Proxied servers and tools: ${r}`,`Use list_tools to search capability summaries and discover tool names, describe_tools to fetch schemas or skill instructions, and use_tool to execute tools.`].join(`
67
+
68
+ `):t===`group`?[`mcp-proxy proxies downstream MCP servers in group mode.`,`Proxied servers and tools: ${r}`,`Use each server-specific describe_tools tool to inspect schemas, then the matching server-specific use_tool tool to execute plain downstream tool names.`].join(`
69
+
70
+ `):[`mcp-proxy proxies downstream MCP servers in meta mode.`,`Proxied servers and tools: ${r}`,`Use describe_tools to inspect capabilities and use_tool to execute them.`].join(`
71
+
72
+ `)}async function Vr(e){let{clientManager:t,definitionsCacheService:n,skillService:r,logger:i,describeTools:a,useTool:o,searchListTools:s,serverId:c,proxyMode:l}=e,u=await n.getServerDefinitions(),d=await Lr(n,r),f=async(e,t,n)=>i.runInSpan?i.runInSpan(e,{attributes:t},async()=>n()):await n(),p=new b.Server({name:`@agimon-ai/po-mcp-proxy`,version:`0.1.0`},{capabilities:{tools:{},resources:{},prompts:{}},instructions:Br(u,l,d)});return p.setRequestHandler(`tools/list`,async()=>f(`mcp.server.list_tools`,{"mcp.service":`@agimon-ai/po-mcp-proxy`},async()=>({tools:(l===`flat`?await(async()=>{let e=await n.getServerDefinitions(),t=await Lr(n,r);return[...Mr(e),...t?[Rr(e,c)]:[]]})():l===`search`?await(async()=>[zr(await n.getServerDefinitions(),c),await s.getDefinition(),o.getDefinition()])():l===`group`?Fr(await n.getServerDefinitions()):[await a.getDefinition(),o.getDefinition()]).map(e=>{if(e.inputSchema.type!==`object`)throw Error(`Tool ${e.name} must declare an object input schema`);return{...e,inputSchema:{...e.inputSchema,type:`object`}}})}))),p.setRequestHandler(`tools/call`,async e=>{let{name:t,arguments:r}=e.params;return await f(`mcp.server.call_tool`,{"mcp.service":`@agimon-ai/po-mcp-proxy`,"mcp.tool.name":t},async()=>{let e=async(e,t)=>{let n=(0,O.coerceArgs)(r??{},e.getInputSchema());try{return await e.execute(n)}catch(n){if(n instanceof y.z.ZodError)return{content:[{type:`text`,text:(0,O.formatZodError)(n,{schemaName:t,schema:e.getInputSchema()})}],isError:!0};throw Error(`Failed to execute ${t}: ${n instanceof Error?n.message:String(n)}`)}};if(t===Y.TOOL_NAME&&l!==`group`)return await e(a,t);if(t===Z.TOOL_NAME&&l!==`group`)return await e(o,t);if(t===hr.TOOL_NAME&&l===`search`)return await e(s,t);let i=l===`group`?Nr(t):null;if(i?.metaToolName===Y.TOOL_NAME){let e=J.safeParse((0,O.coerceArgs)(r??{},J));if(!e.success)return{content:[{type:`text`,text:(0,O.formatZodError)(e.error,{schemaName:t,schema:J})}],isError:!0};let a=e.data,o=await n.getServerDefinitions(),s=o.find(e=>e.serverName===i.serverName),c=Ir(s,a.toolNames);if((c.notFoundItems.length>0||!s)&&(n.clearLiveCache(),await n.collectForCache(),o=await n.getServerDefinitions(),s=o.find(e=>e.serverName===i.serverName),c=Ir(s,a.toolNames)),!s)return{content:[{type:`text`,text:`Server "${i.serverName}" not found. Available servers: ${o.map(e=>e.serverName).join(`, `)}`}],isError:!0};if(c.foundTools.length===0)return{content:[{type:`text`,text:`None of the requested tools found on server "${i.serverName}". Requested: ${a.toolNames.join(`, `)}`}],isError:!0};let l={server:i.serverName,tools:c.foundTools,nextSteps:[`Use ${$(i.serverName,Z.TOOL_NAME)} with a plain toolName and toolArgs based on the inputSchema above.`]};return c.notFoundItems.length>0&&(l.notFound=c.notFoundItems),{content:[{type:`text`,text:JSON.stringify(l,null,2)}]}}if(i?.metaToolName===Z.TOOL_NAME){let e=X.safeParse((0,O.coerceArgs)(r??{},X));if(!e.success)return{content:[{type:`text`,text:(0,O.formatZodError)(e.error,{schemaName:t,schema:X})}],isError:!0};let n=e.data;return z(n.toolName).serverName?{content:[{type:`text`,text:`Tool "${t}" is already scoped to server "${i.serverName}". Pass the downstream tool name without a server prefix.`}],isError:!0}:await o.execute({toolName:$(i.serverName,n.toolName),toolArgs:n.toolArgs||{}})}if(l===`flat`)return await o.execute({toolName:t,toolArgs:r||{}});throw Error(`Unknown tool: ${t}`)})}),p.setRequestHandler(`resources/list`,async()=>{let e=await n.getServerDefinitions(),t=/* @__PURE__ */ new Map;for(let n of e)for(let e of n.resources)t.has(e.uri)||t.set(e.uri,[]),t.get(e.uri)?.push(n.serverName);let r=[];for(let n of e)for(let e of n.resources){let i=(t.get(e.uri)||[]).length>1;r.push({...e,name:e.name??e.uri,uri:i?`${n.serverName}__${e.uri}`:e.uri})}return{resources:r}}),p.setRequestHandler(`resources/read`,async e=>{let{uri:r}=e.params,{serverName:i,actualToolName:a}=z(r);if(i)return await(await t.ensureConnected(i)).readResource(a);let o=await n.getServersForResource(a);if(o.length===0)throw Error(`Resource not found: ${r}`);if(o.length>1)throw Error(`Resource "${a}" exists on multiple servers: ${o.join(`, `)}. Use the prefixed format (e.g., "${o[0]}__${a}") to specify which server to use.`);return await(await t.ensureConnected(o[0])).readResource(a)}),p.setRequestHandler(`prompts/list`,async()=>{let e=await n.getServerDefinitions(),t=/* @__PURE__ */ new Map,r=/* @__PURE__ */ new Map;for(let n of e){r.set(n.serverName,n.prompts);for(let e of n.prompts)t.has(e.name)||t.set(e.name,[]),t.get(e.name).push(n.serverName)}let i=[];for(let n of e){let e=r.get(n.serverName)||[];for(let r of e){let e=(t.get(r.name)||[]).length>1;i.push({name:e?`${n.serverName}__${r.name}`:r.name,description:r.description,arguments:r.arguments})}}return{prompts:i}}),p.setRequestHandler(`prompts/get`,async e=>{let{name:r,arguments:i}=e.params,a=await n.getServerDefinitions(),{serverName:o,actualToolName:s}=z(r);if(o)return await(await t.ensureConnected(o)).getPrompt(s,i);let c=[];for(let e of a)e.prompts.some(e=>e.name===r)&&c.push(e.serverName);if(c.length===0)throw Error(`Prompt not found: ${r}`);if(c.length>1)throw Error(`Prompt "${r}" exists on multiple servers: ${c.join(`, `)}. Use the prefixed format (e.g., "${c[0]}__${r}") to specify which server to use.`);let l=t.getClient(c[0]);return l?await l.getPrompt(r,i):await(await t.ensureConnected(c[0])).getPrompt(r,i)}),p}async function Hr(e){let t=await Tr(e),n=await Vr(t);return Object.assign(n,{dispose:t.dispose}),n}const Ur={STDIO:`stdio`,HTTP:`http`,SSE:`sse`};Object.defineProperty(exports,"$",{enumerable:!0,get:function(){return _e}}),Object.defineProperty(exports,"A",{enumerable:!0,get:function(){return Ht}}),Object.defineProperty(exports,"B",{enumerable:!0,get:function(){return Ue}}),Object.defineProperty(exports,"C",{enumerable:!0,get:function(){return Wn}}),Object.defineProperty(exports,"D",{enumerable:!0,get:function(){return gn}}),Object.defineProperty(exports,"E",{enumerable:!0,get:function(){return Sn}}),Object.defineProperty(exports,"F",{enumerable:!0,get:function(){return wt}}),Object.defineProperty(exports,"G",{enumerable:!0,get:function(){return Pe}}),Object.defineProperty(exports,"H",{enumerable:!0,get:function(){return He}}),Object.defineProperty(exports,"I",{enumerable:!0,get:function(){return Tt}}),Object.defineProperty(exports,"J",{enumerable:!0,get:function(){return Ie}}),Object.defineProperty(exports,"K",{enumerable:!0,get:function(){return Fe}}),Object.defineProperty(exports,"L",{enumerable:!0,get:function(){return Et}}),Object.defineProperty(exports,"M",{enumerable:!0,get:function(){return Nt}}),Object.defineProperty(exports,"N",{enumerable:!0,get:function(){return Ot}}),Object.defineProperty(exports,"O",{enumerable:!0,get:function(){return W}}),Object.defineProperty(exports,"P",{enumerable:!0,get:function(){return Dt}}),Object.defineProperty(exports,"Q",{enumerable:!0,get:function(){return 100}}),Object.defineProperty(exports,"R",{enumerable:!0,get:function(){return St}}),Object.defineProperty(exports,"S",{enumerable:!0,get:function(){return qn}}),Object.defineProperty(exports,"T",{enumerable:!0,get:function(){return K}}),Object.defineProperty(exports,"U",{enumerable:!0,get:function(){return We}}),Object.defineProperty(exports,"V",{enumerable:!0,get:function(){return Be}}),Object.defineProperty(exports,"W",{enumerable:!0,get:function(){return Re}}),Object.defineProperty(exports,"X",{enumerable:!0,get:function(){return 6e4}}),Object.defineProperty(exports,"Y",{enumerable:!0,get:function(){return Oe}}),Object.defineProperty(exports,"Z",{enumerable:!0,get:function(){return 250}}),Object.defineProperty(exports,"_",{enumerable:!0,get:function(){return $n}}),Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return Tr}}),Object.defineProperty(exports,"at",{enumerable:!0,get:function(){return Ce}}),Object.defineProperty(exports,"b",{enumerable:!0,get:function(){return tr}}),Object.defineProperty(exports,"c",{enumerable:!0,get:function(){return Er}}),Object.defineProperty(exports,"ct",{enumerable:!0,get:function(){return pe}}),Object.defineProperty(exports,"d",{enumerable:!0,get:function(){return gr}}),Object.defineProperty(exports,"dt",{enumerable:!0,get:function(){return k}}),Object.defineProperty(exports,"et",{enumerable:!0,get:function(){return ge}}),Object.defineProperty(exports,"f",{enumerable:!0,get:function(){return Z}}),Object.defineProperty(exports,"ft",{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,"g",{enumerable:!0,get:function(){return Yn}}),Object.defineProperty(exports,"h",{enumerable:!0,get:function(){return lr}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return Dr}}),Object.defineProperty(exports,"it",{enumerable:!0,get:function(){return Ee}}),Object.defineProperty(exports,"j",{enumerable:!0,get:function(){return H}}),Object.defineProperty(exports,"k",{enumerable:!0,get:function(){return Wt}}),Object.defineProperty(exports,"l",{enumerable:!0,get:function(){return kr}}),Object.defineProperty(exports,"lt",{enumerable:!0,get:function(){return le}}),Object.defineProperty(exports,"m",{enumerable:!0,get:function(){return Y}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return Hr}}),Object.defineProperty(exports,"nt",{enumerable:!0,get:function(){return Se}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return Q}}),Object.defineProperty(exports,"ot",{enumerable:!0,get:function(){return Te}}),Object.defineProperty(exports,"p",{enumerable:!0,get:function(){return hr}}),Object.defineProperty(exports,"q",{enumerable:!0,get:function(){return Ae}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return Vr}}),Object.defineProperty(exports,"rt",{enumerable:!0,get:function(){return we}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return Or}}),Object.defineProperty(exports,"st",{enumerable:!0,get:function(){return he}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return Ur}}),Object.defineProperty(exports,"tt",{enumerable:!0,get:function(){return me}}),Object.defineProperty(exports,"u",{enumerable:!0,get:function(){return Sr}}),Object.defineProperty(exports,"ut",{enumerable:!0,get:function(){return fe}}),Object.defineProperty(exports,"v",{enumerable:!0,get:function(){return Zn}}),Object.defineProperty(exports,"w",{enumerable:!0,get:function(){return In}}),Object.defineProperty(exports,"x",{enumerable:!0,get:function(){return cr}}),Object.defineProperty(exports,"y",{enumerable:!0,get:function(){return sr}}),Object.defineProperty(exports,"z",{enumerable:!0,get:function(){return vt}});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agimon-ai/po-mcp-proxy",
3
- "version": "0.0.1-alpha.2",
3
+ "version": "0.0.1-alpha.21",
4
4
  "description": "MCP proxy server package",
5
5
  "keywords": [
6
6
  "ai",
@@ -49,10 +49,10 @@
49
49
  "access": "public"
50
50
  },
51
51
  "dependencies": {
52
- "@agimon-ai/foundation-port-registry": "0.30.13",
53
- "@agimon-ai/foundation-process-registry": "0.30.13",
54
- "@agimon-ai/foundation-validator": "0.27.13",
55
- "@agimon-ai/po-logsink": "0.0.1-alpha.5",
52
+ "@agimon-ai/foundation-port-registry": "0.30.14",
53
+ "@agimon-ai/foundation-process-registry": "0.30.14",
54
+ "@agimon-ai/foundation-validator": "0.27.14",
55
+ "@agimon-ai/po-logsink": "0.0.1-alpha.24",
56
56
  "@hono/node-server": "2.1.5",
57
57
  "@modelcontextprotocol/client": "2.3.1",
58
58
  "@modelcontextprotocol/core": "2.3.1",
@@ -61,13 +61,15 @@
61
61
  "commander": "15.0.0",
62
62
  "gray-matter": "4.0.3",
63
63
  "hono": "4.13.13",
64
- "js-yaml": "5.4.3",
65
- "liquidjs": "10.30.0"
64
+ "js-yaml": "5.5.0",
65
+ "liquidjs": "10.30.0",
66
+ "proper-lockfile": "4.1.2"
66
67
  },
67
68
  "devDependencies": {
68
69
  "@modelcontextprotocol/sdk-v1": "npm:@modelcontextprotocol/sdk@1.32.1",
69
70
  "@types/js-yaml": "4.0.9",
70
71
  "@types/node": "26.6.5",
72
+ "@types/proper-lockfile": "4.1.4",
71
73
  "tsdown": "0.23.1",
72
74
  "typescript": "7.0.2",
73
75
  "unplugin-raw": "0.8.0",