@onyxsecurity/mcp-gateway 1.0.68 → 1.0.69

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.
@@ -1,8 +1,8 @@
1
- import{AccessControlBlockError as e,Client as t,ConfigurationError as n,ProxyConnectionError as r,ReadBuffer as i,Server as a,StdioServerTransport as o,compressClientInfo as s,getSessionData as c,initializeTrafficMirror as l,logRequestCounts as u,proxyServer as d,redactCliArgs as f,serializeMessage as p,startHTTPServer as m}from"./stdio-BekdIiS9.js";import{UnauthorizedError as h,createParser as g,normalizeUrl as _}from"./normalizeUrl-fkFv5Mfb.js";import{config as v}from"./env-De1WIFCY.js";import{chownToRealUser as y,extractTraceIdFromHeaders as ee,flushLogs as b,logger as x}from"./logger-CjtkOPTS.js";import{emitKeychainOutcomeLog as te,emitProxySetupLog as ne,hideBin as re,yargs_default as ie}from"./helpers-DpRe9vc7.js";import"./providers-1NndXxjs.js";import{initializeOAuthProviders as ae}from"./oauthProvidersClient-BLKyyoBP.js";import"./pkce-DKfQXsGm.js";import{connectWithTransportFallback as oe,performOAuthFlow as se,tryRefreshCachedToken as S}from"./transportDetection-CmcffTDU.js";import{join as C}from"node:path";import{createHash as w}from"node:crypto";import{chmod as T,mkdir as E,readFile as D,rm as O,writeFile as ce}from"node:fs/promises";import{StringDecoder as le}from"node:string_decoder";import{setTimeout as ue}from"node:timers";import de from"node:util";import{execSync as k,spawn as A,spawnSync as j}from"node:child_process";import{PassThrough as fe,Transform as pe}from"node:stream";var me=class extends Event{constructor(e,t){super(e),this.code=t?.code??void 0,this.message=t?.message??void 0}[Symbol.for(`nodejs.util.inspect.custom`)](e,t,n){return n(ge(this),t)}[Symbol.for(`Deno.customInspect`)](e,t){return e(ge(this),t)}};function he(e){let t=globalThis.DOMException;return typeof t==`function`?new t(e,`SyntaxError`):SyntaxError(e)}function M(e){return e instanceof Error?`errors`in e&&Array.isArray(e.errors)?e.errors.map(M).join(`, `):`cause`in e&&e.cause instanceof Error?`${e}: ${M(e.cause)}`:e.message:`${e}`}function ge(e){return{type:e.type,message:e.message,code:e.code,defaultPrevented:e.defaultPrevented,cancelable:e.cancelable,timeStamp:e.timeStamp}}var _e=e=>{throw TypeError(e)},N=(e,t,n)=>t.has(e)||_e(`Cannot `+n),P=(e,t,n)=>(N(e,t,`read from private field`),n?n.call(e):t.get(e)),F=(e,t,n)=>t.has(e)?_e(`Cannot add the same private member more than once`):t instanceof WeakSet?t.add(e):t.set(e,n),I=(e,t,n,r)=>(N(e,t,`write to private field`),t.set(e,n),n),L=(e,t,n)=>(N(e,t,`access private method`),n),R,z,B,V,H,U,W,G,K,q,J,Y,X,Z,ve,ye,be,xe,Se,Ce,Q,we,Te,$=class extends EventTarget{constructor(e,t){super(),F(this,Z),this.CONNECTING=0,this.OPEN=1,this.CLOSED=2,F(this,R),F(this,z),F(this,B),F(this,V),F(this,H),F(this,U),F(this,W),F(this,G,null),F(this,K),F(this,q),F(this,J,null),F(this,Y,null),F(this,X,null),F(this,ye,async e=>{var t;P(this,q).reset();let{body:n,redirected:r,status:i,headers:a}=e;if(i===204){L(this,Z,Q).call(this,`Server sent HTTP 204, not reconnecting`,204),this.close();return}if(r?I(this,B,new URL(e.url)):I(this,B,void 0),i!==200){L(this,Z,Q).call(this,`Non-200 status code (${i})`,i);return}if(!(a.get(`content-type`)||``).startsWith(`text/event-stream`)){L(this,Z,Q).call(this,`Invalid content type, expected "text/event-stream"`,i);return}if(P(this,R)===this.CLOSED)return;I(this,R,this.OPEN);let o=new Event(`open`);if((t=P(this,X))==null||t.call(this,o),this.dispatchEvent(o),typeof n!=`object`||!n||!(`getReader`in n)){L(this,Z,Q).call(this,`Invalid response body, expected a web ReadableStream`,i),this.close();return}let s=new TextDecoder,c=n.getReader(),l=!0;do{let{done:e,value:t}=await c.read();t&&P(this,q).feed(s.decode(t,{stream:!e})),e&&(l=!1,P(this,q).reset(),L(this,Z,we).call(this))}while(l)}),F(this,be,e=>{I(this,K,void 0),!(e.name===`AbortError`||e.type===`aborted`)&&L(this,Z,we).call(this,M(e))}),F(this,Se,e=>{typeof e.id==`string`&&I(this,G,e.id);let t=new MessageEvent(e.event||`message`,{data:e.data,origin:P(this,B)?P(this,B).origin:P(this,z).origin,lastEventId:e.id||``});P(this,Y)&&(!e.event||e.event===`message`)&&P(this,Y).call(this,t),this.dispatchEvent(t)}),F(this,Ce,e=>{I(this,U,e)}),F(this,Te,()=>{I(this,W,void 0),P(this,R)===this.CONNECTING&&L(this,Z,ve).call(this)});try{if(e instanceof URL)I(this,z,e);else if(typeof e==`string`)I(this,z,new URL(e,Ee()));else throw Error(`Invalid URL`)}catch{throw he(`An invalid or illegal string was specified`)}I(this,q,g({onEvent:P(this,Se),onRetry:P(this,Ce)})),I(this,R,this.CONNECTING),I(this,U,3e3),I(this,H,t?.fetch??globalThis.fetch),I(this,V,t?.withCredentials??!1),L(this,Z,ve).call(this)}get readyState(){return P(this,R)}get url(){return P(this,z).href}get withCredentials(){return P(this,V)}get onerror(){return P(this,J)}set onerror(e){I(this,J,e)}get onmessage(){return P(this,Y)}set onmessage(e){I(this,Y,e)}get onopen(){return P(this,X)}set onopen(e){I(this,X,e)}addEventListener(e,t,n){let r=t;super.addEventListener(e,r,n)}removeEventListener(e,t,n){let r=t;super.removeEventListener(e,r,n)}close(){P(this,W)&&clearTimeout(P(this,W)),P(this,R)!==this.CLOSED&&(P(this,K)&&P(this,K).abort(),I(this,R,this.CLOSED),I(this,K,void 0))}};R=new WeakMap,z=new WeakMap,B=new WeakMap,V=new WeakMap,H=new WeakMap,U=new WeakMap,W=new WeakMap,G=new WeakMap,K=new WeakMap,q=new WeakMap,J=new WeakMap,Y=new WeakMap,X=new WeakMap,Z=new WeakSet,ve=function(){I(this,R,this.CONNECTING),I(this,K,new AbortController),P(this,H)(P(this,z),L(this,Z,xe).call(this)).then(P(this,ye)).catch(P(this,be))},ye=new WeakMap,be=new WeakMap,xe=function(){let e={mode:`cors`,redirect:`follow`,headers:{Accept:`text/event-stream`,...P(this,G)?{"Last-Event-ID":P(this,G)}:void 0},cache:`no-store`,signal:P(this,K)?.signal};return`window`in globalThis&&(e.credentials=this.withCredentials?`include`:`same-origin`),e},Se=new WeakMap,Ce=new WeakMap,Q=function(e,t){var n;P(this,R)!==this.CLOSED&&I(this,R,this.CLOSED);let r=new me(`error`,{code:t,message:e});(n=P(this,J))==null||n.call(this,r),this.dispatchEvent(r)},we=function(e,t){var n;if(P(this,R)===this.CLOSED)return;I(this,R,this.CONNECTING);let r=new me(`error`,{code:t,message:e});(n=P(this,J))==null||n.call(this,r),this.dispatchEvent(r),I(this,W,setTimeout(P(this,Te),P(this,U)))},Te=new WeakMap,$.CONNECTING=0,$.OPEN=1,$.CLOSED=2;function Ee(){let e=`document`in globalThis?globalThis.document:void 0;return e&&typeof e==`object`&&`baseURI`in e&&typeof e.baseURI==`string`?e.baseURI:void 0}var De=class{client;enabled;lastBlockReason;serverName;constructor(e){this.enabled=e.enabled,this.client=e.client,this.serverName=e.serverName,x.info(`AccessControlAuthorizer initialized`,{enabled:this.enabled,hasClient:!!this.client,serverName:this.serverName})}getBlockReason(){return this.lastBlockReason?this.lastBlockReason:`MCP server${this.serverName?` '${this.serverName}'`:``} is not authorized for use in your organization and has been blocked by Onyx.`}async isAllowed(){if(!this.enabled)return!0;if(this.client)try{let e=await this.client.authorize();return e.action===`block`?(e.reason?this.lastBlockReason=e.reason:this.lastBlockReason=`MCP server${this.serverName?` '${this.serverName}'`:``} is not authorized for use in your organization and has been blocked by Onyx.`,!1):!0}catch(e){return x.error(`Access control authorization failed with unexpected error`,{error:String(e)}),!0}return x.warn(`No access control client configured, allowing by default`),!0}},Oe=class{clientInfoBase64;config;constructor(e){this.config=e,this.clientInfoBase64=this.getClientInfoBase64(),x.info(`AccessControlClient initialized`,{timeoutMs:e.timeoutMs,url:e.url})}async authorize(){try{let e=await this.sendAuthorizeRequest();return x.debug(`Access control check successful`,{action:e.action}),e}catch(e){return x.warn(`Access control check failed, failing open (allowing by default)`,{error:String(e)}),{action:`allow`}}}getClientInfoBase64(){return s(this.config.sessionData)}async sendAuthorizeRequest(){let e=new AbortController,t=setTimeout(()=>e.abort(),this.config.timeoutMs);try{let t=`${this.config.url}/${this.config.apiKey}/mcp/${this.clientInfoBase64}`,n=await fetch(t,{headers:{...this.config.headers},method:`POST`,signal:e.signal});if(!n.ok)throw Error(`Access control service returned ${n.status}: ${n.statusText}`);let r=await n.json();if(!r.action||![`allow`,`block`].includes(r.action))throw Error(`Invalid access control response format: action="${r.action}"`);return r}catch(e){throw e instanceof Error&&e.name===`AbortError`?Error(`Access control check timed out after ${this.config.timeoutMs}ms`):e}finally{clearTimeout(t)}}},ke=class{storageDir;constructor(e){this.storageDir=e.storageDir}async delete(e){let t=_(e),n=this.getFilePath(t);try{await O(n),x.debug(`Deleted stored credentials`,{filePath:n,serverUrl:t})}catch(e){e.code!==`ENOENT`&&x.warn(`Failed to delete stored credentials`,{error:String(e),filePath:n,serverUrl:t})}}hasRefreshToken(e){return!!e.tokens?.refresh_token}hasValidAccessToken(e){return!!e.tokens?.access_token&&!this.isAccessTokenExpired(e)}isAccessTokenExpired(e){if(!e.tokens||!e.tokensObtainedAt)return!0;let{expires_in:t}=e.tokens;if(!t)return!1;let n=new Date(e.tokensObtainedAt).getTime()+t*1e3,r=Date.now(),i=r>=n-3e4;return x.debug(`Checked access token expiration`,{expiresAt:new Date(n).toISOString(),expiresIn:t,isExpired:i,now:new Date(r).toISOString(),obtainedAt:e.tokensObtainedAt}),i}async load(e){let t=_(e),n=this.getFilePath(t);try{let e=await D(n,`utf-8`),r=JSON.parse(e);if(_(r.serverUrl)!==t){x.warn(`Credential file server URL mismatch`,{expected:t,filePath:n,found:r.serverUrl});return}return x.debug(`Loaded stored credentials`,{clientId:r.clientInfo?.client_id,hasRefreshToken:!!r.tokens?.refresh_token,hasTokens:!!r.tokens,serverUrl:t}),r}catch(e){if(e.code===`ENOENT`){x.debug(`No stored credentials found`,{serverUrl:t});return}x.warn(`Failed to load stored credentials`,{error:String(e),filePath:n,serverUrl:t});return}}async save(e){await this.ensureStorageDir();let t=this.getFilePath(e.serverUrl),n=JSON.stringify(e,null,2);try{await ce(t,n,{encoding:`utf-8`,mode:384}),await T(t,384),x.debug(`Saved credentials to disk`,{clientId:e.clientInfo?.client_id,filePath:t,hasTokens:!!e.tokens,serverUrl:e.serverUrl})}catch(n){throw x.error(`Failed to save credentials`,{error:String(n),filePath:t,serverUrl:e.serverUrl}),n}}async update(e,t){let n=_(e),r=await this.load(n),i=new Date().toISOString(),a=r?{...r,...t,serverUrl:n,updatedAt:i}:{createdAt:i,serverUrl:n,updatedAt:i,...t};return await this.save(a),a}async ensureStorageDir(){try{await E(this.storageDir,{mode:448,recursive:!0})}catch(e){if(e.code!==`EEXIST`)throw e}try{await y(this.storageDir)}catch(e){x.warn(`Failed to fix OAuth storage directory ownership`,{error:String(e),storageDir:this.storageDir})}}generateKey(e){return w(`sha256`).update(e).digest(`hex`).substring(0,16)}getFilePath(e){let t=this.generateKey(e);return C(this.storageDir,`${t}.json`)}};function Ae(e,t=(...e)=>globalThis.fetch(...e)){return async(n,r)=>{let i=new Headers(r?.headers).has(`Authorization`),a=e=>{let t=new Headers(r?.headers);return e?t.set(`Authorization`,`Bearer ${e}`):i||t.delete(`Authorization`),{...r,headers:t}},o=e.getCurrentBearer(),s=await t(n,a(o));if(s.status===401&&o){x.info(`Upstream returned 401; attempting mid-session silent refresh`,{eventType:`mcp_auth_mid_session_refresh_attempt`});let r=await e.refreshIfPossible(o);r&&r!==o?(x.info(`Silent refresh succeeded mid-session; retrying request`,{eventType:`mcp_auth_mid_session_refresh_succeeded`}),s=await t(n,a(r))):x.warn(`Silent refresh produced no new bearer; passing 401 through`,{eventType:`mcp_auth_mid_session_refresh_failed`})}return s}}function je(e,t,n){let r=n,i=null;return{getCurrentBearer:()=>r,refreshIfPossible:n=>i||(i=(async()=>{try{let i=(await t.load(e))?.tokens?.access_token;if(i&&i!==n)return x.info(`Adopting newer access_token from disk (other process refreshed)`,{eventType:`mcp_auth_disk_bearer_adopted`,serverUrl:e}),r=i,i;let a=await S(e,t);return a?.tokens.access_token?(r=a.tokens.access_token,r):void 0}finally{i=null}})(),i),setBearer:e=>{r=e}}}var Me=class extends pe{buffer=``;droppedLinesLogged=0;constructor(){super({objectMode:!1})}_flush(e){this.buffer.trim().startsWith(`{`)?e(null,Buffer.from(this.buffer)):(this.buffer.trim().length>0&&this.logDroppedLine(this.buffer),e(null,null))}_transform(e,t,n){this.buffer+=e.toString();let r=this.buffer.split(`
1
+ import{AccessControlBlockError as e,Client as t,ConfigurationError as n,ProxyConnectionError as r,ReadBuffer as i,Server as a,StdioServerTransport as o,compressClientInfo as s,getSessionData as c,initializeTrafficMirror as l,logRequestCounts as u,proxyServer as d,redactCliArgs as f,serializeMessage as p,startHTTPServer as m}from"./stdio-CTyEB1eY.js";import{UnauthorizedError as h,createParser as g,normalizeUrl as _}from"./normalizeUrl-fkFv5Mfb.js";import{config as v}from"./env-BbWkec7w.js";import{chownToRealUser as y,extractTraceIdFromHeaders as ee,flushLogs as b,logger as x}from"./logger-fOoIHE0y.js";import{emitKeychainOutcomeLog as te,emitProxySetupLog as ne,hideBin as re,yargs_default as ie}from"./helpers-DpRe9vc7.js";import"./providers-BdLw9eT-.js";import{initializeOAuthProviders as ae}from"./oauthProvidersClient-L4dF01G3.js";import"./pkce-DKfQXsGm.js";import{connectWithTransportFallback as oe,performOAuthFlow as se,tryRefreshCachedToken as S}from"./transportDetection-SviNyBzg.js";import{join as C}from"node:path";import{createHash as w}from"node:crypto";import{chmod as T,mkdir as E,readFile as D,rm as O,writeFile as ce}from"node:fs/promises";import{StringDecoder as le}from"node:string_decoder";import{setTimeout as ue}from"node:timers";import de from"node:util";import{execSync as k,spawn as A,spawnSync as j}from"node:child_process";import{PassThrough as fe,Transform as pe}from"node:stream";var me=class extends Event{constructor(e,t){super(e),this.code=t?.code??void 0,this.message=t?.message??void 0}[Symbol.for(`nodejs.util.inspect.custom`)](e,t,n){return n(ge(this),t)}[Symbol.for(`Deno.customInspect`)](e,t){return e(ge(this),t)}};function he(e){let t=globalThis.DOMException;return typeof t==`function`?new t(e,`SyntaxError`):SyntaxError(e)}function M(e){return e instanceof Error?`errors`in e&&Array.isArray(e.errors)?e.errors.map(M).join(`, `):`cause`in e&&e.cause instanceof Error?`${e}: ${M(e.cause)}`:e.message:`${e}`}function ge(e){return{type:e.type,message:e.message,code:e.code,defaultPrevented:e.defaultPrevented,cancelable:e.cancelable,timeStamp:e.timeStamp}}var _e=e=>{throw TypeError(e)},N=(e,t,n)=>t.has(e)||_e(`Cannot `+n),P=(e,t,n)=>(N(e,t,`read from private field`),n?n.call(e):t.get(e)),F=(e,t,n)=>t.has(e)?_e(`Cannot add the same private member more than once`):t instanceof WeakSet?t.add(e):t.set(e,n),I=(e,t,n,r)=>(N(e,t,`write to private field`),t.set(e,n),n),L=(e,t,n)=>(N(e,t,`access private method`),n),R,z,B,V,H,U,W,G,K,q,J,Y,X,Z,ve,ye,be,xe,Se,Ce,Q,we,Te,$=class extends EventTarget{constructor(e,t){super(),F(this,Z),this.CONNECTING=0,this.OPEN=1,this.CLOSED=2,F(this,R),F(this,z),F(this,B),F(this,V),F(this,H),F(this,U),F(this,W),F(this,G,null),F(this,K),F(this,q),F(this,J,null),F(this,Y,null),F(this,X,null),F(this,ye,async e=>{var t;P(this,q).reset();let{body:n,redirected:r,status:i,headers:a}=e;if(i===204){L(this,Z,Q).call(this,`Server sent HTTP 204, not reconnecting`,204),this.close();return}if(r?I(this,B,new URL(e.url)):I(this,B,void 0),i!==200){L(this,Z,Q).call(this,`Non-200 status code (${i})`,i);return}if(!(a.get(`content-type`)||``).startsWith(`text/event-stream`)){L(this,Z,Q).call(this,`Invalid content type, expected "text/event-stream"`,i);return}if(P(this,R)===this.CLOSED)return;I(this,R,this.OPEN);let o=new Event(`open`);if((t=P(this,X))==null||t.call(this,o),this.dispatchEvent(o),typeof n!=`object`||!n||!(`getReader`in n)){L(this,Z,Q).call(this,`Invalid response body, expected a web ReadableStream`,i),this.close();return}let s=new TextDecoder,c=n.getReader(),l=!0;do{let{done:e,value:t}=await c.read();t&&P(this,q).feed(s.decode(t,{stream:!e})),e&&(l=!1,P(this,q).reset(),L(this,Z,we).call(this))}while(l)}),F(this,be,e=>{I(this,K,void 0),!(e.name===`AbortError`||e.type===`aborted`)&&L(this,Z,we).call(this,M(e))}),F(this,Se,e=>{typeof e.id==`string`&&I(this,G,e.id);let t=new MessageEvent(e.event||`message`,{data:e.data,origin:P(this,B)?P(this,B).origin:P(this,z).origin,lastEventId:e.id||``});P(this,Y)&&(!e.event||e.event===`message`)&&P(this,Y).call(this,t),this.dispatchEvent(t)}),F(this,Ce,e=>{I(this,U,e)}),F(this,Te,()=>{I(this,W,void 0),P(this,R)===this.CONNECTING&&L(this,Z,ve).call(this)});try{if(e instanceof URL)I(this,z,e);else if(typeof e==`string`)I(this,z,new URL(e,Ee()));else throw Error(`Invalid URL`)}catch{throw he(`An invalid or illegal string was specified`)}I(this,q,g({onEvent:P(this,Se),onRetry:P(this,Ce)})),I(this,R,this.CONNECTING),I(this,U,3e3),I(this,H,t?.fetch??globalThis.fetch),I(this,V,t?.withCredentials??!1),L(this,Z,ve).call(this)}get readyState(){return P(this,R)}get url(){return P(this,z).href}get withCredentials(){return P(this,V)}get onerror(){return P(this,J)}set onerror(e){I(this,J,e)}get onmessage(){return P(this,Y)}set onmessage(e){I(this,Y,e)}get onopen(){return P(this,X)}set onopen(e){I(this,X,e)}addEventListener(e,t,n){let r=t;super.addEventListener(e,r,n)}removeEventListener(e,t,n){let r=t;super.removeEventListener(e,r,n)}close(){P(this,W)&&clearTimeout(P(this,W)),P(this,R)!==this.CLOSED&&(P(this,K)&&P(this,K).abort(),I(this,R,this.CLOSED),I(this,K,void 0))}};R=new WeakMap,z=new WeakMap,B=new WeakMap,V=new WeakMap,H=new WeakMap,U=new WeakMap,W=new WeakMap,G=new WeakMap,K=new WeakMap,q=new WeakMap,J=new WeakMap,Y=new WeakMap,X=new WeakMap,Z=new WeakSet,ve=function(){I(this,R,this.CONNECTING),I(this,K,new AbortController),P(this,H)(P(this,z),L(this,Z,xe).call(this)).then(P(this,ye)).catch(P(this,be))},ye=new WeakMap,be=new WeakMap,xe=function(){let e={mode:`cors`,redirect:`follow`,headers:{Accept:`text/event-stream`,...P(this,G)?{"Last-Event-ID":P(this,G)}:void 0},cache:`no-store`,signal:P(this,K)?.signal};return`window`in globalThis&&(e.credentials=this.withCredentials?`include`:`same-origin`),e},Se=new WeakMap,Ce=new WeakMap,Q=function(e,t){var n;P(this,R)!==this.CLOSED&&I(this,R,this.CLOSED);let r=new me(`error`,{code:t,message:e});(n=P(this,J))==null||n.call(this,r),this.dispatchEvent(r)},we=function(e,t){var n;if(P(this,R)===this.CLOSED)return;I(this,R,this.CONNECTING);let r=new me(`error`,{code:t,message:e});(n=P(this,J))==null||n.call(this,r),this.dispatchEvent(r),I(this,W,setTimeout(P(this,Te),P(this,U)))},Te=new WeakMap,$.CONNECTING=0,$.OPEN=1,$.CLOSED=2;function Ee(){let e=`document`in globalThis?globalThis.document:void 0;return e&&typeof e==`object`&&`baseURI`in e&&typeof e.baseURI==`string`?e.baseURI:void 0}var De=class{client;enabled;lastBlockReason;serverName;constructor(e){this.enabled=e.enabled,this.client=e.client,this.serverName=e.serverName,x.info(`AccessControlAuthorizer initialized`,{enabled:this.enabled,hasClient:!!this.client,serverName:this.serverName})}getBlockReason(){return this.lastBlockReason?this.lastBlockReason:`MCP server${this.serverName?` '${this.serverName}'`:``} is not authorized for use in your organization and has been blocked by Onyx.`}async isAllowed(){if(!this.enabled)return!0;if(this.client)try{let e=await this.client.authorize();return e.action===`block`?(e.reason?this.lastBlockReason=e.reason:this.lastBlockReason=`MCP server${this.serverName?` '${this.serverName}'`:``} is not authorized for use in your organization and has been blocked by Onyx.`,!1):!0}catch(e){return x.error(`Access control authorization failed with unexpected error`,{error:String(e)}),!0}return x.warn(`No access control client configured, allowing by default`),!0}},Oe=class{clientInfoBase64;config;constructor(e){this.config=e,this.clientInfoBase64=this.getClientInfoBase64(),x.info(`AccessControlClient initialized`,{timeoutMs:e.timeoutMs,url:e.url})}async authorize(){try{let e=await this.sendAuthorizeRequest();return x.debug(`Access control check successful`,{action:e.action}),e}catch(e){return x.warn(`Access control check failed, failing open (allowing by default)`,{error:String(e)}),{action:`allow`}}}getClientInfoBase64(){return s(this.config.sessionData)}async sendAuthorizeRequest(){let e=new AbortController,t=setTimeout(()=>e.abort(),this.config.timeoutMs);try{let t=`${this.config.url}/${this.config.apiKey}/mcp/${this.clientInfoBase64}`,n=await fetch(t,{headers:{...this.config.headers},method:`POST`,signal:e.signal});if(!n.ok)throw Error(`Access control service returned ${n.status}: ${n.statusText}`);let r=await n.json();if(!r.action||![`allow`,`block`].includes(r.action))throw Error(`Invalid access control response format: action="${r.action}"`);return r}catch(e){throw e instanceof Error&&e.name===`AbortError`?Error(`Access control check timed out after ${this.config.timeoutMs}ms`):e}finally{clearTimeout(t)}}},ke=class{storageDir;constructor(e){this.storageDir=e.storageDir}async delete(e){let t=_(e),n=this.getFilePath(t);try{await O(n),x.debug(`Deleted stored credentials`,{filePath:n,serverUrl:t})}catch(e){e.code!==`ENOENT`&&x.warn(`Failed to delete stored credentials`,{error:String(e),filePath:n,serverUrl:t})}}hasRefreshToken(e){return!!e.tokens?.refresh_token}hasValidAccessToken(e){return!!e.tokens?.access_token&&!this.isAccessTokenExpired(e)}isAccessTokenExpired(e){if(!e.tokens||!e.tokensObtainedAt)return!0;let{expires_in:t}=e.tokens;if(!t)return!1;let n=new Date(e.tokensObtainedAt).getTime()+t*1e3,r=Date.now(),i=r>=n-3e4;return x.debug(`Checked access token expiration`,{expiresAt:new Date(n).toISOString(),expiresIn:t,isExpired:i,now:new Date(r).toISOString(),obtainedAt:e.tokensObtainedAt}),i}async load(e){let t=_(e),n=this.getFilePath(t);try{let e=await D(n,`utf-8`),r=JSON.parse(e);if(_(r.serverUrl)!==t){x.warn(`Credential file server URL mismatch`,{expected:t,filePath:n,found:r.serverUrl});return}return x.debug(`Loaded stored credentials`,{clientId:r.clientInfo?.client_id,hasRefreshToken:!!r.tokens?.refresh_token,hasTokens:!!r.tokens,serverUrl:t}),r}catch(e){if(e.code===`ENOENT`){x.debug(`No stored credentials found`,{serverUrl:t});return}x.warn(`Failed to load stored credentials`,{error:String(e),filePath:n,serverUrl:t});return}}async save(e){await this.ensureStorageDir();let t=this.getFilePath(e.serverUrl),n=JSON.stringify(e,null,2);try{await ce(t,n,{encoding:`utf-8`,mode:384}),await T(t,384),x.debug(`Saved credentials to disk`,{clientId:e.clientInfo?.client_id,filePath:t,hasTokens:!!e.tokens,serverUrl:e.serverUrl})}catch(n){throw x.error(`Failed to save credentials`,{error:String(n),filePath:t,serverUrl:e.serverUrl}),n}}async update(e,t){let n=_(e),r=await this.load(n),i=new Date().toISOString(),a=r?{...r,...t,serverUrl:n,updatedAt:i}:{createdAt:i,serverUrl:n,updatedAt:i,...t};return await this.save(a),a}async ensureStorageDir(){try{await E(this.storageDir,{mode:448,recursive:!0})}catch(e){if(e.code!==`EEXIST`)throw e}try{await y(this.storageDir)}catch(e){x.warn(`Failed to fix OAuth storage directory ownership`,{error:String(e),storageDir:this.storageDir})}}generateKey(e){return w(`sha256`).update(e).digest(`hex`).substring(0,16)}getFilePath(e){let t=this.generateKey(e);return C(this.storageDir,`${t}.json`)}};function Ae(e,t=(...e)=>globalThis.fetch(...e)){return async(n,r)=>{let i=new Headers(r?.headers).has(`Authorization`),a=e=>{let t=new Headers(r?.headers);return e?t.set(`Authorization`,`Bearer ${e}`):i||t.delete(`Authorization`),{...r,headers:t}},o=e.getCurrentBearer(),s=await t(n,a(o));if(s.status===401&&o){x.info(`Upstream returned 401; attempting mid-session silent refresh`,{eventType:`mcp_auth_mid_session_refresh_attempt`});let r=await e.refreshIfPossible(o);r&&r!==o?(x.info(`Silent refresh succeeded mid-session; retrying request`,{eventType:`mcp_auth_mid_session_refresh_succeeded`}),s=await t(n,a(r))):x.warn(`Silent refresh produced no new bearer; passing 401 through`,{eventType:`mcp_auth_mid_session_refresh_failed`})}return s}}function je(e,t,n){let r=n,i=null;return{getCurrentBearer:()=>r,refreshIfPossible:n=>i||(i=(async()=>{try{let i=(await t.load(e))?.tokens?.access_token;if(i&&i!==n)return x.info(`Adopting newer access_token from disk (other process refreshed)`,{eventType:`mcp_auth_disk_bearer_adopted`,serverUrl:e}),r=i,i;let a=await S(e,t);return a?.tokens.access_token?(r=a.tokens.access_token,r):void 0}finally{i=null}})(),i),setBearer:e=>{r=e}}}var Me=class extends pe{buffer=``;droppedLinesLogged=0;constructor(){super({objectMode:!1})}_flush(e){this.buffer.trim().startsWith(`{`)?e(null,Buffer.from(this.buffer)):(this.buffer.trim().length>0&&this.logDroppedLine(this.buffer),e(null,null))}_transform(e,t,n){this.buffer+=e.toString();let r=this.buffer.split(`
2
2
  `);this.buffer=r.pop()||``;let i=[];for(let e of r)e.trim().startsWith(`{`)?i.push(e):e.trim().length>0&&this.logDroppedLine(e);if(i.length>0){let e=`${i.join(`
3
3
  `)}\n`;n(null,Buffer.from(e))}else n(null,null)}logDroppedLine(e){if(!(this.droppedLinesLogged>50)){if(this.droppedLinesLogged===50){this.droppedLinesLogged+=1,x.info(`Suppressing further non-JSON stdout lines`,{eventType:`mcp_server_stdout_dropped_suppressed`,loggedSoFar:50});return}this.droppedLinesLogged+=1,x.info(`MCP server stdout (non-JSON, dropped)`,{eventType:`mcp_server_stdout_dropped`,line:e.length>1024?`${e.slice(0,1024)}…`:e})}}},Ne=class{onclose;onerror;onmessage;get pid(){return this._process?.pid??null}get stderr(){return this._stderrStream?this._stderrStream:this._process?.stderr??null}_abortController=new AbortController;_process;_readBuffer=new i;_serverParams;_stderrStream=null;onEvent;constructor(e){this._serverParams=e,(e.stderr===`pipe`||e.stderr===`overlapped`)&&(this._stderrStream=new fe),this.onEvent=e.onEvent}async close(){if(this.onEvent?.({type:`close`}),this._process?.pid)try{if(process.platform===`win32`){let e=j(`taskkill`,[`/PID`,String(this._process.pid),`/T`,`/F`],{stdio:`ignore`});if(e.error)throw e.error;if(e.status!==0)throw Error(`taskkill exited with status ${e.status}`)}else process.kill(-this._process.pid,`SIGTERM`)}catch(e){x.debug(`Process tree cleanup failed (process may already be dead)`,{error:e.message,pid:this._process.pid})}this._abortController.abort(),this._process=void 0,this._readBuffer.clear()}send(e){return new Promise(t=>{if(!this._process?.stdin)throw Error(`Not connected`);let n=p(e);this._process.stdin.write(n)?t():this._process.stdin.once(`drain`,t)})}async start(){if(this._process)throw Error(`StdioClientTransport already started! If using Client class, note that connect() calls start() automatically.`);return new Promise((e,t)=>{let n=this._serverParams.shell??!1,r=n&&process.platform===`win32`,i=r?Pe(this._serverParams.command):this._serverParams.command,a=r?(this._serverParams.args??[]).map(Pe):this._serverParams.args??[];this._process=A(i,a,{cwd:this._serverParams.cwd,detached:process.platform!==`win32`,env:this._serverParams.env,shell:n,signal:this._abortController.signal,stdio:[`pipe`,`pipe`,this._serverParams.stderr??`inherit`]}),this._process.on(`error`,e=>{if(e.name===`AbortError`){this.onclose?.();return}x.error(`Process spawn error`,{args:this._serverParams.args?f(this._serverParams.args):void 0,command:this._serverParams.command,cwd:this._serverParams.cwd,error:e.message,errorCode:e.code,errorErrno:e.errno,errorSyscall:e.syscall,operation:`spawn`,shell:this._serverParams.shell,transportType:`stdio`}),t(e),this.onerror?.(e)});let o,s;this._process.on(`spawn`,()=>{o=Date.now(),s=this._process?.pid,x.info(`MCP server process spawned`,{argCount:this._serverParams.args?.length,command:this._serverParams.command,eventType:`mcp_server_process_spawned`,pid:s}),e()}),this._process.on(`close`,(e,t)=>{let n=o===void 0?void 0:Date.now()-o;x[e===0&&t===null?`info`:`warn`](`MCP server process closed`,{argCount:this._serverParams.args?.length,code:e,command:this._serverParams.command,eventType:`mcp_server_process_closed`,pid:s,signal:t,uptimeMs:n}),this.onEvent?.({type:`close`}),this._process=void 0,this.onclose?.()}),this._process.stdin?.on(`error`,e=>{x.error(`Stdin error`,{command:this._serverParams.command,error:e.message,operation:`write`,pid:this._process?.pid,transportType:`stdio`}),this.onEvent?.({error:e,type:`error`}),this.onerror?.(e)});let c=new Me;this._process.stdout?.pipe(c),c.on(`data`,e=>{this.onEvent?.({chunk:e.toString(),type:`data`}),this._readBuffer.append(e),this.processReadBuffer()}),c.on(`error`,e=>{x.error(`JSON filter error`,{command:this._serverParams.command,error:e.message,operation:`parse`,pid:this._process?.pid,transportType:`stdio`}),this.onEvent?.({error:e,type:`error`}),this.onerror?.(e)}),this._stderrStream&&this._process.stderr&&this._process.stderr.pipe(this._stderrStream)})}processReadBuffer(){for(;;)try{let e=this._readBuffer.readMessage();if(e===null)break;this.onEvent?.({message:e,type:`message`}),this.onmessage?.(e)}catch(e){let t=`unknown`;try{let e=this._readBuffer.readMessage();e&&(t=typeof e)}catch{}x.error(`Message processing error`,{command:this._serverParams.command,error:e.message,messageType:t,operation:`process`,pid:this._process?.pid,transportType:`stdio`}),this.onEvent?.({error:e,type:`error`}),this.onerror?.(e)}}};function Pe(e){return e.length===0||!/[\s"&|<>^()]/.test(e)?e:`"${e.replace(/"/g,`""`).replace(/(\\+)$/,`$1$1`)}"`}function Fe(e){let t=e.toLowerCase().split(/[/\\]/).pop()||``;return t===`docker`||t===`docker.exe`?`docker`:t===`podman`||t===`podman.exe`?`podman`:t===`nerdctl`||t===`nerdctl.exe`?`nerdctl`:t===`finch`||t===`finch.exe`?`finch`:`unknown`}function Ie(e){let t=e.indexOf(`run`);if(t===-1)return;let n=e.slice(t+1),r=new Set(`--add-host.--annotation.--arch.--attach.--blkio-weight.--blkio-weight-device.--cap-add.--cap-drop.--cgroup-parent.--cgroupns.--cidfile.--cosign-key.--cpu-period.--cpu-quota.--cpu-rt-period.--cpu-rt-runtime.--cpu-shares.--cpus.--cpuset-cpus.--cpuset-mems.--decryption-key.--device.--device-cgroup-rule.--device-read-bps.--device-read-iops.--device-write-bps.--device-write-iops.--dns.--dns-option.--dns-search.--domainname.--entrypoint.--env.--env-file.--env-host.--expose.--gidmap.--gpus.--group-add.--health-cmd.--health-interval.--health-retries.--health-start-period.--health-timeout.--hostname.--image-volume.--ip.--ip6.--ipc.--isolation.--kernel-memory.--label.--label-file.--link.--link-local-ip.--log-driver.--log-opt.--mac-address.--memory.--memory-reservation.--memory-swap.--memory-swappiness.--mount.--name.--network.--network-alias.--oom-kill-disable.--oom-score-adj.--os.--pid.--pidfile.--pids-limit.--platform.--pod.--privileged.--publish.--publish-all.--pull.--requires.--restart.--rootfs.--runtime.--secret.--security-opt.--shm-size.--stop-signal.--stop-timeout.--storage-opt.--subgidname.--subuidname.--sysctl.--systemd.--timeout.--tmpfs.--tz.--uidmap.--ulimit.--user.--userns.--uts.--variant.--volume.--volume-driver.--volumes-from.--workdir.-a.-c.-e.-h.-l.-m.-p.-P.-u.-v.-w`.split(`.`)),i=0;for(;i<n.length;){let e=n[i];if(e.startsWith(`-`)){if(e.includes(`=`)){i++;continue}if(r.has(e)){i+=2;continue}i++;continue}return e}}function Le(e,t){try{let n=k(`${t===`unknown`?`docker`:t} image inspect --format "{{json .RepoDigests}}" ${JSON.stringify(e)}`,{encoding:`utf-8`,stdio:[`pipe`,`pipe`,`pipe`],timeout:5e3}).trim(),r;try{r=JSON.parse(n)}catch{return x.debug(`Could not parse RepoDigests JSON`,{imageName:e,result:n,runtime:t}),[]}let i=[];for(let e of r){let t=e.match(/sha256:[a-f0-9]{64}/i);t?i.push(t[0]):/^sha256:[a-f0-9]{64}$/i.test(e)&&i.push(e)}return i.length>0?(x.debug(`Container image digests retrieved`,{digests:i,imageName:e,runtime:t}),i):(x.debug(`No digests available for image (may be locally built)`,{imageName:e,runtime:t}),[])}catch(n){return x.debug(`Could not get container image digests`,{error:n instanceof Error?n.message:String(n),imageName:e,runtime:t}),[]}}function Re(e,t){let n=Fe(e);if(n===`unknown`)return{imageDigests:[],imageName:``,isContainerMCP:!1,runtime:`unknown`};if(!t||!t.includes(`run`))return{imageDigests:[],imageName:``,isContainerMCP:!1,runtime:n};let r=Ie(t);return r?{imageDigests:Le(r,n),imageName:r,isContainerMCP:!0,runtime:n}:(x.debug(`Container command detected but could not extract image name`,{args:t,command:e,runtime:n}),{imageDigests:[],imageName:``,isContainerMCP:!0,runtime:n})}de.inspect.defaultOptions.depth=8,`EventSource`in global||(global.EventSource=$);const ze=async()=>{ne(x),te(x);let i=await ie(re(process.argv)).scriptName(`mcp-gateway`).command(`stdio [command] [args...]`,`Run a local command with stdio transport (default)`,e=>e.positional(`command`,{describe:`The command to run`,type:`string`}).positional(`args`,{array:!0,describe:`The arguments to pass to the command`,type:`string`})).command(`remote`,`Connect to a remote MCP server`,e=>e.options({"bearer-token-env":{describe:`Environment variable name containing a bearer token for remote authentication`,type:`string`},"env-http-headers":{describe:`HTTP headers resolved from environment variables (format: HeaderName:ENV_VAR_NAME)`,string:!0,type:`array`},headers:{deprecated:`Use --env-http-headers with env var names instead. --headers exposes values in process listings.`,describe:`Legacy: headers with literal values (format: key:value)`,string:!0,type:`array`},"remote-transport":{choices:[`sse`,`stream`],deprecated:`Transport is now auto-detected per MCP spec. This option is ignored.`,describe:`(Deprecated) The transport type - now auto-detected`,type:`string`},url:{demandOption:!0,describe:`The URL of the remote MCP server`,type:`string`}})).command(`$0 [command] [args...]`,`Run a command with MCP arguments (backward compatible)`,e=>e.positional(`command`,{describe:`The command to run`,type:`string`}).positional(`args`,{array:!0,describe:`The arguments to pass to the command`,type:`string`})).env(`MCP_GATEWAY`).parserConfiguration({"populate--":!0,"unknown-options-as-args":!0}).options({"access-control-url":{describe:`URL of the access control service (overrides MCP_GATEWAY_ACCESS_CONTROL_URL)`,type:`string`},debug:{default:!1,describe:`Enable debug logging`,type:`boolean`},env:{describe:`Environment variables to pass to the command (format: KEY=value)`,string:!0,type:`array`},gracefulShutdownTimeout:{default:5e3,describe:`The timeout (in milliseconds) for graceful shutdown`,type:`number`},"oauth-providers-url":{describe:`URL of the OAuth providers config endpoint (overrides MCP_GATEWAY_OAUTH_PROVIDERS_URL)`,type:`string`},port:{describe:`Run as HTTP server on the specified port instead of stdio`,type:`number`},"scanner-api-key":{describe:`API key for scanner authentication (overrides MCP_GATEWAY_SCANNER_API_KEY)`,type:`string`},"scanner-fail-open":{describe:`Allow requests when scanner is unavailable (overrides MCP_GATEWAY_SCANNER_FAIL_OPEN)`,type:`boolean`},"scanner-timeout-ms":{describe:`Scanner request timeout in milliseconds (overrides MCP_GATEWAY_SCANNER_TIMEOUT_MS)`,type:`number`},"scanner-url":{describe:`URL of the scanner/evaluator service (overrides MCP_GATEWAY_SCANNER_URL)`,type:`string`},shell:{default:process.platform===`win32`,describe:`Spawn the server via the user's shell (defaults to true on Windows)`,type:`boolean`}}).help().parseAsync();await ae(v.oauthProviders);let s,p,g,y,S,C={},w={};if(i.env)for(let e of i.env){let[t,...n]=e.split(`=`);t&&n.length>0&&(w[t.trim()]=n.join(`=`).trim())}let T=e=>{if(e.includes("${")){let t,n=e.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g,(e,n)=>process.env[n]||(t=n,``));return t?{missingVar:t,resolved:``}:{resolved:n}}let t=process.env[e];return t?{resolved:t}:{missingVar:e,resolved:``}};if(i.headers)for(let e of i.headers){let[t,...n]=e.split(`:`);t&&n.length>0&&(C[t.trim()]=n.join(`:`).trim())}if(i.bearerTokenEnv){let e=i.bearerTokenEnv,{missingVar:t,resolved:n}=T(e);t&&(x.error(`Bearer token env var specified but not set`,{envVar:t,eventType:`mcp_auth_bearer_env_missing`}),process.exit(1)),C.Authorization=`Bearer ${n}`,x.info(`Bearer token loaded from environment variable`,{authType:`bearer_token`,envVar:e,eventType:`mcp_auth_bearer_env`,remoteUrl:i.url})}if(i.envHttpHeaders)for(let e of i.envHttpHeaders){let[t,...n]=e.split(`:`),r=n.join(`:`).trim();if(t&&r){let e=t.trim(),{missingVar:n,resolved:a}=T(r);n&&(x.error(`Env var for HTTP header not set`,{envVar:n,eventType:`mcp_auth_env_header_missing`,header:e}),process.exit(1)),C[e]=a,x.info(`HTTP header loaded from environment`,{eventType:`mcp_auth_env_header`,header:e,remoteUrl:i.url})}}let E=ee(C);if(E&&x.setTraceId(E),C.Authorization){let e=C.Authorization.startsWith(`Bearer `)?`bearer_token`:C.Authorization.startsWith(`Basic `)?`basic`:`api_key`;x.info(`Authorization header provided`,{authType:e,eventType:`mcp_auth_header_provided`,remoteUrl:i.url})}let D={...v.scanner.headers};if(x.debug(`Initializing traffic scanner`,{failOpen:v.scanner.failOpen,hasApiKey:!!v.scanner.apiKey,scannerEnabled:v.scanner.enabled,scannerUrl:v.scanner.url,timeoutMs:v.scanner.timeoutMs}),i._[0]===`remote`){s=`remote`,i[`remote-transport`]&&x.warn(`The --remote-transport option is deprecated and will be ignored. Transport is now auto-detected per MCP spec (Streamable HTTP with SSE fallback).`,{providedTransport:i[`remote-transport`]});let e=i.url;if(!e)throw new n(`Remote URL is required for remote proxy type`,`url`);y=_(e),y!==e&&x.debug(`Normalized remote URL`,{normalizedUrl:y,originalUrl:e})}else{if(s=`stdio`,i[`--`]&&i[`--`].length>0){let e=i[`--`];p=e[0],g=e.slice(1).map(String)}else p=i.command,g=(i.args||[]).map(String);if(!p)throw new n(`No command specified for stdio proxy`,`command`)}let O;s===`stdio`&&p&&(O=Re(p,g),O.isContainerMCP&&x.info(`Container MCP detected`,{imageDigests:O.imageDigests,imageName:O.imageName,runtime:O.runtime}));let ce;if(v.accessControl.url&&v.scanner.apiKey){let e=await c(),t=s===`stdio`?{...e,proxyType:`stdio`,stdioCliArgs:{args:f(g),command:p,dockerImageDigests:O?.imageDigests,dockerImageName:O?.imageName,proxyType:`stdio`}}:{...e,proxyType:`remote`,remoteCliArgs:{proxyType:`remote`,url:y}};ce=new Oe({apiKey:v.scanner.apiKey,headers:v.accessControl.headers,sessionData:t,timeoutMs:v.accessControl.timeoutMs,url:v.accessControl.url})}let de=s===`remote`?y:p,k=new De({client:ce,enabled:v.accessControl.enabled,serverName:de}),A=new ke({storageDir:v.oauthDir}),j=()=>new t({name:`mcp-gateway`,version:v.appVersion},{capabilities:{}}),fe=async t=>{if(!await k.isAllowed()){let t=k.getBlockReason();throw x.warn(`MCP server blocked by access control`,{proxyType:s,reason:t}),new e(t,`policy_block`)}if(x.info(`MCP server allowed by access control`),s===`stdio`){let e={...process.env,...w},n=new Ne({args:g,command:p,env:e,onEvent:e=>{i.debug&&x.debug(`Transport event`,{event:e})},shell:i.shell,stderr:`pipe`}),a=1024;a*8;let o=e=>e.length>a?`${e.slice(0,a)}…`:e,c=``,l=[],u=e=>{let t=o(e);l.push(t),l.length>100&&l.shift(),x.info(`MCP server stderr`,{command:p,eventType:`mcp_server_stderr`,line:t})},d=()=>{c.length!==0&&(u(c),c=``)},f=new le(`utf8`),m=!1,h=()=>{if(m)return;m=!0;let e=f.end();e&&(c+=e),d()};n.stderr?.on(`data`,e=>{process.stderr.write(e),c+=f.write(e);let t=c.split(`
4
4
  `);c=t.pop()??``;for(let e of t){if(e.length===0)continue;u(e)}c.length>8192&&d()}),n.stderr?.once(`end`,h),n.stderr?.once(`close`,h);try{return await t.connect(n),t}catch(e){throw h(),x.warn(`Failed original server access`,{command:p,error:e instanceof Error?e.message:String(e),eventType:`mcp_server_access_failed`,proxyType:s,stderrTail:l.slice(-20)}),new r(`Failed to connect to stdio process: ${e}`,void 0,`stdio`,{argCount:g?.length,command:p})}}else if(s===`remote`){let e=y,t=()=>{let e={...C};return Object.keys(e).length>0?{headers:e}:void 0},n=e=>{if(e instanceof h)return!0;if(e&&typeof e==`object`){let t=e.status,n=e.code,r=e.message;if(t===401||n===401||r&&/unauthorized|401/i.test(String(r)))return!0}return!1},i=async()=>{let t=await se(e,{credentialStore:A});return x.info(`Authentication performed`,{authType:`oauth`,eventType:`mcp_auth_performed`,fromCache:t.fromCache,remoteUrl:e}),t.tokens.access_token},a;try{let r=await A.load(e),o=r&&A.hasValidAccessToken(r)?r.tokens?.access_token:void 0,s=je(e,A,o),c=Ae(s),l=!1;try{let n=await oe(j,e,t(),c);a=n.client,S=n.transportType,x.info(`Connected to remote server`,{hasAuth:!!o,transport:S})}catch(r){if(n(r)){if(l)throw r;s.getCurrentBearer()??o?(x.info(`Cached + refresh both rejected; falling back to full OAuth flow`),await A.update(e,{tokensObtainedAt:void 0})):x.info(`Server requires OAuth, starting authentication flow...`);let n=await i();s.setBearer(n),l=!0;let u=await oe(j,e,t(),c);a=u.client,S=u.transportType,x.info(`Connected to remote server with OAuth`,{transport:S})}else throw r}return a}catch(t){throw x.warn(`Failed original server access`,{error:t instanceof Error?t.message:String(t),eventType:`mcp_server_access_failed`,proxyType:s,remoteUrl:e}),t instanceof r?t:new r(`Failed to connect to remote server: ${t instanceof Error?t.message:String(t)}`,e,S,{headerCount:Object.keys(C).length})}}return t},pe=async()=>{if(i.port){let e=s===`stdio`?{args:g,command:p,dockerImageDigests:O?.imageDigests,dockerImageName:O?.imageName,proxyType:s}:{proxyType:s,url:y};await l({cliArgs:e,scanApiKey:v.scanner.apiKey,scanEnabled:v.scanner.enabled,scanFailOpen:v.scanner.failOpen,scanHeaders:D,scanTimeoutMs:v.scanner.timeoutMs,scanUrl:v.scanner.url||``});let t,n=await m({createServer:async()=>{let e=j();t=await fe(e);let n=t.getServerVersion(),r=t.getServerCapabilities(),i=new a(n,{capabilities:r});return d({authorizer:k,client:t,server:i,serverCapabilities:r}),i},onClose:async e=>{t&&await t.close(),await e.close()},port:i.port});return x.info(`MCP gateway started`,{eventType:`mcp_gateway_started`,mode:`http`,port:i.port,proxyType:s}),s===`stdio`?x.info(`MCP server configuration`,{args:f(g??[]).join(` `),command:p,eventType:`mcp_server_config`,proxyType:s}):x.info(`MCP server configuration`,{eventType:`mcp_server_config`,proxyType:s,remoteUrl:y}),{close:()=>n.close()}}let e=j(),t=await fe(e),n=t.getServerVersion(),r=t.getServerCapabilities(),c=new a(n,{capabilities:r});d({authorizer:k,client:t,server:c,serverCapabilities:r});let u=new o,h=s===`stdio`?{args:g,command:p,dockerImageDigests:O?.imageDigests,dockerImageName:O?.imageName,proxyType:s}:{proxyType:s,url:y};return await l({cliArgs:h,scanApiKey:v.scanner.apiKey,scanEnabled:v.scanner.enabled,scanFailOpen:v.scanner.failOpen,scanHeaders:D,scanTimeoutMs:v.scanner.timeoutMs,scanUrl:v.scanner.url||``}),await c.connect(u),x.info(`MCP gateway started`,{eventType:`mcp_gateway_started`,mode:`stdio`,proxyType:s}),x.info(`MCP server configuration`,{capabilities:Object.keys(r||{}),eventType:`mcp_server_config`,proxyType:s,serverName:n?.name,serverVersion:n?.version,...s===`stdio`?{args:f(g??[]).join(` `),command:p}:{remoteUrl:y,transport:S}}),{close:()=>t.close()}},me=({server:e,timeout:t})=>{let n=!1,r=async r=>{if(!n){n=!0,x.info(`MCP gateway stopping`,{eventType:`mcp_gateway_stopping`,signal:r});try{await e.close(),u(),await b(2e3),process.exit(0)}catch(e){let n=`Error during shutdown: ${e}`;x.error(`Error during shutdown`,{error:n,eventType:`mcp_gateway_stopped`,shutdownTimeout:t}),await b(2e3),process.exit(1)}}},i=e=>async()=>{ue(()=>{x.error(`Graceful shutdown timeout exceeded, forcing exit`),process.exit(1)},t).unref(),await r(e)};return process.once(`SIGTERM`,i(`SIGTERM`)),process.once(`SIGINT`,i(`SIGINT`)),process.stdin.once(`end`,i(`stdin-end`)),()=>e.close()};x.info(`MCP gateway starting`,{command:p,eventType:`mcp_gateway_starting`,proxyType:s,transport:s===`remote`?`auto-detect`:`stdio`,url:y});try{let e=await pe();me({server:e,timeout:i.gracefulShutdownTimeout})}catch(t){t instanceof e&&(console.error(`
5
5
  ❌ ACCESS DENIED`),console.error(`━`.repeat(60)),console.error(`
6
6
  This MCP server has been blocked by Onyx because it is not authorized by your organization's access control policy. Please contact your administrator if you believe this is an error.
7
7
  `),x.error(`MCP server blocked by access control policy`,{error:t.message,reason:t.reason}),await b(2e3),process.exit(1));let n=`Could not start the proxy: ${t}`;x.error(`MCP server failed to start`,{args:g?f(g):void 0,command:p,error:n,eventType:`mcp_server_start_failed`,proxyType:s,remoteUrl:y,transport:S}),await b(2e3),process.exit(1)}};export{ze as main};
8
- //# sourceMappingURL=main-C4SI73nG.js.map
8
+ //# sourceMappingURL=main-I7pQoVW3.js.map