@agimon-ai/po-mcp-proxy 0.0.1-alpha.39 → 0.0.1-alpha.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +3 -3
- package/dist/cli.mjs +4 -4
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +33 -1
- package/dist/index.d.mts +33 -1
- package/dist/index.mjs +1 -1
- package/dist/src-BwFgoC11.mjs +72 -0
- package/dist/src-CyntLpz1.cjs +72 -0
- package/package.json +3 -3
- package/dist/src-DFwDK-O4.cjs +0 -72
- package/dist/src-DxYjJ7-h.mjs +0 -72
package/dist/cli.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const e=require("./src-
|
|
2
|
+
const e=require("./src-CyntLpz1.cjs");let t=require("node:fs/promises"),n=require("node:path"),r=require("node:crypto"),i=require("@agimon-ai/foundation-process-registry"),a=require("js-yaml");a=e.mt(a,1);let o=require("@agimon-ai/foundation-port-registry"),s=require("liquidjs"),c=require("commander"),l=require("node:fs");function u(e){return`runtime:${e}`}function d(e){return e instanceof Error?e.message:String(e)}async function f(e){let t=await e.listProcesses({serviceName:`mcp-proxy-http`,liveOnly:!0}),n=/* @__PURE__ */ new Set;for(let e of t){let t=e.metadata?.serverId;typeof t==`string`&&n.add(t)}return n}async function p(e,t){let n=await e.listProcesses({serviceType:`tool`,tags:[`mcp-proxy-stdio-http-bridge`],liveOnly:!0}),r=u(t);return n.filter(e=>e.tags?.includes(r)).length}async function m(t){let n=t.probe??(async(t,n)=>(await e.b(t,n)).ok),r={stopped:[],removedFiles:[],kept:[]},i=await f(t.processRegistry),a=await t.runtimeStateService.listOrphans(i);for(let e of a){let i={serverId:e.serverId,host:e.host,port:e.port,reason:``};if(!await n(e.host,e.port)){i.reason=`unreachable runtime; removed stale state file`,t.dryRun||await t.runtimeStateService.remove(e.serverId),r.removedFiles.push(i);continue}if(e.runtimeLifecycle!==`stdio-http-managed`){i.reason=`manual runtime; left untouched`,r.kept.push(i);continue}let a=await p(t.processRegistry,e.serverId);if(a>0)i.reason=`managed runtime with ${a} live bridge(s); kept`,r.kept.push(i);else{if(i.reason=`orphaned stdio-http-managed runtime (no live bridges); stopped`,!t.dryRun)try{await t.stopServerService.stop({serverId:e.serverId,force:!0}),await t.runtimeStateService.remove(e.serverId).catch(()=>void 0)}catch(e){i.reason=`failed to stop orphaned runtime: ${d(e)}`,r.kept.push(i);continue}r.stopped.push(i)}}return r}function h(e,t){let n=t?`Would stop`:`Stopped`;for(let t of e.stopped)console.log(`${n} orphaned runtime '${t.serverId}' (http://${t.host}:${t.port}) — ${t.reason}`);let r=t?`Would remove`:`Removed`;for(let t of e.removedFiles)console.log(`${r} stale state for '${t.serverId}' (http://${t.host}:${t.port})`);for(let t of e.kept)console.log(`Kept '${t.serverId}' (http://${t.host}:${t.port}) — ${t.reason}`);console.log(`Summary: ${e.stopped.length} stopped, ${e.removedFiles.length} stale file(s), ${e.kept.length} kept.`)}const g=new c.Command(`cleanup`).description(`Reap orphaned/stale mcp-proxy HTTP runtimes and their leftover state files`).option(`-n, --dry-run`,`Report what would be done without stopping or removing anything`,!1).option(`-j, --json`,`Output as JSON`,!1).action(async t=>{try{let n=await m({runtimeStateService:new e.T,processRegistry:new i.ProcessRegistryService(process.env.PROCESS_REGISTRY_PATH),stopServerService:new e.C,dryRun:t.dryRun});if(t.json){console.log(JSON.stringify({dryRun:t.dryRun,...n},null,2));return}h(n,t.dryRun)}catch(e){let n=`Error executing cleanup: ${d(e)}`;t.json?console.log(JSON.stringify({ok:!1,error:n},null,2)):console.error(n),process.exit(1)}});function _(e){return e instanceof Error?e.message:String(e)}async function v(e,t){try{return(await fetch(`http://${e}:${t}/health`,{signal:AbortSignal.timeout(3e3)})).ok}catch{return!1}}async function y(t,n,r,i,a){let o=n.proxy?.host??`localhost`,s=n.proxy?.port,c=`http://${o}:${s}/mcp`;await v(o,s)||(i.json||console.error(`Starting HTTP proxy server in background...`),await e.y({host:o,port:s,config:r,cache:i.useCache!==!1,clearDefinitionsCache:!1,proxyMode:`flat`}));let l=await t.createClientManagerService();try{await l.connectToServer(`proxy`,{name:`proxy`,transport:`http`,config:{url:c}}),i.json||console.error(`✓ Connected to proxy at ${c}`)}catch(e){throw Error(`Failed to connect to proxy server at ${c}: ${_(e)}`)}try{return await a({container:t,configFilePaths:r,config:n,clientManager:l})}finally{await l.disconnectAll()}}async function b(e,t,n,r,i){let a=await e.createClientManagerService();if(await Promise.all(Object.entries(t.mcpServers).map(async([e,t])=>{try{await a.connectToServer(e,t),r.json||console.error(`✓ Connected to ${e}`)}catch(t){r.json||console.error(`✗ Failed to connect to ${e}: ${_(t)}`)}})),a.getAllClients().length===0)throw Error(`No MCP servers connected`);try{return await i({container:e,configFilePaths:n,config:t,clientManager:a})}finally{await a.disconnectAll()}}async function x(t,n){let r=(e,t)=>{t===void 0?console.error(e):console.error(e,t)},i=t.json?{trace:r,debug:r,info:r,warn:r,error:r}:console,a=e.o(i),o=e.R(t.config),s=o.length>0?null:await e.I(),c=s?[s]:o;if(c.length===0)throw Error(`No config file found. Use --config or create mcp-config.yaml`);let l=await a.createConfigFetcherService({configSources:e.z(c),useCache:t.useCache}).fetchConfiguration();return l.proxy?.port?await y(a,l,c,t,n):await b(a,l,c,t,n)}function S(e){return e instanceof Error?e.message:String(e)}const C=new c.Command(`describe-tools`).description(`Describe specific MCP tools`).argument(`<toolNames...>`,`Tool names to describe`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,e.L).option(`-s, --server <name>`,`Filter by server name`).option(`-j, --json`,`Output as JSON`,!1).action(async(e,t)=>{try{await x(t,async({container:n,config:r,clientManager:i})=>{let a=t.server?[i.getClient(t.server)].filter(e=>e!==void 0):i.getAllClients();if(t.server&&a.length===0)throw Error(`Server "${t.server}" not found`);let o=process.env.PROJECT_PATH||process.cwd(),s=r.skills?.paths||[],c=s.length>0?n.createSkillService(o,s):void 0,l=[],u=[],d=[...e],f=await Promise.all(a.map(async e=>{try{return{client:e,tools:await e.listTools(),error:null}}catch(t){return{client:e,tools:[],error:t}}}));for(let{client:n,tools:r,error:i}of f)if(i)t.json||console.error(`Failed to list tools from ${n.serverName}:`,i);else for(let t of e){let e=r.find(e=>e.name===t);if(e){l.push({server:n.serverName,name:e.name,description:e.description,inputSchema:e.inputSchema});let r=d.indexOf(t);r>-1&&d.splice(r,1)}}if(c&&d.length>0){let e=await Promise.all([...d].map(async e=>{let t=e.startsWith(`skill__`)?e.slice(7):e;return{toolName:e,skill:await c.getSkill(t)}}));for(let{toolName:t,skill:n}of e)if(n){u.push({name:n.name,location:n.basePath,instructions:n.content});let e=d.indexOf(t);e>-1&&d.splice(e,1)}}let p=[];if(l.length>0&&p.push(`For MCP tools: Use the use_tool function with toolName and toolArgs based on the inputSchema above.`),u.length>0&&p.push(`For skill, just follow skill's description to continue.`),t.json){let e={};l.length>0&&(e.tools=l),u.length>0&&(e.skills=u),p.length>0&&(e.nextSteps=p),d.length>0&&(e.notFound=d),console.log(JSON.stringify(e,null,2))}else{if(l.length>0){console.log(`
|
|
3
3
|
Found tools:
|
|
4
4
|
`);for(let e of l)console.log(`Server: ${e.server}`),console.log(`Tool: ${e.name}`),console.log(`Description: ${e.description||`No description`}`),console.log(`Input Schema:`),console.log(JSON.stringify(e.inputSchema,null,2)),console.log(``)}if(u.length>0){console.log(`
|
|
5
5
|
Found skills:
|
|
6
6
|
`);for(let e of u)console.log(`Skill: ${e.name}`),console.log(`Location: ${e.location}`),console.log(`Instructions:\n${e.instructions}`),console.log(``)}if(p.length>0){console.log(`
|
|
7
|
-
Next steps:`);for(let e of p)console.log(` • ${e}`);console.log(``)}d.length>0&&console.error(`\nTools/skills not found: ${d.join(`, `)}`),l.length===0&&u.length===0&&(console.error(`No tools or skills found`),process.exit(1))}})}catch(e){console.error(`Error executing describe-tools: ${S(e)}`),process.exit(1)}});function w(e){return e instanceof Error?e.message:String(e)}const ee=new c.Command(`get-prompt`).description(`Get a prompt by name from a connected MCP server`).argument(`<promptName>`,`Prompt name to fetch`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,e.
|
|
7
|
+
Next steps:`);for(let e of p)console.log(` • ${e}`);console.log(``)}d.length>0&&console.error(`\nTools/skills not found: ${d.join(`, `)}`),l.length===0&&u.length===0&&(console.error(`No tools or skills found`),process.exit(1))}})}catch(e){console.error(`Error executing describe-tools: ${S(e)}`),process.exit(1)}});function w(e){return e instanceof Error?e.message:String(e)}const ee=new c.Command(`get-prompt`).description(`Get a prompt by name from a connected MCP server`).argument(`<promptName>`,`Prompt name to fetch`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,e.L).option(`-s, --server <name>`,`Server name (required if prompt exists on multiple servers)`).option(`-a, --args <json>`,`Prompt arguments as JSON string`,`{}`).option(`-j, --json`,`Output as JSON`,!1).action(async(e,t)=>{try{let n={};try{n=JSON.parse(t.args)}catch{throw Error(`Invalid JSON in --args`)}await x(t,async({clientManager:r})=>{let i=r.getAllClients();if(t.server){let i=r.getClient(t.server);if(!i)throw Error(`Server "${t.server}" not found`);let a=await i.getPrompt(e,n);if(t.json)console.log(JSON.stringify(a,null,2));else for(let e of a.messages){let t=e.content;typeof t==`object`&&t&&`text`in t?console.log(t.text):console.log(JSON.stringify(e,null,2))}return}let a=[];if(await Promise.all(i.map(async n=>{try{(await n.listPrompts()).some(t=>t.name===e)&&a.push(n.serverName)}catch(e){t.json||console.error(`Failed to list prompts from ${n.serverName}: ${w(e)}`)}})),a.length===0)throw Error(`Prompt "${e}" not found on any connected server`);if(a.length>1)throw Error(`Prompt "${e}" found on multiple servers: ${a.join(`, `)}. Use --server to disambiguate`);let o=r.getClient(a[0]);if(!o)throw Error(`Internal error: Server "${a[0]}" not connected`);let s=await o.getPrompt(e,n);if(t.json)console.log(JSON.stringify(s,null,2));else for(let e of s.messages){let t=e.content;typeof t==`object`&&t&&`text`in t?console.log(t.text):console.log(JSON.stringify(e,null,2))}})}catch(e){console.error(`Error executing get-prompt: ${w(e)}`),process.exit(1)}});var te=`{
|
|
8
8
|
"_comment": "MCP Server Configuration - Use \${VAR_NAME} syntax for environment variable interpolation",
|
|
9
9
|
"_instructions": "config.instruction: Server's default instruction | instruction: User override (takes precedence)",
|
|
10
10
|
"mcpServers": {
|
|
@@ -138,7 +138,7 @@ mcpServers:
|
|
|
138
138
|
# # omitToolDescription: true
|
|
139
139
|
# # instruction: Optional user override
|
|
140
140
|
{% endif %}
|
|
141
|
-
`;function T(e=``){console.log(e)}function E(e,t){console.error(t?`${e} ${t}`:e)}const D={info:e=>T(e),error:(e,t)=>E(e,t)},O={info:e=>T(e),warning:e=>T(`Warning: ${e}`),error:e=>E(e),success:e=>T(e),newline:()=>T(),header:e=>T(e),item:e=>T(`- ${e}`),indent:e=>T(` ${e}`)},re=new c.Command(`init`).description(`Initialize MCP configuration file`).option(`-o, --output <path>`,`Output file path`,`mcp-config.yaml`).option(`--json`,`Generate JSON config instead of YAML`,!1).option(`-f, --force`,`Overwrite existing config file`,!1).option(`--mcp-servers <json>`,`JSON string of MCP servers to add to config (optional)`).action(async e=>{try{let r=(0,n.resolve)(e.output),i=!e.json&&(r.endsWith(`.yaml`)||r.endsWith(`.yml`)),a;if(i){let t=new s.Liquid,n=null;if(e.mcpServers)try{let t=JSON.parse(e.mcpServers);n=Object.entries(t).map(([e,t])=>({name:e,command:t.command,args:t.args}))}catch(e){D.error(`Failed to parse --mcp-servers JSON:`,e instanceof Error?e.message:String(e)),process.exit(1)}a=await t.parseAndRender(ne,{mcpServers:n})}else a=te;try{await(0,t.writeFile)(r,a,{encoding:`utf-8`,flag:e.force?`w`:`wx`})}catch(e){throw e&&typeof e==`object`&&`code`in e&&e.code===`EEXIST`&&(D.error(`Config file already exists: ${r}`),D.info(`Use --force to overwrite`),process.exit(1)),e}D.info(`MCP configuration file created: ${r}`),D.info(`Next steps:`),D.info(`1. Edit the configuration file to add your MCP servers`),D.info(`2. Run: po-mcp-proxy mcp-serve --config ${r}`)}catch(e){D.error(`Error executing init:`,e instanceof Error?e.message:String(e)),process.exit(1)}});function k(e){return e instanceof Error?e.message:String(e)}const ie=new c.Command(`list-prompts`).description(`List all available prompts from connected MCP servers`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,e.F).option(`-s, --server <name>`,`Filter by server name`).option(`-j, --json`,`Output as JSON`,!1).action(async e=>{try{await x(e,async({clientManager:t})=>{let n=e.server?[t.getClient(e.server)].filter(e=>e!==void 0):t.getAllClients();if(e.server&&n.length===0)throw Error(`Server "${e.server}" not found`);let r={};if(await Promise.all(n.map(async t=>{try{r[t.serverName]=await t.listPrompts()}catch(n){r[t.serverName]=[],e.json||console.error(`Failed to list prompts from ${t.serverName}: ${k(n)}`)}})),e.json)console.log(JSON.stringify(r,null,2));else for(let[e,t]of Object.entries(r))if(console.log(`\n${e}:`),t.length===0)console.log(` No prompts available`);else for(let e of t)if(console.log(` - ${e.name}: ${e.description||`No description`}`),e.arguments&&e.arguments.length>0){let t=e.arguments.map(e=>`${e.name}${e.required?` (required)`:``}`).join(`, `);console.log(` args: ${t}`)}})}catch(e){console.error(`Error executing list-prompts: ${k(e)}`),process.exit(1)}});function A(e){return e instanceof Error?e.message:String(e)}const ae=new c.Command(`list-resources`).description(`List all available resources from connected MCP servers`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,e.F).option(`-s, --server <name>`,`Filter by server name`).option(`-j, --json`,`Output as JSON`,!1).action(async e=>{try{await x(e,async({clientManager:t})=>{let n=e.server?[t.getClient(e.server)].filter(e=>e!==void 0):t.getAllClients();if(e.server&&n.length===0)throw Error(`Server "${e.server}" not found`);let r={},i=await Promise.all(n.map(async e=>{try{let t=await e.listResources();return{serverName:e.serverName,resources:t,error:null}}catch(t){return{serverName:e.serverName,resources:[],error:t}}}));for(let{serverName:t,resources:n,error:a}of i)a&&!e.json&&console.error(`Failed to list resources from ${t}: ${A(a)}`),r[t]=n;if(e.json)console.log(JSON.stringify(r,null,2));else for(let[e,t]of Object.entries(r))if(console.log(`\n${e}:`),t.length===0)console.log(` No resources available`);else for(let e of t){let t=e.name?`${e.name} (${e.uri})`:e.uri;console.log(` - ${t}${e.description?`: ${e.description}`:``}`)}})}catch(e){console.error(`Error executing list-resources: ${A(e)}`),process.exit(1)}});function oe(e){return e instanceof Error?e.message:String(e)}function se(e){for(let t of e.servers)if(console.log(`\n${t.server}:`),t.capabilities&&t.capabilities.length>0&&console.log(` capabilities: ${t.capabilities.join(`, `)}`),t.summary&&console.log(` summary: ${t.summary}`),t.tools.length===0)console.log(` no tools`);else for(let e of t.tools){let t=e.capabilities&&e.capabilities.length>0?` [${e.capabilities.join(`, `)}]`:``;console.log(` - ${e.name}${t}`),e.description&&console.log(` ${e.description}`)}}const ce=new c.Command(`search-tools`).description(`Search proxied MCP tools by capability or server`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,e.F).option(`-s, --server <name>`,`Filter by server name`).option(`--capability <name>`,`Filter by capability tag, summary, tool name, or description`).option(`--definitions-cache <path>`,`Path to definitions cache file`).option(`-j, --json`,`Output as JSON`,!1).action(async t=>{try{await x(t,async({container:n,config:r,clientManager:i,configFilePaths:a})=>{i.registerServerConfigs(r.mcpServers);let o=t.definitionsCache||e.j.getDefaultCachePath(a),s;try{s=await e.j.readFromFile(o)}catch{s=void 0}let c=n.createDefinitionsCacheService(i,void 0,{cacheData:s}),l=(await n.createSearchListToolsTool(i,c).execute({capability:t.capability,serverName:t.server})).content.find(e=>e.type===`text`),u=l?.type===`text`?JSON.parse(l.text):{servers:[]};if(t.json)console.log(JSON.stringify(u,null,2));else{if(!u.servers||u.servers.length===0)throw Error(`No tools matched the requested filters`);se(u)}})}catch(e){console.error(`Error executing search-tools: ${oe(e)}`),process.exit(1)}}),j=[`mcp-config.yaml`,`mcp-config.yml`,`mcp-config.json`],M=`/mcp`,N=`localhost`,P=`stdio`,F=`http`,I=`stdio-http`,L=`mcp-proxy-http`,R=`service`;async function le(){return e.dt()}const z=`mcp-proxy-stdio-http-bridge`,B=`stdio-http-managed`,V=`manual`,H=`MCP_PROXY_IDLE_SHUTDOWN_MINUTES`;async function U(){return le()}function W(e){return e instanceof Error?e.message:String(e)}function ue(e){let t=process.env[H],n=e??(t?Number.parseFloat(t):void 0);return n===void 0||!Number.isFinite(n)||n<=0?0:Math.round(n*6e4)}function G(e){return e===P||e===F||e===I}function de(e){return e===`meta`||e===`flat`||e===`search`||e===`group`}async function K(e){try{return await(0,t.access)(e,l.constants.F_OK),!0}catch{return!1}}async function fe(){try{let e=process.env.PROJECT_PATH;if(e)for(let t of j){let r=(0,n.resolve)(e,t);if(await K(r))return r}let t=process.cwd();for(let e=0;e<=3;e++){for(let e of j){let r=(0,n.join)(t,e);if(await K(r))return r}let e=(0,n.dirname)(t);if(e===t)break;t=e}return null}catch(e){throw Error(`Failed to discover MCP config file: ${W(e)}`)}}async function pe(e){try{let n=await(0,t.readFile)(e,`utf-8`),r=(e.endsWith(`.yaml`)||e.endsWith(`.yml`)?a.load(n):JSON.parse(n))?.proxy;if(!r||typeof r!=`object`)return{};let i=r;return{type:typeof i.type==`string`?i.type:void 0,port:typeof i.port==`number`&&Number.isInteger(i.port)&&i.port>0?i.port:void 0,host:typeof i.host==`string`?i.host:void 0,keepAlive:typeof i.keepAlive==`boolean`?i.keepAlive:void 0}}catch{return{}}}async function me(e){let t={};for(let n of e){let e=await pe(n);e.type!==void 0&&(t.type=e.type),e.port!==void 0&&(t.port=e.port),e.host!==void 0&&(t.host=e.host),e.keepAlive!==void 0&&(t.keepAlive=e.keepAlive)}return t}async function he(t,n){let r=e.o();if(t.id)return t.id;if(n.length>0)try{let i=await r.createConfigFetcherService({configSources:e.L(n),useCache:t.cache!==!1}).fetchConfiguration(t.cache===!1);if(i.id)return i.id}catch(e){throw Error(`Failed to resolve server ID from config '${n.join(`, `)}': ${W(e)}`)}return e.N()}function ge(e){if(!G(e))throw Error(`Unknown transport type: '${e}'. Valid options: ${P}, ${F}, ${I}`);return e}function _e(e){if(!de(e))throw Error(`Unknown proxy mode: '${String(e)}'. Valid options: meta, flat, search, group`)}function ve(e){return e===B?B:V}function q(e,t,n){let r=process.env.MCP_PORT?Number(process.env.MCP_PORT):void 0;return{mode:t,port:e.port??(Number.isFinite(r)?r:void 0)??n?.port,host:e.host??process.env.MCP_HOST??n?.host??N}}function J(){let e=(e,t)=>{t===void 0?console.error(e):console.error(e,t)};return{trace:e,debug:e,info:e,warn:e,error:e}}function ye(e,t,n){return{configFilePath:t.length>0?t:void 0,noCache:e.cache===!1,serverId:n,definitionsCachePath:e.definitionsCache,clearDefinitionsCache:e.clearDefinitionsCache,proxyMode:e.proxyMode}}function be(e,t,n,r){let i=W(r);return e===P?`Failed to start MCP server with transport '${e}': ${i}`:`Failed to start MCP server with transport '${e}' on ${n===void 0?`${t} (dynamic port)`:`${t}:${n}`}: ${i}`}function xe(e,t,n,r,i,a=V){return{serverId:e,host:t.host??N,port:n,transport:`http`,shutdownToken:r,startedAt:(/* @__PURE__ */ new Date()).toISOString(),pid:process.pid,configPath:i,runtimeLifecycle:a}}function Se(){return new o.PortRegistryService(process.env.PORT_REGISTRY_PATH)}function Y(){return process.env.NODE_ENV??`development`}async function Ce(e,t,n,r,i,a,s=n===void 0?o.DEFAULT_PORT_RANGE:{min:n,max:n}){let c=Se(),l=await c.reservePort({repositoryPath:await U(),serviceName:e,serviceType:R,environment:Y(),pid:process.pid,host:t,preferredPort:n,portRange:s,force:!0,metadata:{transport:i,serverId:r,...a?{configPath:a}:{}}});if(!l.success||!l.record){let e=n===void 0?`dynamic port`:`port ${n}`;throw Error(l.error||`Failed to reserve ${e} in port registry`)}let u=!1;return{port:l.record.port,release:async()=>{if(u)return;u=!0;let t=await c.releasePort({repositoryPath:await U(),serviceName:e,serviceType:R,pid:process.pid,environment:Y(),force:!0});if(!t.success&&t.error&&!t.error.includes(`No matching registry entry`))throw Error(t.error||`Failed to release port for ${e}`)}}}async function we(e){e&&await e.release()}function Te(e,t,n,r,i){return{serverId:e,shutdownToken:t,onShutdownRequested:n,runtimeLifecycle:r,idleShutdownMs:i}}async function X(e,t){try{await e.remove(t)}catch(e){throw Error(`Failed to remove runtime state for '${t}': ${W(e)}`)}}async function Ee(e,t){try{await e.write(t)}catch(e){throw Error(`Failed to persist runtime state for '${t.serverId}': ${W(e)}`)}}async function De(e,t,n,r){try{try{await e.stop()}catch(e){throw Error(`Failed to stop owned HTTP transport '${n}': ${W(e)}`)}}finally{await r?.release({kill:!1}),await X(t,n)}}async function Oe(e,t,n){await n?.release({kill:!1}),await X(e,t)}async function ke(e,t,n,r){try{try{await e.stop()}catch(e){throw Error(`Failed to stop HTTP transport during cleanup for '${n}': ${W(e)}`)}}finally{await r?.release({kill:!1}),await X(t,n)}}async function Z(e,t,n={}){try{await e.start()}catch(e){throw Error(`Failed to start transport handler: ${W(e)}`)}let r=!1,i=async n=>{if(!r){r=!0,console.error(`\nReceived ${n}, shutting down gracefully...`);try{await e.stop(),t&&await t(),process.exit(0)}catch(e){console.error(`Failed to gracefully stop transport during ${n}: ${W(e)}`),process.exit(1)}}};process.on(`SIGINT`,async()=>await i(`SIGINT`)),process.on(`SIGTERM`,async()=>await i(`SIGTERM`)),n.shutdownOnStdinClose&&(process.stdin.on(`end`,async()=>await i(`stdin end`)),process.stdin.on(`close`,async()=>await i(`stdin close`)))}async function Ae(t,n,a,s){e.M();let c=a[0],l=await e.l(t),u=new e.T,d=(0,r.randomUUID)(),f=t.serverId??e.N(),p=ve(process.env.MCP_PROXY_RUNTIME_LIFECYCLE),m=n.port,h=m===void 0?o.DEFAULT_PORT_RANGE:{min:m,max:m},g=await Ce(L,n.host??N,m,f,F,c,h),_=g.port,v={...n,port:_},y=await(0,i.createProcessLease)({repositoryPath:await U(),serviceName:`mcp-proxy-http`,serviceType:`service`,environment:Y(),host:v.host??N,port:_,command:process.argv[1],args:process.argv.slice(2),...e.v()?{processGroupId:process.pid,terminationMode:`process-group`}:{terminationMode:`direct`},metadata:{transport:F,serverId:f,runtimeLifecycle:p,...c?{configPath:c}:{}}}),b=async()=>{await we(g??null),b=async()=>void 0},x=xe(f,v,_,d,c,p),S,C=!1,w=async()=>{if(!C){C=!0;try{await De(S,u,x.serverId,y),await b(),await l.dispose(),process.exit(0)}catch(e){throw Error(`Failed to stop HTTP runtime '${x.serverId}' from admin shutdown: ${W(e)}`)}}};try{let t=Te(x.serverId,d,w,p,s);S=new e.S(()=>e.r(l),v,t)}catch(e){throw await b(),await y.release({kill:!1}),await l.dispose(),Error(`Failed to create HTTP runtime server: ${W(e)}`)}try{await Z(S,async()=>{await b(),await l.dispose(),await Oe(u,x.serverId,y)}),await Ee(u,x)}catch(e){throw await b(),await l.dispose(),await ke(S,u,x.serverId,y),Error(`Failed to start HTTP runtime '${x.serverId}': ${W(e)}`)}console.error(`Runtime state: http://${x.host}:${x.port} (${x.serverId})`)}async function je(t){let n;try{n=await e.n(t),await Z(new e.d(n,J()),async()=>{await n?.dispose?.()},{shutdownOnStdinClose:!0})}catch(e){throw await n?.dispose?.(),Error(`Failed to start stdio transport: ${W(e)}`)}}async function Me(t){if(t)try{return(await new e.T().read(t))?.runtimeLifecycle}catch{return}}function Ne(t){if(!t)return e.g;let n=Number.parseInt(t,10);return Number.isInteger(n)&&n>0?n:e.g}function Q(e,t){let a=i.ProcessRegistryService.resolveRegistryPath(process.env.PROCESS_REGISTRY_PATH),o=(0,r.createHash)(`sha1`).update(`${(0,i.normalizeRepositoryPath)(e)}|${t}`).digest(`hex`);return(0,n.join)((0,n.dirname)(a),`mcp-proxy-runtime-${o.slice(0,16)}.lock`)}async function $(e,t,n){if(e.port!==void 0)return{endpoint:new URL(`http://${e.host??N}:${e.port}${M}`),runtimeLifecycle:V};let r=await U(),a=Ne(t.timeoutMs)+1e4;return await(0,i.withFileLock)(Q(r,L),async()=>Pe(r,e,t,n),{staleAfterMs:a,retryDelayMs:250,maxRetries:Math.ceil(a/250)})}async function Pe(t,n,r,i){let a=await e._(t);if(a){let e=n.host??a.host,t=a.serverId===`unknown`?void 0:a.serverId;return{endpoint:new URL(`http://${e}:${a.port}${M}`),runtimeServerId:t,runtimeLifecycle:a.runtimeLifecycle??await Me(t)??V}}let o=await e.y({host:n.host??N,config:i,cache:r.cache,definitionsCache:r.definitionsCache,clearDefinitionsCache:r.clearDefinitionsCache,proxyMode:r.proxyMode,runtimeLifecycle:B,idleShutdownMinutes:r.idleShutdownMinutes});return{endpoint:new URL(`http://${o.host}:${o.port}${M}`),runtimeServerId:o.serverId,runtimeLifecycle:o.runtimeLifecycle??V}}async function Fe(e,t,n){let{endpoint:r}=await $(e,t,n);return r}function Ie(e){return`runtime:${e}`}async function Le(e){if(e.runtimeLifecycle===B&&e.runtimeServerId)return await(0,i.createProcessLease)({repositoryPath:await U(),serviceName:`mcp-proxy-stdio-http-bridge:${(0,r.randomUUID)()}`,serviceType:`tool`,environment:Y(),pid:process.pid,command:process.argv[1],args:process.argv.slice(2),tags:[z,Ie(e.runtimeServerId)],metadata:{transport:I,runtimeServerId:e.runtimeServerId,runtimeLifecycle:e.runtimeLifecycle,endpoint:e.endpoint.toString()},force:!1})}function Re(e){return e.pid===process.pid}async function ze(e){return await new i.ProcessRegistryService(process.env.PROCESS_REGISTRY_PATH).listProcesses({repositoryPath:await U(),serviceType:`tool`,tags:[z,Ie(e)],environment:Y(),liveOnly:!0})}async function Be(e){return(await ze(e)).filter(e=>!Re(e)).length>0?!1:(await new Promise(e=>setTimeout(e,500)),(await ze(e)).filter(e=>!Re(e)).length===0)}async function Ve(t){if(t.runtimeLifecycle!==B||!t.runtimeServerId)return;let n=t.runtimeServerId,r=Q(await U(),L);try{await(0,i.withFileLock)(r,async()=>{await Be(n)&&await new e.C().stop({serverId:n,force:!0})})}catch(e){console.error(`Failed to stop managed stdio-http runtime; leaving it alive: ${W(e)}`)}}async function He(t,n,r,i){let a=n.autoDisconnect?!0:i?.keepAlive!==void 0&&!i.keepAlive,o,s;try{o=await $(t,n,r),s=await Le(o);let{endpoint:i}=o;await Z(new e.u({endpoint:i,resolveEndpoint:async()=>await Fe(t,n,r)},J()),async()=>{try{await s?.release({kill:!1,releasePort:!1})}catch(e){console.error(`Failed to release stdio-http bridge lease; leaving runtime alive: ${W(e)}`);return}a&&o&&await Ve(o)},{shutdownOnStdinClose:!0})}catch(e){try{await s?.release({kill:!1,releasePort:!1})}catch(t){throw Error(`Failed to start stdio-http transport: ${W(e)}; also failed to release bridge lease: ${W(t)}`)}throw Error(`Failed to start stdio-http transport: ${W(e)}`)}}async function Ue(t,n,r,i,a){try{if(t===P){await je(i);return}if(t===F){await Ae(i,q(n,e.t.HTTP,a),r,ue(n.idleShutdownMinutes));return}await He(q(n,e.t.HTTP,a),n,r,a)}catch(e){throw Error(`Failed to start transport '${t}': ${W(e)}`)}}async function We(t,n){try{let r=await e.y({id:t.id,host:t.host??N,port:t.port,config:n,cache:t.cache,definitionsCache:t.definitionsCache,clearDefinitionsCache:t.clearDefinitionsCache,proxyMode:t.proxyMode,timeoutMs:t.timeoutMs,idleShutdownMinutes:t.idleShutdownMinutes});e.x(r)}catch(e){console.error(`Failed to prestart HTTP runtime '${t.id||`generated-server-id`}': ${W(e)}`),process.exit(1)}}const Ge=new c.Command(`mcp-serve`).description(`Start MCP server with specified transport or prestart the HTTP runtime in the background`).option(`-t, --type <type>`,`Transport type: ${P}, ${F}, or ${I}`).option(`-p, --port <port>`,`Port to listen on (http) or backend port for stdio-http`,e=>Number.parseInt(e,10)).option(`--host <host>`,`Host to bind to (http) or backend host for stdio-http`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,e.F).option(`--no-cache`,`Disable configuration caching, always reload from config file`).option(`--definitions-cache <path>`,`Path to prefetched tool/prompt/skill definitions cache file`).option(`--clear-definitions-cache`,`Delete definitions cache before startup`,!1).option(`--proxy-mode <mode>`,`How mcp-proxy exposes downstream tools: meta, flat, search, or group`,`meta`).option(`--id <id>`,`Unique server identifier (overrides config file id, auto-generated if not provided)`).option(`--auto-disconnect`,`Stop the managed HTTP runtime when the last stdio-http bridge exits (default: keep runtime alive for reuse)`,!1).option(`--idle-shutdown-minutes <minutes>`,`Stop the HTTP runtime after N minutes with no MCP session and no request (0 disables; overrides ${H})`,e=>Number.parseFloat(e)).option(`--prestart-http`,`Prestart the HTTP runtime in the background and exit after it becomes healthy`,!1).option(`--timeout-ms <ms>`,`How long to wait for the HTTP runtime to become healthy`,String(e.g)).action(async t=>{try{let n=e.I(t.config),r=n.length>0?null:await fe(),i=r?[r]:n;if(t.prestartHttp){await We(t,i);return}let a=await me(i),o=ge((t.type??a.type??P).toLowerCase());_e(t.proxyMode),await Ue(o,t,i,ye(t,i,await he(t,i)),a)}catch(e){let n=(t.type??P).toLowerCase(),r=G(n)?n:P,i=process.env.MCP_PORT?Number(process.env.MCP_PORT):void 0,a=t.port??(Number.isFinite(i)?i:void 0);console.error(be(r,t.host??N,a,e)),process.exit(1)}}),Ke=new c.Command(`prefetch`).description(`Pre-download packages used by MCP servers (npx, pnpx, uvx, uv)`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,e.F).option(`-p, --parallel`,`Run prefetch commands in parallel`,!1).option(`-d, --dry-run`,`Show what would be prefetched without executing`,!1).option(`-f, --filter <type>`,`Filter by package manager type: npx, pnpx, uvx, or uv`).option(`--definitions-out <path>`,`Write discovered definitions to a JSON or YAML cache file`).option(`--skip-packages`,`Skip package prefetch and only build definitions cache`,!1).option(`--clear-definitions-cache`,`Delete the definitions cache file before continuing`,!1).action(async t=>{try{let n=e.o(),r=e.I(t.config),i=r.length>0?null:await e.P(),a=i?[i]:r;a.length===0&&(O.error(`No MCP configuration file found.`),O.info(`Use --config <path> to specify a config file, or run "po-mcp-proxy init" to create one.`),process.exit(1)),O.info(`Loading configuration from: ${a.join(`, `)}`);let o=await n.createConfigFetcherService({configSources:e.L(a),useCache:!1}).fetchConfiguration(!0),s=o.id||e.N(),c=e.j.generateConfigHash(o),l=t.definitionsOut||e.j.getDefaultCachePath(a),u=n.createPrefetchService({mcpConfig:o,filter:t.filter,parallel:t.parallel}),d=u.extractPackages(),f=!t.skipPackages,p=!!t.definitionsOut;if(t.clearDefinitionsCache&&(t.dryRun?O.info(`Would clear definitions cache: ${l}`):(await e.j.clearFile(l),O.success(`Cleared definitions cache: ${l}`))),f){if(d.length===0)O.warning(`No packages found to prefetch.`),O.info(`Prefetch supports: npx, pnpx, uvx, and uv run commands`);else{O.info(`Found ${d.length} package(s) to prefetch:`);for(let e of d)O.item(`${e.serverName}: ${e.packageManager} ${e.packageName}`)}}if(!f&&!p){O.warning(`Nothing to do. Use package prefetch or provide --definitions-out.`);return}if(t.dryRun){if(f&&d.length>0){O.newline(),O.header(`Dry run mode - commands that would be executed:`);for(let e of d)O.indent(e.fullCommand.join(` `))}p&&(O.newline(),O.info(`Would write definitions cache to: ${l}`));return}let m=!1;if(f&&d.length>0){O.newline(),O.info(`Prefetching packages...`);let e=await u.prefetch();if(O.newline(),e.failed===0?O.success(`Package prefetch complete: ${e.successful} succeeded, ${e.failed} failed`):O.warning(`Package prefetch complete: ${e.successful} succeeded, ${e.failed} failed`),e.failed>0){m=!0,O.newline(),O.error(`Failed packages:`);for(let t of e.results.filter(e=>!e.success))O.item(`${t.package.serverName} (${t.package.packageName}): ${t.output.trim()}`)}}if(p){O.newline(),O.info(`Collecting definitions cache...`);let t=await n.createClientManagerService(),r=o.skills?.paths||[],i=r.length>0?n.createSkillService(process.cwd(),r):void 0,u=n.createDefinitionsCacheService(t,i);await Promise.all(Object.entries(o.mcpServers).map(async([e,n])=>{try{await t.connectToServer(e,n),O.item(`Connected for definitions: ${e}`)}catch(t){O.warning(`Failed to connect for definitions: ${e} (${t instanceof Error?t.message:String(t)})`)}}));let d=await u.collectForCache({configPath:a[0],configHash:c,oneMcpVersion:e.h,serverId:s});await e.j.writeToFile(l,d),O.success(`Definitions cache written: ${l} (${Object.keys(d.servers).length} servers, ${d.skills.length} skills)`),d.failures.length>0&&O.warning(`Definitions cache completed with ${d.failures.length} server failure(s)`),await t.disconnectAll()}m&&process.exit(1)}catch(e){O.error(`Error executing prefetch: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});function qe(e){return e instanceof Error?e.message:String(e)}const Je=new c.Command(`read-resource`).description(`Read a resource by URI from a connected MCP server`).argument(`<uri>`,`Resource URI to read`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,e.F).option(`-s, --server <name>`,`Server name (required if resource exists on multiple servers)`).option(`-j, --json`,`Output as JSON`,!1).action(async(e,t)=>{try{await x(t,async({clientManager:n})=>{let r=n.getAllClients();if(t.server){let r=n.getClient(t.server);if(!r)throw Error(`Server "${t.server}" not found`);t.json||console.error(`Reading ${e} from ${t.server}...`);let i=await r.readResource(e);if(t.json)console.log(JSON.stringify(i,null,2));else for(let e of i.contents)`text`in e?console.log(e.text):console.log(JSON.stringify(e,null,2));return}let i=await Promise.all(r.map(async t=>{try{let n=(await t.listResources()).some(t=>t.uri===e);return{serverName:t.serverName,hasResource:n,error:null}}catch(e){return{serverName:t.serverName,hasResource:!1,error:e}}})),a=[];for(let{serverName:e,hasResource:t,error:n}of i)n?console.error(`Failed to list resources from ${e}: ${qe(n)}`):t&&a.push(e);if(a.length===0)throw Error(`Resource "${e}" not found on any connected server`);if(a.length>1)throw Error(`Resource "${e}" found on multiple servers: ${a.join(`, `)}. Use --server to disambiguate`);let o=a[0],s=n.getClient(o);if(!s)throw Error(`Internal error: Server "${o}" not connected`);t.json||console.error(`Reading ${e} from ${o}...`);let c=await s.readResource(e);if(t.json)console.log(JSON.stringify(c,null,2));else for(let e of c.contents)`text`in e?console.log(e.text):console.log(JSON.stringify(e,null,2))})}catch(e){console.error(`Error executing read-resource: ${qe(e)}`),process.exit(1)}});function Ye(e){return e instanceof Error?e.message:String(e)}function Xe(e){console.log(`Stopped mcp-proxy server '${e.serverId}'.`),console.log(`Endpoint: http://${e.host}:${e.port}`),console.log(`Result: ${e.message}`)}const Ze=new c.Command(`stop`).description(`Stop a running HTTP mcp-proxy server`).option(`--id <id>`,`Target server ID from the runtime registry`).option(`--host <host>`,`Target runtime host`).option(`--port <port>`,`Target runtime port`,e=>Number.parseInt(e,10)).option(`-c, --config <path>`,`Reserved for future config-based targeting support`).option(`--token <token>`,`Override the persisted shutdown token`).option(`--force`,`Skip server ID verification against the /health response`,!1).option(`-j, --json`,`Output as JSON`,!1).option(`--timeout <ms>`,`Maximum time to wait for shutdown completion`,e=>Number.parseInt(e,10),5e3).action(async t=>{try{t.config&&console.error(`Warning: --config is not used yet; runtime resolution uses the persisted registry.`);let n=await e.o().createStopServerService().stop({serverId:t.id,host:t.host,port:t.port,token:t.token,force:t.force,timeoutMs:t.timeout});if(t.json){console.log(JSON.stringify(n,null,2));return}Xe(n)}catch(e){let n=`Error executing stop: ${Ye(e)}`;t.json?console.log(JSON.stringify({ok:!1,error:n},null,2)):console.error(n),process.exit(1)}});function Qe(e){return e instanceof Error?e.message:String(e)}const $e=new c.Command(`use-tool`).description(`Execute an MCP tool with arguments`).argument(`<toolName>`,`Tool name to execute`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,e.F).option(`-s, --server <name>`,`Server name (required if tool exists on multiple servers)`).option(`-a, --args <json>`,`Tool arguments as JSON string`,`{}`).option(`-t, --timeout <ms>`,`Request timeout in milliseconds for tool execution (default: 60000)`,Number.parseInt).option(`-j, --json`,`Output as JSON`,!1).action(async(e,t)=>{try{let n={};try{n=JSON.parse(t.args)}catch{console.error(`Error: Invalid JSON in --args`),process.exit(1)}await x(t,async({container:r,config:i,clientManager:a})=>{let o=a.getAllClients();if(t.server){let r=a.getClient(t.server);if(!r)throw Error(`Server "${t.server}" not found`);t.json||console.error(`Executing ${e} on ${t.server}...`);let i=t.timeout?{timeout:t.timeout}:void 0,o=await r.callTool(e,n,i);if(t.json)console.log(JSON.stringify(o,null,2));else{if(console.log(`
|
|
141
|
+
`;function T(e=``){console.log(e)}function E(e,t){console.error(t?`${e} ${t}`:e)}const D={info:e=>T(e),error:(e,t)=>E(e,t)},O={info:e=>T(e),warning:e=>T(`Warning: ${e}`),error:e=>E(e),success:e=>T(e),newline:()=>T(),header:e=>T(e),item:e=>T(`- ${e}`),indent:e=>T(` ${e}`)},re=new c.Command(`init`).description(`Initialize MCP configuration file`).option(`-o, --output <path>`,`Output file path`,`mcp-config.yaml`).option(`--json`,`Generate JSON config instead of YAML`,!1).option(`-f, --force`,`Overwrite existing config file`,!1).option(`--mcp-servers <json>`,`JSON string of MCP servers to add to config (optional)`).action(async e=>{try{let r=(0,n.resolve)(e.output),i=!e.json&&(r.endsWith(`.yaml`)||r.endsWith(`.yml`)),a;if(i){let t=new s.Liquid,n=null;if(e.mcpServers)try{let t=JSON.parse(e.mcpServers);n=Object.entries(t).map(([e,t])=>({name:e,command:t.command,args:t.args}))}catch(e){D.error(`Failed to parse --mcp-servers JSON:`,e instanceof Error?e.message:String(e)),process.exit(1)}a=await t.parseAndRender(ne,{mcpServers:n})}else a=te;try{await(0,t.writeFile)(r,a,{encoding:`utf-8`,flag:e.force?`w`:`wx`})}catch(e){throw e&&typeof e==`object`&&`code`in e&&e.code===`EEXIST`&&(D.error(`Config file already exists: ${r}`),D.info(`Use --force to overwrite`),process.exit(1)),e}D.info(`MCP configuration file created: ${r}`),D.info(`Next steps:`),D.info(`1. Edit the configuration file to add your MCP servers`),D.info(`2. Run: po-mcp-proxy mcp-serve --config ${r}`)}catch(e){D.error(`Error executing init:`,e instanceof Error?e.message:String(e)),process.exit(1)}});function k(e){return e instanceof Error?e.message:String(e)}const ie=new c.Command(`list-prompts`).description(`List all available prompts from connected MCP servers`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,e.L).option(`-s, --server <name>`,`Filter by server name`).option(`-j, --json`,`Output as JSON`,!1).action(async e=>{try{await x(e,async({clientManager:t})=>{let n=e.server?[t.getClient(e.server)].filter(e=>e!==void 0):t.getAllClients();if(e.server&&n.length===0)throw Error(`Server "${e.server}" not found`);let r={};if(await Promise.all(n.map(async t=>{try{r[t.serverName]=await t.listPrompts()}catch(n){r[t.serverName]=[],e.json||console.error(`Failed to list prompts from ${t.serverName}: ${k(n)}`)}})),e.json)console.log(JSON.stringify(r,null,2));else for(let[e,t]of Object.entries(r))if(console.log(`\n${e}:`),t.length===0)console.log(` No prompts available`);else for(let e of t)if(console.log(` - ${e.name}: ${e.description||`No description`}`),e.arguments&&e.arguments.length>0){let t=e.arguments.map(e=>`${e.name}${e.required?` (required)`:``}`).join(`, `);console.log(` args: ${t}`)}})}catch(e){console.error(`Error executing list-prompts: ${k(e)}`),process.exit(1)}});function A(e){return e instanceof Error?e.message:String(e)}const ae=new c.Command(`list-resources`).description(`List all available resources from connected MCP servers`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,e.L).option(`-s, --server <name>`,`Filter by server name`).option(`-j, --json`,`Output as JSON`,!1).action(async e=>{try{await x(e,async({clientManager:t})=>{let n=e.server?[t.getClient(e.server)].filter(e=>e!==void 0):t.getAllClients();if(e.server&&n.length===0)throw Error(`Server "${e.server}" not found`);let r={},i=await Promise.all(n.map(async e=>{try{let t=await e.listResources();return{serverName:e.serverName,resources:t,error:null}}catch(t){return{serverName:e.serverName,resources:[],error:t}}}));for(let{serverName:t,resources:n,error:a}of i)a&&!e.json&&console.error(`Failed to list resources from ${t}: ${A(a)}`),r[t]=n;if(e.json)console.log(JSON.stringify(r,null,2));else for(let[e,t]of Object.entries(r))if(console.log(`\n${e}:`),t.length===0)console.log(` No resources available`);else for(let e of t){let t=e.name?`${e.name} (${e.uri})`:e.uri;console.log(` - ${t}${e.description?`: ${e.description}`:``}`)}})}catch(e){console.error(`Error executing list-resources: ${A(e)}`),process.exit(1)}});function oe(e){return e instanceof Error?e.message:String(e)}function se(e){for(let t of e.servers)if(console.log(`\n${t.server}:`),t.capabilities&&t.capabilities.length>0&&console.log(` capabilities: ${t.capabilities.join(`, `)}`),t.summary&&console.log(` summary: ${t.summary}`),t.tools.length===0)console.log(` no tools`);else for(let e of t.tools){let t=e.capabilities&&e.capabilities.length>0?` [${e.capabilities.join(`, `)}]`:``;console.log(` - ${e.name}${t}`),e.description&&console.log(` ${e.description}`)}}const ce=new c.Command(`search-tools`).description(`Search proxied MCP tools by capability or server`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,e.L).option(`-s, --server <name>`,`Filter by server name`).option(`--capability <name>`,`Filter by capability tag, summary, tool name, or description`).option(`--definitions-cache <path>`,`Path to definitions cache file`).option(`-j, --json`,`Output as JSON`,!1).action(async t=>{try{await x(t,async({container:n,config:r,clientManager:i,configFilePaths:a})=>{i.registerServerConfigs(r.mcpServers);let o=t.definitionsCache||e.j.getDefaultCachePath(a),s;try{s=await e.j.readFromFile(o)}catch{s=void 0}let c=n.createDefinitionsCacheService(i,void 0,{cacheData:s}),l=(await n.createSearchListToolsTool(i,c).execute({capability:t.capability,serverName:t.server})).content.find(e=>e.type===`text`),u=l?.type===`text`?JSON.parse(l.text):{servers:[]};if(t.json)console.log(JSON.stringify(u,null,2));else{if(!u.servers||u.servers.length===0)throw Error(`No tools matched the requested filters`);se(u)}})}catch(e){console.error(`Error executing search-tools: ${oe(e)}`),process.exit(1)}}),j=[`mcp-config.yaml`,`mcp-config.yml`,`mcp-config.json`],M=`/mcp`,N=`localhost`,P=`stdio`,F=`http`,I=`stdio-http`,L=`mcp-proxy-http`,R=`service`;async function le(){return e.pt()}const z=`mcp-proxy-stdio-http-bridge`,B=`stdio-http-managed`,V=`manual`,H=`MCP_PROXY_IDLE_SHUTDOWN_MINUTES`;async function U(){return le()}function W(e){return e instanceof Error?e.message:String(e)}function ue(e){let t=process.env[H],n=e??(t?Number.parseFloat(t):void 0);return n===void 0||!Number.isFinite(n)||n<=0?0:Math.round(n*6e4)}function G(e){return e===P||e===F||e===I}function de(e){return e===`meta`||e===`flat`||e===`search`||e===`group`}async function K(e){try{return await(0,t.access)(e,l.constants.F_OK),!0}catch{return!1}}async function fe(){try{let e=process.env.PROJECT_PATH;if(e)for(let t of j){let r=(0,n.resolve)(e,t);if(await K(r))return r}let t=process.cwd();for(let e=0;e<=3;e++){for(let e of j){let r=(0,n.join)(t,e);if(await K(r))return r}let e=(0,n.dirname)(t);if(e===t)break;t=e}return null}catch(e){throw Error(`Failed to discover MCP config file: ${W(e)}`)}}async function pe(e){try{let n=await(0,t.readFile)(e,`utf-8`),r=(e.endsWith(`.yaml`)||e.endsWith(`.yml`)?a.load(n):JSON.parse(n))?.proxy;if(!r||typeof r!=`object`)return{};let i=r;return{type:typeof i.type==`string`?i.type:void 0,port:typeof i.port==`number`&&Number.isInteger(i.port)&&i.port>0?i.port:void 0,host:typeof i.host==`string`?i.host:void 0,keepAlive:typeof i.keepAlive==`boolean`?i.keepAlive:void 0}}catch{return{}}}async function me(e){let t={};for(let n of e){let e=await pe(n);e.type!==void 0&&(t.type=e.type),e.port!==void 0&&(t.port=e.port),e.host!==void 0&&(t.host=e.host),e.keepAlive!==void 0&&(t.keepAlive=e.keepAlive)}return t}async function he(t,n){let r=e.o();if(t.id)return t.id;if(n.length>0)try{let i=await r.createConfigFetcherService({configSources:e.z(n),useCache:t.cache!==!1}).fetchConfiguration(t.cache===!1);if(i.id)return i.id}catch(e){throw Error(`Failed to resolve server ID from config '${n.join(`, `)}': ${W(e)}`)}return e.F()}function ge(e){if(!G(e))throw Error(`Unknown transport type: '${e}'. Valid options: ${P}, ${F}, ${I}`);return e}function _e(e){if(!de(e))throw Error(`Unknown proxy mode: '${String(e)}'. Valid options: meta, flat, search, group`)}function ve(e){return e===B?B:V}function q(e,t,n){let r=process.env.MCP_PORT?Number(process.env.MCP_PORT):void 0;return{mode:t,port:e.port??(Number.isFinite(r)?r:void 0)??n?.port,host:e.host??process.env.MCP_HOST??n?.host??N}}function J(){let e=(e,t)=>{t===void 0?console.error(e):console.error(e,t)};return{trace:e,debug:e,info:e,warn:e,error:e}}function ye(e,t,n){return{configFilePath:t.length>0?t:void 0,noCache:e.cache===!1,serverId:n,definitionsCachePath:e.definitionsCache,clearDefinitionsCache:e.clearDefinitionsCache,proxyMode:e.proxyMode}}function be(e,t,n,r){let i=W(r);return e===P?`Failed to start MCP server with transport '${e}': ${i}`:`Failed to start MCP server with transport '${e}' on ${n===void 0?`${t} (dynamic port)`:`${t}:${n}`}: ${i}`}function xe(e,t,n,r,i,a=V){return{serverId:e,host:t.host??N,port:n,transport:`http`,shutdownToken:r,startedAt:(/* @__PURE__ */ new Date()).toISOString(),pid:process.pid,configPath:i,runtimeLifecycle:a}}function Se(){return new o.PortRegistryService(process.env.PORT_REGISTRY_PATH)}function Y(){return process.env.NODE_ENV??`development`}async function Ce(e,t,n,r,i,a,s=n===void 0?o.DEFAULT_PORT_RANGE:{min:n,max:n}){let c=Se(),l=await c.reservePort({repositoryPath:await U(),serviceName:e,serviceType:R,environment:Y(),pid:process.pid,host:t,preferredPort:n,portRange:s,force:!0,metadata:{transport:i,serverId:r,...a?{configPath:a}:{}}});if(!l.success||!l.record){let e=n===void 0?`dynamic port`:`port ${n}`;throw Error(l.error||`Failed to reserve ${e} in port registry`)}let u=!1;return{port:l.record.port,release:async()=>{if(u)return;u=!0;let t=await c.releasePort({repositoryPath:await U(),serviceName:e,serviceType:R,pid:process.pid,environment:Y(),force:!0});if(!t.success&&t.error&&!t.error.includes(`No matching registry entry`))throw Error(t.error||`Failed to release port for ${e}`)}}}async function we(e){e&&await e.release()}function Te(e,t,n,r,i){return{serverId:e,shutdownToken:t,onShutdownRequested:n,runtimeLifecycle:r,idleShutdownMs:i}}async function X(e,t){try{await e.remove(t)}catch(e){throw Error(`Failed to remove runtime state for '${t}': ${W(e)}`)}}async function Ee(e,t){try{await e.write(t)}catch(e){throw Error(`Failed to persist runtime state for '${t.serverId}': ${W(e)}`)}}async function De(e,t,n,r){try{try{await e.stop()}catch(e){throw Error(`Failed to stop owned HTTP transport '${n}': ${W(e)}`)}}finally{await r?.release({kill:!1}),await X(t,n)}}async function Oe(e,t,n){await n?.release({kill:!1}),await X(e,t)}async function ke(e,t,n,r){try{try{await e.stop()}catch(e){throw Error(`Failed to stop HTTP transport during cleanup for '${n}': ${W(e)}`)}}finally{await r?.release({kill:!1}),await X(t,n)}}async function Z(e,t,n={}){try{await e.start()}catch(e){throw Error(`Failed to start transport handler: ${W(e)}`)}let r=!1,i=async n=>{if(!r){r=!0,console.error(`\nReceived ${n}, shutting down gracefully...`);try{await e.stop(),t&&await t(),process.exit(0)}catch(e){console.error(`Failed to gracefully stop transport during ${n}: ${W(e)}`),process.exit(1)}}};process.on(`SIGINT`,async()=>await i(`SIGINT`)),process.on(`SIGTERM`,async()=>await i(`SIGTERM`)),n.shutdownOnStdinClose&&(process.stdin.on(`end`,async()=>await i(`stdin end`)),process.stdin.on(`close`,async()=>await i(`stdin close`)))}async function Ae(t,n,a,s){e.P();let c=a[0],l=await e.l(t),u=new e.T,d=(0,r.randomUUID)(),f=t.serverId??e.F(),p=ve(process.env.MCP_PROXY_RUNTIME_LIFECYCLE),m=n.port,h=m===void 0?o.DEFAULT_PORT_RANGE:{min:m,max:m},g=await Ce(L,n.host??N,m,f,F,c,h),_=g.port,v={...n,port:_},y=await(0,i.createProcessLease)({repositoryPath:await U(),serviceName:`mcp-proxy-http`,serviceType:`service`,environment:Y(),host:v.host??N,port:_,command:process.argv[1],args:process.argv.slice(2),...e.v()?{processGroupId:process.pid,terminationMode:`process-group`}:{terminationMode:`direct`},metadata:{transport:F,serverId:f,runtimeLifecycle:p,...c?{configPath:c}:{}}}),b=async()=>{await we(g??null),b=async()=>void 0},x=xe(f,v,_,d,c,p),S,C=!1,w=async()=>{if(!C){C=!0;try{await De(S,u,x.serverId,y),await b(),await l.dispose(),process.exit(0)}catch(e){throw Error(`Failed to stop HTTP runtime '${x.serverId}' from admin shutdown: ${W(e)}`)}}};try{let t=Te(x.serverId,d,w,p,s);S=new e.S(()=>e.r(l),v,t)}catch(e){throw await b(),await y.release({kill:!1}),await l.dispose(),Error(`Failed to create HTTP runtime server: ${W(e)}`)}try{await Z(S,async()=>{await b(),await l.dispose(),await Oe(u,x.serverId,y)}),await Ee(u,x)}catch(e){throw await b(),await l.dispose(),await ke(S,u,x.serverId,y),Error(`Failed to start HTTP runtime '${x.serverId}': ${W(e)}`)}console.error(`Runtime state: http://${x.host}:${x.port} (${x.serverId})`)}async function je(t){let n;try{n=await e.n(t),await Z(new e.d(n,J()),async()=>{await n?.dispose?.()},{shutdownOnStdinClose:!0})}catch(e){throw await n?.dispose?.(),Error(`Failed to start stdio transport: ${W(e)}`)}}async function Me(t){if(t)try{return(await new e.T().read(t))?.runtimeLifecycle}catch{return}}function Ne(t){if(!t)return e.g;let n=Number.parseInt(t,10);return Number.isInteger(n)&&n>0?n:e.g}function Q(e,t){let a=i.ProcessRegistryService.resolveRegistryPath(process.env.PROCESS_REGISTRY_PATH),o=(0,r.createHash)(`sha1`).update(`${(0,i.normalizeRepositoryPath)(e)}|${t}`).digest(`hex`);return(0,n.join)((0,n.dirname)(a),`mcp-proxy-runtime-${o.slice(0,16)}.lock`)}async function $(e,t,n){if(e.port!==void 0)return{endpoint:new URL(`http://${e.host??N}:${e.port}${M}`),runtimeLifecycle:V};let r=await U(),a=Ne(t.timeoutMs)+1e4;return await(0,i.withFileLock)(Q(r,L),async()=>Pe(r,e,t,n),{staleAfterMs:a,retryDelayMs:250,maxRetries:Math.ceil(a/250)})}async function Pe(t,n,r,i){let a=await e._(t);if(a){let e=n.host??a.host,t=a.serverId===`unknown`?void 0:a.serverId;return{endpoint:new URL(`http://${e}:${a.port}${M}`),runtimeServerId:t,runtimeLifecycle:a.runtimeLifecycle??await Me(t)??V}}let o=await e.y({host:n.host??N,config:i,cache:r.cache,definitionsCache:r.definitionsCache,clearDefinitionsCache:r.clearDefinitionsCache,proxyMode:r.proxyMode,runtimeLifecycle:B,idleShutdownMinutes:r.idleShutdownMinutes});return{endpoint:new URL(`http://${o.host}:${o.port}${M}`),runtimeServerId:o.serverId,runtimeLifecycle:o.runtimeLifecycle??V}}async function Fe(e,t,n){let{endpoint:r}=await $(e,t,n);return r}function Ie(e){return`runtime:${e}`}async function Le(e){if(e.runtimeLifecycle===B&&e.runtimeServerId)return await(0,i.createProcessLease)({repositoryPath:await U(),serviceName:`mcp-proxy-stdio-http-bridge:${(0,r.randomUUID)()}`,serviceType:`tool`,environment:Y(),pid:process.pid,command:process.argv[1],args:process.argv.slice(2),tags:[z,Ie(e.runtimeServerId)],metadata:{transport:I,runtimeServerId:e.runtimeServerId,runtimeLifecycle:e.runtimeLifecycle,endpoint:e.endpoint.toString()},force:!1})}function Re(e){return e.pid===process.pid}async function ze(e){return await new i.ProcessRegistryService(process.env.PROCESS_REGISTRY_PATH).listProcesses({repositoryPath:await U(),serviceType:`tool`,tags:[z,Ie(e)],environment:Y(),liveOnly:!0})}async function Be(e){return(await ze(e)).filter(e=>!Re(e)).length>0?!1:(await new Promise(e=>setTimeout(e,500)),(await ze(e)).filter(e=>!Re(e)).length===0)}async function Ve(t){if(t.runtimeLifecycle!==B||!t.runtimeServerId)return;let n=t.runtimeServerId,r=Q(await U(),L);try{await(0,i.withFileLock)(r,async()=>{await Be(n)&&await new e.C().stop({serverId:n,force:!0})})}catch(e){console.error(`Failed to stop managed stdio-http runtime; leaving it alive: ${W(e)}`)}}async function He(t,n,r,i){let a=n.autoDisconnect?!0:i?.keepAlive!==void 0&&!i.keepAlive,o,s;try{o=await $(t,n,r),s=await Le(o);let{endpoint:i}=o;await Z(new e.u({endpoint:i,resolveEndpoint:async()=>await Fe(t,n,r)},J()),async()=>{try{await s?.release({kill:!1,releasePort:!1})}catch(e){console.error(`Failed to release stdio-http bridge lease; leaving runtime alive: ${W(e)}`);return}a&&o&&await Ve(o)},{shutdownOnStdinClose:!0})}catch(e){try{await s?.release({kill:!1,releasePort:!1})}catch(t){throw Error(`Failed to start stdio-http transport: ${W(e)}; also failed to release bridge lease: ${W(t)}`)}throw Error(`Failed to start stdio-http transport: ${W(e)}`)}}async function Ue(t,n,r,i,a){try{if(t===P){await je(i);return}if(t===F){await Ae(i,q(n,e.t.HTTP,a),r,ue(n.idleShutdownMinutes));return}await He(q(n,e.t.HTTP,a),n,r,a)}catch(e){throw Error(`Failed to start transport '${t}': ${W(e)}`)}}async function We(t,n){try{let r=await e.y({id:t.id,host:t.host??N,port:t.port,config:n,cache:t.cache,definitionsCache:t.definitionsCache,clearDefinitionsCache:t.clearDefinitionsCache,proxyMode:t.proxyMode,timeoutMs:t.timeoutMs,idleShutdownMinutes:t.idleShutdownMinutes});e.x(r)}catch(e){console.error(`Failed to prestart HTTP runtime '${t.id||`generated-server-id`}': ${W(e)}`),process.exit(1)}}const Ge=new c.Command(`mcp-serve`).description(`Start MCP server with specified transport or prestart the HTTP runtime in the background`).option(`-t, --type <type>`,`Transport type: ${P}, ${F}, or ${I}`).option(`-p, --port <port>`,`Port to listen on (http) or backend port for stdio-http`,e=>Number.parseInt(e,10)).option(`--host <host>`,`Host to bind to (http) or backend host for stdio-http`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,e.L).option(`--no-cache`,`Disable configuration caching, always reload from config file`).option(`--definitions-cache <path>`,`Path to prefetched tool/prompt/skill definitions cache file`).option(`--clear-definitions-cache`,`Delete definitions cache before startup`,!1).option(`--proxy-mode <mode>`,`How mcp-proxy exposes downstream tools: meta, flat, search, or group`,`meta`).option(`--id <id>`,`Unique server identifier (overrides config file id, auto-generated if not provided)`).option(`--auto-disconnect`,`Stop the managed HTTP runtime when the last stdio-http bridge exits (default: keep runtime alive for reuse)`,!1).option(`--idle-shutdown-minutes <minutes>`,`Stop the HTTP runtime after N minutes with no MCP session and no request (0 disables; overrides ${H})`,e=>Number.parseFloat(e)).option(`--prestart-http`,`Prestart the HTTP runtime in the background and exit after it becomes healthy`,!1).option(`--timeout-ms <ms>`,`How long to wait for the HTTP runtime to become healthy`,String(e.g)).action(async t=>{try{let n=e.R(t.config),r=n.length>0?null:await fe(),i=r?[r]:n;if(t.prestartHttp){await We(t,i);return}let a=await me(i),o=ge((t.type??a.type??P).toLowerCase());_e(t.proxyMode),await Ue(o,t,i,ye(t,i,await he(t,i)),a)}catch(e){let n=(t.type??P).toLowerCase(),r=G(n)?n:P,i=process.env.MCP_PORT?Number(process.env.MCP_PORT):void 0,a=t.port??(Number.isFinite(i)?i:void 0);console.error(be(r,t.host??N,a,e)),process.exit(1)}}),Ke=new c.Command(`prefetch`).description(`Pre-download packages used by MCP servers (npx, pnpx, uvx, uv)`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,e.L).option(`-p, --parallel`,`Run prefetch commands in parallel`,!1).option(`-d, --dry-run`,`Show what would be prefetched without executing`,!1).option(`-f, --filter <type>`,`Filter by package manager type: npx, pnpx, uvx, or uv`).option(`--definitions-out <path>`,`Write discovered definitions to a JSON or YAML cache file`).option(`--skip-packages`,`Skip package prefetch and only build definitions cache`,!1).option(`--clear-definitions-cache`,`Delete the definitions cache file before continuing`,!1).action(async t=>{try{let n=e.o(),r=e.R(t.config),i=r.length>0?null:await e.I(),a=i?[i]:r;a.length===0&&(O.error(`No MCP configuration file found.`),O.info(`Use --config <path> to specify a config file, or run "po-mcp-proxy init" to create one.`),process.exit(1)),O.info(`Loading configuration from: ${a.join(`, `)}`);let o=await n.createConfigFetcherService({configSources:e.z(a),useCache:!1}).fetchConfiguration(!0),s=o.id||e.F(),c=e.j.generateConfigHash(o),l=t.definitionsOut||e.j.getDefaultCachePath(a),u=n.createPrefetchService({mcpConfig:o,filter:t.filter,parallel:t.parallel}),d=u.extractPackages(),f=!t.skipPackages,p=!!t.definitionsOut;if(t.clearDefinitionsCache&&(t.dryRun?O.info(`Would clear definitions cache: ${l}`):(await e.j.clearFile(l),O.success(`Cleared definitions cache: ${l}`))),f){if(d.length===0)O.warning(`No packages found to prefetch.`),O.info(`Prefetch supports: npx, pnpx, uvx, and uv run commands`);else{O.info(`Found ${d.length} package(s) to prefetch:`);for(let e of d)O.item(`${e.serverName}: ${e.packageManager} ${e.packageName}`)}}if(!f&&!p){O.warning(`Nothing to do. Use package prefetch or provide --definitions-out.`);return}if(t.dryRun){if(f&&d.length>0){O.newline(),O.header(`Dry run mode - commands that would be executed:`);for(let e of d)O.indent(e.fullCommand.join(` `))}p&&(O.newline(),O.info(`Would write definitions cache to: ${l}`));return}let m=!1;if(f&&d.length>0){O.newline(),O.info(`Prefetching packages...`);let e=await u.prefetch();if(O.newline(),e.failed===0?O.success(`Package prefetch complete: ${e.successful} succeeded, ${e.failed} failed`):O.warning(`Package prefetch complete: ${e.successful} succeeded, ${e.failed} failed`),e.failed>0){m=!0,O.newline(),O.error(`Failed packages:`);for(let t of e.results.filter(e=>!e.success))O.item(`${t.package.serverName} (${t.package.packageName}): ${t.output.trim()}`)}}if(p){O.newline(),O.info(`Collecting definitions cache...`);let t=await n.createClientManagerService(),r=o.skills?.paths||[],i=r.length>0?n.createSkillService(process.cwd(),r):void 0,u=n.createDefinitionsCacheService(t,i);await Promise.all(Object.entries(o.mcpServers).map(async([e,n])=>{try{await t.connectToServer(e,n),O.item(`Connected for definitions: ${e}`)}catch(t){O.warning(`Failed to connect for definitions: ${e} (${t instanceof Error?t.message:String(t)})`)}}));let d=await u.collectForCache({configPath:a[0],configHash:c,oneMcpVersion:e.h,serverId:s});await e.j.writeToFile(l,d),O.success(`Definitions cache written: ${l} (${Object.keys(d.servers).length} servers, ${d.skills.length} skills)`),d.failures.length>0&&O.warning(`Definitions cache completed with ${d.failures.length} server failure(s)`),await t.disconnectAll()}m&&process.exit(1)}catch(e){O.error(`Error executing prefetch: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});function qe(e){return e instanceof Error?e.message:String(e)}const Je=new c.Command(`read-resource`).description(`Read a resource by URI from a connected MCP server`).argument(`<uri>`,`Resource URI to read`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,e.L).option(`-s, --server <name>`,`Server name (required if resource exists on multiple servers)`).option(`-j, --json`,`Output as JSON`,!1).action(async(e,t)=>{try{await x(t,async({clientManager:n})=>{let r=n.getAllClients();if(t.server){let r=n.getClient(t.server);if(!r)throw Error(`Server "${t.server}" not found`);t.json||console.error(`Reading ${e} from ${t.server}...`);let i=await r.readResource(e);if(t.json)console.log(JSON.stringify(i,null,2));else for(let e of i.contents)`text`in e?console.log(e.text):console.log(JSON.stringify(e,null,2));return}let i=await Promise.all(r.map(async t=>{try{let n=(await t.listResources()).some(t=>t.uri===e);return{serverName:t.serverName,hasResource:n,error:null}}catch(e){return{serverName:t.serverName,hasResource:!1,error:e}}})),a=[];for(let{serverName:e,hasResource:t,error:n}of i)n?console.error(`Failed to list resources from ${e}: ${qe(n)}`):t&&a.push(e);if(a.length===0)throw Error(`Resource "${e}" not found on any connected server`);if(a.length>1)throw Error(`Resource "${e}" found on multiple servers: ${a.join(`, `)}. Use --server to disambiguate`);let o=a[0],s=n.getClient(o);if(!s)throw Error(`Internal error: Server "${o}" not connected`);t.json||console.error(`Reading ${e} from ${o}...`);let c=await s.readResource(e);if(t.json)console.log(JSON.stringify(c,null,2));else for(let e of c.contents)`text`in e?console.log(e.text):console.log(JSON.stringify(e,null,2))})}catch(e){console.error(`Error executing read-resource: ${qe(e)}`),process.exit(1)}});function Ye(e){return e instanceof Error?e.message:String(e)}function Xe(e){console.log(`Stopped mcp-proxy server '${e.serverId}'.`),console.log(`Endpoint: http://${e.host}:${e.port}`),console.log(`Result: ${e.message}`)}const Ze=new c.Command(`stop`).description(`Stop a running HTTP mcp-proxy server`).option(`--id <id>`,`Target server ID from the runtime registry`).option(`--host <host>`,`Target runtime host`).option(`--port <port>`,`Target runtime port`,e=>Number.parseInt(e,10)).option(`-c, --config <path>`,`Reserved for future config-based targeting support`).option(`--token <token>`,`Override the persisted shutdown token`).option(`--force`,`Skip server ID verification against the /health response`,!1).option(`-j, --json`,`Output as JSON`,!1).option(`--timeout <ms>`,`Maximum time to wait for shutdown completion`,e=>Number.parseInt(e,10),5e3).action(async t=>{try{t.config&&console.error(`Warning: --config is not used yet; runtime resolution uses the persisted registry.`);let n=await e.o().createStopServerService().stop({serverId:t.id,host:t.host,port:t.port,token:t.token,force:t.force,timeoutMs:t.timeout});if(t.json){console.log(JSON.stringify(n,null,2));return}Xe(n)}catch(e){let n=`Error executing stop: ${Ye(e)}`;t.json?console.log(JSON.stringify({ok:!1,error:n},null,2)):console.error(n),process.exit(1)}});function Qe(e){return e instanceof Error?e.message:String(e)}const $e=new c.Command(`use-tool`).description(`Execute an MCP tool with arguments`).argument(`<toolName>`,`Tool name to execute`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,e.L).option(`-s, --server <name>`,`Server name (required if tool exists on multiple servers)`).option(`-a, --args <json>`,`Tool arguments as JSON string`,`{}`).option(`-t, --timeout <ms>`,`Request timeout in milliseconds for tool execution (default: 60000)`,Number.parseInt).option(`-j, --json`,`Output as JSON`,!1).action(async(e,t)=>{try{let n={};try{n=JSON.parse(t.args)}catch{console.error(`Error: Invalid JSON in --args`),process.exit(1)}await x(t,async({container:r,config:i,clientManager:a})=>{let o=a.getAllClients();if(t.server){let r=a.getClient(t.server);if(!r)throw Error(`Server "${t.server}" not found`);t.json||console.error(`Executing ${e} on ${t.server}...`);let i=t.timeout?{timeout:t.timeout}:void 0,o=await r.callTool(e,n,i);if(t.json)console.log(JSON.stringify(o,null,2));else{if(console.log(`
|
|
142
142
|
Result:`),o.content)for(let e of o.content)e.type===`text`?console.log(e.text):console.log(JSON.stringify(e,null,2));o.isError&&(console.error(`
|
|
143
143
|
⚠️ Tool execution returned an error`),process.exit(1))}return}let s=await Promise.all(o.map(async t=>{try{let n=(await t.listTools()).some(t=>t.name===e);return{serverName:t.serverName,hasTool:n,error:null}}catch(e){return{serverName:t.serverName,hasTool:!1,error:e}}})),c=[];for(let{serverName:e,hasTool:n,error:r}of s)r?t.json||console.error(`Failed to list tools from ${e}:`,r):n&&c.push(e);if(c.length===0){let n=i.skills?.paths||[];if(n.length>0)try{let i=process.env.PROJECT_PATH||process.cwd(),a=r.createSkillService(i,n),o=e.startsWith(`skill__`)?e.slice(7):e,s=await a.getSkill(o);if(s){let e={content:[{type:`text`,text:s.content}]};t.json?console.log(JSON.stringify(e,null,2)):(console.log(`
|
|
144
144
|
Skill content:`),console.log(s.content));return}}catch(n){t.json||console.error(`Failed to lookup skill "${e}":`,n)}throw Error(`Tool or skill "${e}" not found on any connected server or configured skill paths`)}if(c.length>1)throw Error(`Tool "${e}" found on multiple servers: ${c.join(`, `)}`);let l=c[0],u=a.getClient(l);if(!u)throw Error(`Internal error: Server "${l}" not connected`);t.json||console.error(`Executing ${e} on ${l}...`);let d=t.timeout?{timeout:t.timeout}:void 0,f=await u.callTool(e,n,d);if(t.json)console.log(JSON.stringify(f,null,2));else{if(console.log(`
|
package/dist/cli.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{C as e,F as t,I as n,L as r,
|
|
2
|
+
import{C as e,F as t,I as n,L as r,P as i,R as a,S as o,T as s,_ as c,b as l,d as u,g as d,h as f,j as p,l as m,n as h,o as g,pt as _,r as v,t as y,u as b,v as ee,x,y as S,z as C}from"./src-BwFgoC11.mjs";import{access as w,readFile as T,writeFile as te}from"node:fs/promises";import{dirname as E,join as D,resolve as O}from"node:path";import{createHash as ne,randomUUID as re}from"node:crypto";import{ProcessRegistryService as k,createProcessLease as ie,normalizeRepositoryPath as ae,withFileLock as oe}from"@agimon-ai/foundation-process-registry";import*as se from"js-yaml";import{DEFAULT_PORT_RANGE as ce,PortRegistryService as le}from"@agimon-ai/foundation-port-registry";import{Liquid as ue}from"liquidjs";import{Command as A}from"commander";import{constants as de}from"node:fs";function fe(e){return`runtime:${e}`}function pe(e){return e instanceof Error?e.message:String(e)}async function me(e){let t=await e.listProcesses({serviceName:`mcp-proxy-http`,liveOnly:!0}),n=/* @__PURE__ */ new Set;for(let e of t){let t=e.metadata?.serverId;typeof t==`string`&&n.add(t)}return n}async function he(e,t){let n=await e.listProcesses({serviceType:`tool`,tags:[`mcp-proxy-stdio-http-bridge`],liveOnly:!0}),r=fe(t);return n.filter(e=>e.tags?.includes(r)).length}async function ge(e){let t=e.probe??(async(e,t)=>(await l(e,t)).ok),n={stopped:[],removedFiles:[],kept:[]},r=await me(e.processRegistry),i=await e.runtimeStateService.listOrphans(r);for(let r of i){let i={serverId:r.serverId,host:r.host,port:r.port,reason:``};if(!await t(r.host,r.port)){i.reason=`unreachable runtime; removed stale state file`,e.dryRun||await e.runtimeStateService.remove(r.serverId),n.removedFiles.push(i);continue}if(r.runtimeLifecycle!==`stdio-http-managed`){i.reason=`manual runtime; left untouched`,n.kept.push(i);continue}let a=await he(e.processRegistry,r.serverId);if(a>0)i.reason=`managed runtime with ${a} live bridge(s); kept`,n.kept.push(i);else{if(i.reason=`orphaned stdio-http-managed runtime (no live bridges); stopped`,!e.dryRun)try{await e.stopServerService.stop({serverId:r.serverId,force:!0}),await e.runtimeStateService.remove(r.serverId).catch(()=>void 0)}catch(e){i.reason=`failed to stop orphaned runtime: ${pe(e)}`,n.kept.push(i);continue}n.stopped.push(i)}}return n}function _e(e,t){let n=t?`Would stop`:`Stopped`;for(let t of e.stopped)console.log(`${n} orphaned runtime '${t.serverId}' (http://${t.host}:${t.port}) — ${t.reason}`);let r=t?`Would remove`:`Removed`;for(let t of e.removedFiles)console.log(`${r} stale state for '${t.serverId}' (http://${t.host}:${t.port})`);for(let t of e.kept)console.log(`Kept '${t.serverId}' (http://${t.host}:${t.port}) — ${t.reason}`);console.log(`Summary: ${e.stopped.length} stopped, ${e.removedFiles.length} stale file(s), ${e.kept.length} kept.`)}const ve=new A(`cleanup`).description(`Reap orphaned/stale mcp-proxy HTTP runtimes and their leftover state files`).option(`-n, --dry-run`,`Report what would be done without stopping or removing anything`,!1).option(`-j, --json`,`Output as JSON`,!1).action(async t=>{try{let n=await ge({runtimeStateService:new s,processRegistry:new k(process.env.PROCESS_REGISTRY_PATH),stopServerService:new e,dryRun:t.dryRun});if(t.json){console.log(JSON.stringify({dryRun:t.dryRun,...n},null,2));return}_e(n,t.dryRun)}catch(e){let n=`Error executing cleanup: ${pe(e)}`;t.json?console.log(JSON.stringify({ok:!1,error:n},null,2)):console.error(n),process.exit(1)}});function j(e){return e instanceof Error?e.message:String(e)}async function ye(e,t){try{return(await fetch(`http://${e}:${t}/health`,{signal:AbortSignal.timeout(3e3)})).ok}catch{return!1}}async function be(e,t,n,r,i){let a=t.proxy?.host??`localhost`,o=t.proxy?.port,s=`http://${a}:${o}/mcp`;await ye(a,o)||(r.json||console.error(`Starting HTTP proxy server in background...`),await S({host:a,port:o,config:n,cache:r.useCache!==!1,clearDefinitionsCache:!1,proxyMode:`flat`}));let c=await e.createClientManagerService();try{await c.connectToServer(`proxy`,{name:`proxy`,transport:`http`,config:{url:s}}),r.json||console.error(`✓ Connected to proxy at ${s}`)}catch(e){throw Error(`Failed to connect to proxy server at ${s}: ${j(e)}`)}try{return await i({container:e,configFilePaths:n,config:t,clientManager:c})}finally{await c.disconnectAll()}}async function xe(e,t,n,r,i){let a=await e.createClientManagerService();if(await Promise.all(Object.entries(t.mcpServers).map(async([e,t])=>{try{await a.connectToServer(e,t),r.json||console.error(`✓ Connected to ${e}`)}catch(t){r.json||console.error(`✗ Failed to connect to ${e}: ${j(t)}`)}})),a.getAllClients().length===0)throw Error(`No MCP servers connected`);try{return await i({container:e,configFilePaths:n,config:t,clientManager:a})}finally{await a.disconnectAll()}}async function M(e,t){let r=(e,t)=>{t===void 0?console.error(e):console.error(e,t)},i=e.json?{trace:r,debug:r,info:r,warn:r,error:r}:console,o=g(i),s=a(e.config),c=s.length>0?null:await n(),l=c?[c]:s;if(l.length===0)throw Error(`No config file found. Use --config or create mcp-config.yaml`);let u=await o.createConfigFetcherService({configSources:C(l),useCache:e.useCache}).fetchConfiguration();return u.proxy?.port?await be(o,u,l,e,t):await xe(o,u,l,e,t)}function Se(e){return e instanceof Error?e.message:String(e)}const Ce=new A(`describe-tools`).description(`Describe specific MCP tools`).argument(`<toolNames...>`,`Tool names to describe`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,r).option(`-s, --server <name>`,`Filter by server name`).option(`-j, --json`,`Output as JSON`,!1).action(async(e,t)=>{try{await M(t,async({container:n,config:r,clientManager:i})=>{let a=t.server?[i.getClient(t.server)].filter(e=>e!==void 0):i.getAllClients();if(t.server&&a.length===0)throw Error(`Server "${t.server}" not found`);let o=process.env.PROJECT_PATH||process.cwd(),s=r.skills?.paths||[],c=s.length>0?n.createSkillService(o,s):void 0,l=[],u=[],d=[...e],f=await Promise.all(a.map(async e=>{try{return{client:e,tools:await e.listTools(),error:null}}catch(t){return{client:e,tools:[],error:t}}}));for(let{client:n,tools:r,error:i}of f)if(i)t.json||console.error(`Failed to list tools from ${n.serverName}:`,i);else for(let t of e){let e=r.find(e=>e.name===t);if(e){l.push({server:n.serverName,name:e.name,description:e.description,inputSchema:e.inputSchema});let r=d.indexOf(t);r>-1&&d.splice(r,1)}}if(c&&d.length>0){let e=await Promise.all([...d].map(async e=>{let t=e.startsWith(`skill__`)?e.slice(7):e;return{toolName:e,skill:await c.getSkill(t)}}));for(let{toolName:t,skill:n}of e)if(n){u.push({name:n.name,location:n.basePath,instructions:n.content});let e=d.indexOf(t);e>-1&&d.splice(e,1)}}let p=[];if(l.length>0&&p.push(`For MCP tools: Use the use_tool function with toolName and toolArgs based on the inputSchema above.`),u.length>0&&p.push(`For skill, just follow skill's description to continue.`),t.json){let e={};l.length>0&&(e.tools=l),u.length>0&&(e.skills=u),p.length>0&&(e.nextSteps=p),d.length>0&&(e.notFound=d),console.log(JSON.stringify(e,null,2))}else{if(l.length>0){console.log(`
|
|
3
3
|
Found tools:
|
|
4
4
|
`);for(let e of l)console.log(`Server: ${e.server}`),console.log(`Tool: ${e.name}`),console.log(`Description: ${e.description||`No description`}`),console.log(`Input Schema:`),console.log(JSON.stringify(e.inputSchema,null,2)),console.log(``)}if(u.length>0){console.log(`
|
|
5
5
|
Found skills:
|
|
6
6
|
`);for(let e of u)console.log(`Skill: ${e.name}`),console.log(`Location: ${e.location}`),console.log(`Instructions:\n${e.instructions}`),console.log(``)}if(p.length>0){console.log(`
|
|
7
|
-
Next steps:`);for(let e of p)console.log(` • ${e}`);console.log(``)}d.length>0&&console.error(`\nTools/skills not found: ${d.join(`, `)}`),l.length===0&&u.length===0&&(console.error(`No tools or skills found`),process.exit(1))}})}catch(e){console.error(`Error executing describe-tools: ${Se(e)}`),process.exit(1)}});function N(e){return e instanceof Error?e.message:String(e)}const we=new A(`get-prompt`).description(`Get a prompt by name from a connected MCP server`).argument(`<promptName>`,`Prompt name to fetch`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,
|
|
7
|
+
Next steps:`);for(let e of p)console.log(` • ${e}`);console.log(``)}d.length>0&&console.error(`\nTools/skills not found: ${d.join(`, `)}`),l.length===0&&u.length===0&&(console.error(`No tools or skills found`),process.exit(1))}})}catch(e){console.error(`Error executing describe-tools: ${Se(e)}`),process.exit(1)}});function N(e){return e instanceof Error?e.message:String(e)}const we=new A(`get-prompt`).description(`Get a prompt by name from a connected MCP server`).argument(`<promptName>`,`Prompt name to fetch`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,r).option(`-s, --server <name>`,`Server name (required if prompt exists on multiple servers)`).option(`-a, --args <json>`,`Prompt arguments as JSON string`,`{}`).option(`-j, --json`,`Output as JSON`,!1).action(async(e,t)=>{try{let n={};try{n=JSON.parse(t.args)}catch{throw Error(`Invalid JSON in --args`)}await M(t,async({clientManager:r})=>{let i=r.getAllClients();if(t.server){let i=r.getClient(t.server);if(!i)throw Error(`Server "${t.server}" not found`);let a=await i.getPrompt(e,n);if(t.json)console.log(JSON.stringify(a,null,2));else for(let e of a.messages){let t=e.content;typeof t==`object`&&t&&`text`in t?console.log(t.text):console.log(JSON.stringify(e,null,2))}return}let a=[];if(await Promise.all(i.map(async n=>{try{(await n.listPrompts()).some(t=>t.name===e)&&a.push(n.serverName)}catch(e){t.json||console.error(`Failed to list prompts from ${n.serverName}: ${N(e)}`)}})),a.length===0)throw Error(`Prompt "${e}" not found on any connected server`);if(a.length>1)throw Error(`Prompt "${e}" found on multiple servers: ${a.join(`, `)}. Use --server to disambiguate`);let o=r.getClient(a[0]);if(!o)throw Error(`Internal error: Server "${a[0]}" not connected`);let s=await o.getPrompt(e,n);if(t.json)console.log(JSON.stringify(s,null,2));else for(let e of s.messages){let t=e.content;typeof t==`object`&&t&&`text`in t?console.log(t.text):console.log(JSON.stringify(e,null,2))}})}catch(e){console.error(`Error executing get-prompt: ${N(e)}`),process.exit(1)}});var Te=`{
|
|
8
8
|
"_comment": "MCP Server Configuration - Use \${VAR_NAME} syntax for environment variable interpolation",
|
|
9
9
|
"_instructions": "config.instruction: Server's default instruction | instruction: User override (takes precedence)",
|
|
10
10
|
"mcpServers": {
|
|
@@ -138,9 +138,9 @@ mcpServers:
|
|
|
138
138
|
# # omitToolDescription: true
|
|
139
139
|
# # instruction: Optional user override
|
|
140
140
|
{% endif %}
|
|
141
|
-
`;function P(e=``){console.log(e)}function F(e,t){console.error(t?`${e} ${t}`:e)}const I={info:e=>P(e),error:(e,t)=>F(e,t)},L={info:e=>P(e),warning:e=>P(`Warning: ${e}`),error:e=>F(e),success:e=>P(e),newline:()=>P(),header:e=>P(e),item:e=>P(`- ${e}`),indent:e=>P(` ${e}`)},De=new A(`init`).description(`Initialize MCP configuration file`).option(`-o, --output <path>`,`Output file path`,`mcp-config.yaml`).option(`--json`,`Generate JSON config instead of YAML`,!1).option(`-f, --force`,`Overwrite existing config file`,!1).option(`--mcp-servers <json>`,`JSON string of MCP servers to add to config (optional)`).action(async e=>{try{let t=O(e.output),n=!e.json&&(t.endsWith(`.yaml`)||t.endsWith(`.yml`)),r;if(n){let t=new ue,n=null;if(e.mcpServers)try{let t=JSON.parse(e.mcpServers);n=Object.entries(t).map(([e,t])=>({name:e,command:t.command,args:t.args}))}catch(e){I.error(`Failed to parse --mcp-servers JSON:`,e instanceof Error?e.message:String(e)),process.exit(1)}r=await t.parseAndRender(Ee,{mcpServers:n})}else r=Te;try{await te(t,r,{encoding:`utf-8`,flag:e.force?`w`:`wx`})}catch(e){throw e&&typeof e==`object`&&`code`in e&&e.code===`EEXIST`&&(I.error(`Config file already exists: ${t}`),I.info(`Use --force to overwrite`),process.exit(1)),e}I.info(`MCP configuration file created: ${t}`),I.info(`Next steps:`),I.info(`1. Edit the configuration file to add your MCP servers`),I.info(`2. Run: po-mcp-proxy mcp-serve --config ${t}`)}catch(e){I.error(`Error executing init:`,e instanceof Error?e.message:String(e)),process.exit(1)}});function R(e){return e instanceof Error?e.message:String(e)}const Oe=new A(`list-prompts`).description(`List all available prompts from connected MCP servers`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,t).option(`-s, --server <name>`,`Filter by server name`).option(`-j, --json`,`Output as JSON`,!1).action(async e=>{try{await M(e,async({clientManager:t})=>{let n=e.server?[t.getClient(e.server)].filter(e=>e!==void 0):t.getAllClients();if(e.server&&n.length===0)throw Error(`Server "${e.server}" not found`);let r={};if(await Promise.all(n.map(async t=>{try{r[t.serverName]=await t.listPrompts()}catch(n){r[t.serverName]=[],e.json||console.error(`Failed to list prompts from ${t.serverName}: ${R(n)}`)}})),e.json)console.log(JSON.stringify(r,null,2));else for(let[e,t]of Object.entries(r))if(console.log(`\n${e}:`),t.length===0)console.log(` No prompts available`);else for(let e of t)if(console.log(` - ${e.name}: ${e.description||`No description`}`),e.arguments&&e.arguments.length>0){let t=e.arguments.map(e=>`${e.name}${e.required?` (required)`:``}`).join(`, `);console.log(` args: ${t}`)}})}catch(e){console.error(`Error executing list-prompts: ${R(e)}`),process.exit(1)}});function ke(e){return e instanceof Error?e.message:String(e)}const Ae=new A(`list-resources`).description(`List all available resources from connected MCP servers`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,t).option(`-s, --server <name>`,`Filter by server name`).option(`-j, --json`,`Output as JSON`,!1).action(async e=>{try{await M(e,async({clientManager:t})=>{let n=e.server?[t.getClient(e.server)].filter(e=>e!==void 0):t.getAllClients();if(e.server&&n.length===0)throw Error(`Server "${e.server}" not found`);let r={},i=await Promise.all(n.map(async e=>{try{let t=await e.listResources();return{serverName:e.serverName,resources:t,error:null}}catch(t){return{serverName:e.serverName,resources:[],error:t}}}));for(let{serverName:t,resources:n,error:a}of i)a&&!e.json&&console.error(`Failed to list resources from ${t}: ${ke(a)}`),r[t]=n;if(e.json)console.log(JSON.stringify(r,null,2));else for(let[e,t]of Object.entries(r))if(console.log(`\n${e}:`),t.length===0)console.log(` No resources available`);else for(let e of t){let t=e.name?`${e.name} (${e.uri})`:e.uri;console.log(` - ${t}${e.description?`: ${e.description}`:``}`)}})}catch(e){console.error(`Error executing list-resources: ${ke(e)}`),process.exit(1)}});function je(e){return e instanceof Error?e.message:String(e)}function Me(e){for(let t of e.servers)if(console.log(`\n${t.server}:`),t.capabilities&&t.capabilities.length>0&&console.log(` capabilities: ${t.capabilities.join(`, `)}`),t.summary&&console.log(` summary: ${t.summary}`),t.tools.length===0)console.log(` no tools`);else for(let e of t.tools){let t=e.capabilities&&e.capabilities.length>0?` [${e.capabilities.join(`, `)}]`:``;console.log(` - ${e.name}${t}`),e.description&&console.log(` ${e.description}`)}}const Ne=new A(`search-tools`).description(`Search proxied MCP tools by capability or server`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,t).option(`-s, --server <name>`,`Filter by server name`).option(`--capability <name>`,`Filter by capability tag, summary, tool name, or description`).option(`--definitions-cache <path>`,`Path to definitions cache file`).option(`-j, --json`,`Output as JSON`,!1).action(async e=>{try{await M(e,async({container:t,config:n,clientManager:r,configFilePaths:i})=>{r.registerServerConfigs(n.mcpServers);let a=e.definitionsCache||h.getDefaultCachePath(i),o;try{o=await h.readFromFile(a)}catch{o=void 0}let s=t.createDefinitionsCacheService(r,void 0,{cacheData:o}),c=(await t.createSearchListToolsTool(r,s).execute({capability:e.capability,serverName:e.server})).content.find(e=>e.type===`text`),l=c?.type===`text`?JSON.parse(c.text):{servers:[]};if(e.json)console.log(JSON.stringify(l,null,2));else{if(!l.servers||l.servers.length===0)throw Error(`No tools matched the requested filters`);Me(l)}})}catch(e){console.error(`Error executing search-tools: ${je(e)}`),process.exit(1)}}),Pe=[`mcp-config.yaml`,`mcp-config.yml`,`mcp-config.json`],z=`/mcp`,B=`localhost`,V=`stdio`,H=`http`,U=`stdio-http`,W=`mcp-proxy-http`,Fe=`service`;async function Ie(){return f()}const G=`mcp-proxy-stdio-http-bridge`,K=`stdio-http-managed`,q=`manual`,Le=`MCP_PROXY_IDLE_SHUTDOWN_MINUTES`;async function J(){return Ie()}function Y(e){return e instanceof Error?e.message:String(e)}function Re(e){let t=process.env[Le],n=e??(t?Number.parseFloat(t):void 0);return n===void 0||!Number.isFinite(n)||n<=0?0:Math.round(n*6e4)}function ze(e){return e===V||e===H||e===U}function Be(e){return e===`meta`||e===`flat`||e===`search`||e===`group`}async function Ve(e){try{return await w(e,de.F_OK),!0}catch{return!1}}async function He(){try{let e=process.env.PROJECT_PATH;if(e)for(let t of Pe){let n=O(e,t);if(await Ve(n))return n}let t=process.cwd();for(let e=0;e<=3;e++){for(let e of Pe){let n=D(t,e);if(await Ve(n))return n}let e=E(t);if(e===t)break;t=e}return null}catch(e){throw Error(`Failed to discover MCP config file: ${Y(e)}`)}}async function Ue(e){try{let t=await T(e,`utf-8`),n=(e.endsWith(`.yaml`)||e.endsWith(`.yml`)?se.load(t):JSON.parse(t))?.proxy;if(!n||typeof n!=`object`)return{};let r=n;return{type:typeof r.type==`string`?r.type:void 0,port:typeof r.port==`number`&&Number.isInteger(r.port)&&r.port>0?r.port:void 0,host:typeof r.host==`string`?r.host:void 0,keepAlive:typeof r.keepAlive==`boolean`?r.keepAlive:void 0}}catch{return{}}}async function We(e){let t={};for(let n of e){let e=await Ue(n);e.type!==void 0&&(t.type=e.type),e.port!==void 0&&(t.port=e.port),e.host!==void 0&&(t.host=e.host),e.keepAlive!==void 0&&(t.keepAlive=e.keepAlive)}return t}async function Ge(e,t){let n=v();if(e.id)return e.id;if(t.length>0)try{let i=await n.createConfigFetcherService({configSources:r(t),useCache:e.cache!==!1}).fetchConfiguration(e.cache===!1);if(i.id)return i.id}catch(e){throw Error(`Failed to resolve server ID from config '${t.join(`, `)}': ${Y(e)}`)}return a()}function Ke(e){if(!ze(e))throw Error(`Unknown transport type: '${e}'. Valid options: ${V}, ${H}, ${U}`);return e}function qe(e){if(!Be(e))throw Error(`Unknown proxy mode: '${String(e)}'. Valid options: meta, flat, search, group`)}function Je(e){return e===K?K:q}function Ye(e,t,n){let r=process.env.MCP_PORT?Number(process.env.MCP_PORT):void 0;return{mode:t,port:e.port??(Number.isFinite(r)?r:void 0)??n?.port,host:e.host??process.env.MCP_HOST??n?.host??B}}function Xe(){let e=(e,t)=>{t===void 0?console.error(e):console.error(e,t)};return{trace:e,debug:e,info:e,warn:e,error:e}}function Ze(e,t,n){return{configFilePath:t.length>0?t:void 0,noCache:e.cache===!1,serverId:n,definitionsCachePath:e.definitionsCache,clearDefinitionsCache:e.clearDefinitionsCache,proxyMode:e.proxyMode}}function Qe(e,t,n,r){let i=Y(r);return e===V?`Failed to start MCP server with transport '${e}': ${i}`:`Failed to start MCP server with transport '${e}' on ${n===void 0?`${t} (dynamic port)`:`${t}:${n}`}: ${i}`}function $e(e,t,n,r,i,a=q){return{serverId:e,host:t.host??B,port:n,transport:`http`,shutdownToken:r,startedAt:(/* @__PURE__ */ new Date()).toISOString(),pid:process.pid,configPath:i,runtimeLifecycle:a}}function et(){return new le(process.env.PORT_REGISTRY_PATH)}function X(){return process.env.NODE_ENV??`development`}async function tt(e,t,n,r,i,a,o=n===void 0?ce:{min:n,max:n}){let s=et(),c=await s.reservePort({repositoryPath:await J(),serviceName:e,serviceType:Fe,environment:X(),pid:process.pid,host:t,preferredPort:n,portRange:o,force:!0,metadata:{transport:i,serverId:r,...a?{configPath:a}:{}}});if(!c.success||!c.record){let e=n===void 0?`dynamic port`:`port ${n}`;throw Error(c.error||`Failed to reserve ${e} in port registry`)}let l=!1;return{port:c.record.port,release:async()=>{if(l)return;l=!0;let t=await s.releasePort({repositoryPath:await J(),serviceName:e,serviceType:Fe,pid:process.pid,environment:X(),force:!0});if(!t.success&&t.error&&!t.error.includes(`No matching registry entry`))throw Error(t.error||`Failed to release port for ${e}`)}}}async function nt(e){e&&await e.release()}function rt(e,t,n,r,i){return{serverId:e,shutdownToken:t,onShutdownRequested:n,runtimeLifecycle:r,idleShutdownMs:i}}async function Z(e,t){try{await e.remove(t)}catch(e){throw Error(`Failed to remove runtime state for '${t}': ${Y(e)}`)}}async function it(e,t){try{await e.write(t)}catch(e){throw Error(`Failed to persist runtime state for '${t.serverId}': ${Y(e)}`)}}async function at(e,t,n,r){try{try{await e.stop()}catch(e){throw Error(`Failed to stop owned HTTP transport '${n}': ${Y(e)}`)}}finally{await r?.release({kill:!1}),await Z(t,n)}}async function ot(e,t,n){await n?.release({kill:!1}),await Z(e,t)}async function st(e,t,n,r){try{try{await e.stop()}catch(e){throw Error(`Failed to stop HTTP transport during cleanup for '${n}': ${Y(e)}`)}}finally{await r?.release({kill:!1}),await Z(t,n)}}async function Q(e,t,n={}){try{await e.start()}catch(e){throw Error(`Failed to start transport handler: ${Y(e)}`)}let r=!1,i=async n=>{if(!r){r=!0,console.error(`\nReceived ${n}, shutting down gracefully...`);try{await e.stop(),t&&await t(),process.exit(0)}catch(e){console.error(`Failed to gracefully stop transport during ${n}: ${Y(e)}`),process.exit(1)}}};process.on(`SIGINT`,async()=>await i(`SIGINT`)),process.on(`SIGTERM`,async()=>await i(`SIGTERM`)),n.shutdownOnStdinClose&&(process.stdin.on(`end`,async()=>await i(`stdin end`)),process.stdin.on(`close`,async()=>await i(`stdin close`)))}async function ct(e,t,n,r){i();let o=n[0],l=await g(e),u=new c,d=re(),f=e.serverId??a(),p=Je(process.env.MCP_PROXY_RUNTIME_LIFECYCLE),m=t.port,h=m===void 0?ce:{min:m,max:m},_=await tt(W,t.host??B,m,f,H,o,h),v=_.port,b={...t,port:v},x=await ie({repositoryPath:await J(),serviceName:`mcp-proxy-http`,serviceType:`service`,environment:X(),host:b.host??B,port:v,command:process.argv[1],args:process.argv.slice(2),...ee()?{processGroupId:process.pid,terminationMode:`process-group`}:{terminationMode:`direct`},metadata:{transport:H,serverId:f,runtimeLifecycle:p,...o?{configPath:o}:{}}}),S=async()=>{await nt(_??null),S=async()=>void 0},C=$e(f,b,v,d,o,p),w,T=!1,te=async()=>{if(!T){T=!0;try{await at(w,u,C.serverId,x),await S(),await l.dispose(),process.exit(0)}catch(e){throw Error(`Failed to stop HTTP runtime '${C.serverId}' from admin shutdown: ${Y(e)}`)}}};try{let e=rt(C.serverId,d,te,p,r);w=new s(()=>y(l),b,e)}catch(e){throw await S(),await x.release({kill:!1}),await l.dispose(),Error(`Failed to create HTTP runtime server: ${Y(e)}`)}try{await Q(w,async()=>{await S(),await l.dispose(),await ot(u,C.serverId,x)}),await it(u,C)}catch(e){throw await S(),await l.dispose(),await st(w,u,C.serverId,x),Error(`Failed to start HTTP runtime '${C.serverId}': ${Y(e)}`)}console.error(`Runtime state: http://${C.host}:${C.port} (${C.serverId})`)}async function lt(e){let t;try{t=await _(e),await Q(new d(t,Xe()),async()=>{await t?.dispose?.()},{shutdownOnStdinClose:!0})}catch(e){throw await t?.dispose?.(),Error(`Failed to start stdio transport: ${Y(e)}`)}}async function ut(e){if(e)try{return(await new c().read(e))?.runtimeLifecycle}catch{return}}function dt(e){if(!e)return p;let t=Number.parseInt(e,10);return Number.isInteger(t)&&t>0?t:p}function ft(e,t){let n=k.resolveRegistryPath(process.env.PROCESS_REGISTRY_PATH),r=ne(`sha1`).update(`${ae(e)}|${t}`).digest(`hex`);return D(E(n),`mcp-proxy-runtime-${r.slice(0,16)}.lock`)}async function pt(e,t,n){if(e.port!==void 0)return{endpoint:new URL(`http://${e.host??B}:${e.port}${z}`),runtimeLifecycle:q};let r=await J(),i=dt(t.timeoutMs)+1e4;return await oe(ft(r,W),async()=>mt(r,e,t,n),{staleAfterMs:i,retryDelayMs:250,maxRetries:Math.ceil(i/250)})}async function mt(e,t,n,r){let i=await l(e);if(i){let e=t.host??i.host,n=i.serverId===`unknown`?void 0:i.serverId;return{endpoint:new URL(`http://${e}:${i.port}${z}`),runtimeServerId:n,runtimeLifecycle:i.runtimeLifecycle??await ut(n)??q}}let a=await C({host:t.host??B,config:r,cache:n.cache,definitionsCache:n.definitionsCache,clearDefinitionsCache:n.clearDefinitionsCache,proxyMode:n.proxyMode,runtimeLifecycle:K,idleShutdownMinutes:n.idleShutdownMinutes});return{endpoint:new URL(`http://${a.host}:${a.port}${z}`),runtimeServerId:a.serverId,runtimeLifecycle:a.runtimeLifecycle??q}}async function ht(e,t,n){let{endpoint:r}=await pt(e,t,n);return r}function gt(e){return`runtime:${e}`}async function _t(e){if(e.runtimeLifecycle===K&&e.runtimeServerId)return await ie({repositoryPath:await J(),serviceName:`mcp-proxy-stdio-http-bridge:${re()}`,serviceType:`tool`,environment:X(),pid:process.pid,command:process.argv[1],args:process.argv.slice(2),tags:[G,gt(e.runtimeServerId)],metadata:{transport:U,runtimeServerId:e.runtimeServerId,runtimeLifecycle:e.runtimeLifecycle,endpoint:e.endpoint.toString()},force:!1})}function vt(e){return e.pid===process.pid}async function yt(e){return await new k(process.env.PROCESS_REGISTRY_PATH).listProcesses({repositoryPath:await J(),serviceType:`tool`,tags:[G,gt(e)],environment:X(),liveOnly:!0})}async function bt(e){return(await yt(e)).filter(e=>!vt(e)).length>0?!1:(await new Promise(e=>setTimeout(e,500)),(await yt(e)).filter(e=>!vt(e)).length===0)}async function xt(t){if(t.runtimeLifecycle!==K||!t.runtimeServerId)return;let n=t.runtimeServerId,r=ft(await J(),W);try{await oe(r,async()=>{await bt(n)&&await new e().stop({serverId:n,force:!0})})}catch(e){console.error(`Failed to stop managed stdio-http runtime; leaving it alive: ${Y(e)}`)}}async function St(e,t,n,r){let i=t.autoDisconnect?!0:r?.keepAlive!==void 0&&!r.keepAlive,a,o;try{a=await pt(e,t,n),o=await _t(a);let{endpoint:r}=a;await Q(new x({endpoint:r,resolveEndpoint:async()=>await ht(e,t,n)},Xe()),async()=>{try{await o?.release({kill:!1,releasePort:!1})}catch(e){console.error(`Failed to release stdio-http bridge lease; leaving runtime alive: ${Y(e)}`);return}i&&a&&await xt(a)},{shutdownOnStdinClose:!0})}catch(e){try{await o?.release({kill:!1,releasePort:!1})}catch(t){throw Error(`Failed to start stdio-http transport: ${Y(e)}; also failed to release bridge lease: ${Y(t)}`)}throw Error(`Failed to start stdio-http transport: ${Y(e)}`)}}async function Ct(e,t,n,r,i){try{if(e===V){await lt(r);return}if(e===H){await ct(r,Ye(t,b.HTTP,i),n,Re(t.idleShutdownMinutes));return}await St(Ye(t,b.HTTP,i),t,n,i)}catch(t){throw Error(`Failed to start transport '${e}': ${Y(t)}`)}}async function wt(e,t){try{let n=await C({id:e.id,host:e.host??B,port:e.port,config:t,cache:e.cache,definitionsCache:e.definitionsCache,clearDefinitionsCache:e.clearDefinitionsCache,proxyMode:e.proxyMode,timeoutMs:e.timeoutMs,idleShutdownMinutes:e.idleShutdownMinutes});S(n)}catch(t){console.error(`Failed to prestart HTTP runtime '${e.id||`generated-server-id`}': ${Y(t)}`),process.exit(1)}}const Tt=new A(`mcp-serve`).description(`Start MCP server with specified transport or prestart the HTTP runtime in the background`).option(`-t, --type <type>`,`Transport type: ${V}, ${H}, or ${U}`).option(`-p, --port <port>`,`Port to listen on (http) or backend port for stdio-http`,e=>Number.parseInt(e,10)).option(`--host <host>`,`Host to bind to (http) or backend host for stdio-http`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,t).option(`--no-cache`,`Disable configuration caching, always reload from config file`).option(`--definitions-cache <path>`,`Path to prefetched tool/prompt/skill definitions cache file`).option(`--clear-definitions-cache`,`Delete definitions cache before startup`,!1).option(`--proxy-mode <mode>`,`How mcp-proxy exposes downstream tools: meta, flat, search, or group`,`meta`).option(`--id <id>`,`Unique server identifier (overrides config file id, auto-generated if not provided)`).option(`--auto-disconnect`,`Stop the managed HTTP runtime when the last stdio-http bridge exits (default: keep runtime alive for reuse)`,!1).option(`--idle-shutdown-minutes <minutes>`,`Stop the HTTP runtime after N minutes with no MCP session and no request (0 disables; overrides ${Le})`,e=>Number.parseFloat(e)).option(`--prestart-http`,`Prestart the HTTP runtime in the background and exit after it becomes healthy`,!1).option(`--timeout-ms <ms>`,`How long to wait for the HTTP runtime to become healthy`,String(p)).action(async e=>{try{let t=n(e.config),r=t.length>0?null:await He(),i=r?[r]:t;if(e.prestartHttp){await wt(e,i);return}let a=await We(i),o=Ke((e.type??a.type??V).toLowerCase());qe(e.proxyMode),await Ct(o,e,i,Ze(e,i,await Ge(e,i)),a)}catch(t){let n=(e.type??V).toLowerCase(),r=ze(n)?n:V,i=process.env.MCP_PORT?Number(process.env.MCP_PORT):void 0,a=e.port??(Number.isFinite(i)?i:void 0);console.error(Qe(r,e.host??B,a,t)),process.exit(1)}}),Et=new A(`prefetch`).description(`Pre-download packages used by MCP servers (npx, pnpx, uvx, uv)`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,t).option(`-p, --parallel`,`Run prefetch commands in parallel`,!1).option(`-d, --dry-run`,`Show what would be prefetched without executing`,!1).option(`-f, --filter <type>`,`Filter by package manager type: npx, pnpx, uvx, or uv`).option(`--definitions-out <path>`,`Write discovered definitions to a JSON or YAML cache file`).option(`--skip-packages`,`Skip package prefetch and only build definitions cache`,!1).option(`--clear-definitions-cache`,`Delete the definitions cache file before continuing`,!1).action(async e=>{try{let t=v(),i=n(e.config),s=i.length>0?null:await o(),c=s?[s]:i;c.length===0&&(L.error(`No MCP configuration file found.`),L.info(`Use --config <path> to specify a config file, or run "po-mcp-proxy init" to create one.`),process.exit(1)),L.info(`Loading configuration from: ${c.join(`, `)}`);let l=await t.createConfigFetcherService({configSources:r(c),useCache:!1}).fetchConfiguration(!0),u=l.id||a(),d=h.generateConfigHash(l),f=e.definitionsOut||h.getDefaultCachePath(c),p=t.createPrefetchService({mcpConfig:l,filter:e.filter,parallel:e.parallel}),g=p.extractPackages(),_=!e.skipPackages,y=!!e.definitionsOut;if(e.clearDefinitionsCache&&(e.dryRun?L.info(`Would clear definitions cache: ${f}`):(await h.clearFile(f),L.success(`Cleared definitions cache: ${f}`))),_){if(g.length===0)L.warning(`No packages found to prefetch.`),L.info(`Prefetch supports: npx, pnpx, uvx, and uv run commands`);else{L.info(`Found ${g.length} package(s) to prefetch:`);for(let e of g)L.item(`${e.serverName}: ${e.packageManager} ${e.packageName}`)}}if(!_&&!y){L.warning(`Nothing to do. Use package prefetch or provide --definitions-out.`);return}if(e.dryRun){if(_&&g.length>0){L.newline(),L.header(`Dry run mode - commands that would be executed:`);for(let e of g)L.indent(e.fullCommand.join(` `))}y&&(L.newline(),L.info(`Would write definitions cache to: ${f}`));return}let b=!1;if(_&&g.length>0){L.newline(),L.info(`Prefetching packages...`);let e=await p.prefetch();if(L.newline(),e.failed===0?L.success(`Package prefetch complete: ${e.successful} succeeded, ${e.failed} failed`):L.warning(`Package prefetch complete: ${e.successful} succeeded, ${e.failed} failed`),e.failed>0){b=!0,L.newline(),L.error(`Failed packages:`);for(let t of e.results.filter(e=>!e.success))L.item(`${t.package.serverName} (${t.package.packageName}): ${t.output.trim()}`)}}if(y){L.newline(),L.info(`Collecting definitions cache...`);let e=await t.createClientManagerService(),n=l.skills?.paths||[],r=n.length>0?t.createSkillService(process.cwd(),n):void 0,i=t.createDefinitionsCacheService(e,r);await Promise.all(Object.entries(l.mcpServers).map(async([t,n])=>{try{await e.connectToServer(t,n),L.item(`Connected for definitions: ${t}`)}catch(e){L.warning(`Failed to connect for definitions: ${t} (${e instanceof Error?e.message:String(e)})`)}}));let a=await i.collectForCache({configPath:c[0],configHash:d,oneMcpVersion:m,serverId:u});await h.writeToFile(f,a),L.success(`Definitions cache written: ${f} (${Object.keys(a.servers).length} servers, ${a.skills.length} skills)`),a.failures.length>0&&L.warning(`Definitions cache completed with ${a.failures.length} server failure(s)`),await e.disconnectAll()}b&&process.exit(1)}catch(e){L.error(`Error executing prefetch: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});function $(e){return e instanceof Error?e.message:String(e)}const Dt=new A(`read-resource`).description(`Read a resource by URI from a connected MCP server`).argument(`<uri>`,`Resource URI to read`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,t).option(`-s, --server <name>`,`Server name (required if resource exists on multiple servers)`).option(`-j, --json`,`Output as JSON`,!1).action(async(e,t)=>{try{await M(t,async({clientManager:n})=>{let r=n.getAllClients();if(t.server){let r=n.getClient(t.server);if(!r)throw Error(`Server "${t.server}" not found`);t.json||console.error(`Reading ${e} from ${t.server}...`);let i=await r.readResource(e);if(t.json)console.log(JSON.stringify(i,null,2));else for(let e of i.contents)`text`in e?console.log(e.text):console.log(JSON.stringify(e,null,2));return}let i=await Promise.all(r.map(async t=>{try{let n=(await t.listResources()).some(t=>t.uri===e);return{serverName:t.serverName,hasResource:n,error:null}}catch(e){return{serverName:t.serverName,hasResource:!1,error:e}}})),a=[];for(let{serverName:e,hasResource:t,error:n}of i)n?console.error(`Failed to list resources from ${e}: ${$(n)}`):t&&a.push(e);if(a.length===0)throw Error(`Resource "${e}" not found on any connected server`);if(a.length>1)throw Error(`Resource "${e}" found on multiple servers: ${a.join(`, `)}. Use --server to disambiguate`);let o=a[0],s=n.getClient(o);if(!s)throw Error(`Internal error: Server "${o}" not connected`);t.json||console.error(`Reading ${e} from ${o}...`);let c=await s.readResource(e);if(t.json)console.log(JSON.stringify(c,null,2));else for(let e of c.contents)`text`in e?console.log(e.text):console.log(JSON.stringify(e,null,2))})}catch(e){console.error(`Error executing read-resource: ${$(e)}`),process.exit(1)}});function Ot(e){return e instanceof Error?e.message:String(e)}function kt(e){console.log(`Stopped mcp-proxy server '${e.serverId}'.`),console.log(`Endpoint: http://${e.host}:${e.port}`),console.log(`Result: ${e.message}`)}const At=new A(`stop`).description(`Stop a running HTTP mcp-proxy server`).option(`--id <id>`,`Target server ID from the runtime registry`).option(`--host <host>`,`Target runtime host`).option(`--port <port>`,`Target runtime port`,e=>Number.parseInt(e,10)).option(`-c, --config <path>`,`Reserved for future config-based targeting support`).option(`--token <token>`,`Override the persisted shutdown token`).option(`--force`,`Skip server ID verification against the /health response`,!1).option(`-j, --json`,`Output as JSON`,!1).option(`--timeout <ms>`,`Maximum time to wait for shutdown completion`,e=>Number.parseInt(e,10),5e3).action(async e=>{try{e.config&&console.error(`Warning: --config is not used yet; runtime resolution uses the persisted registry.`);let t=await v().createStopServerService().stop({serverId:e.id,host:e.host,port:e.port,token:e.token,force:e.force,timeoutMs:e.timeout});if(e.json){console.log(JSON.stringify(t,null,2));return}kt(t)}catch(t){let n=`Error executing stop: ${Ot(t)}`;e.json?console.log(JSON.stringify({ok:!1,error:n},null,2)):console.error(n),process.exit(1)}});function jt(e){return e instanceof Error?e.message:String(e)}const Mt=new A(`use-tool`).description(`Execute an MCP tool with arguments`).argument(`<toolName>`,`Tool name to execute`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,t).option(`-s, --server <name>`,`Server name (required if tool exists on multiple servers)`).option(`-a, --args <json>`,`Tool arguments as JSON string`,`{}`).option(`-t, --timeout <ms>`,`Request timeout in milliseconds for tool execution (default: 60000)`,Number.parseInt).option(`-j, --json`,`Output as JSON`,!1).action(async(e,t)=>{try{let n={};try{n=JSON.parse(t.args)}catch{console.error(`Error: Invalid JSON in --args`),process.exit(1)}await M(t,async({container:r,config:i,clientManager:a})=>{let o=a.getAllClients();if(t.server){let r=a.getClient(t.server);if(!r)throw Error(`Server "${t.server}" not found`);t.json||console.error(`Executing ${e} on ${t.server}...`);let i=t.timeout?{timeout:t.timeout}:void 0,o=await r.callTool(e,n,i);if(t.json)console.log(JSON.stringify(o,null,2));else{if(console.log(`
|
|
141
|
+
`;function P(e=``){console.log(e)}function F(e,t){console.error(t?`${e} ${t}`:e)}const I={info:e=>P(e),error:(e,t)=>F(e,t)},L={info:e=>P(e),warning:e=>P(`Warning: ${e}`),error:e=>F(e),success:e=>P(e),newline:()=>P(),header:e=>P(e),item:e=>P(`- ${e}`),indent:e=>P(` ${e}`)},De=new A(`init`).description(`Initialize MCP configuration file`).option(`-o, --output <path>`,`Output file path`,`mcp-config.yaml`).option(`--json`,`Generate JSON config instead of YAML`,!1).option(`-f, --force`,`Overwrite existing config file`,!1).option(`--mcp-servers <json>`,`JSON string of MCP servers to add to config (optional)`).action(async e=>{try{let t=O(e.output),n=!e.json&&(t.endsWith(`.yaml`)||t.endsWith(`.yml`)),r;if(n){let t=new ue,n=null;if(e.mcpServers)try{let t=JSON.parse(e.mcpServers);n=Object.entries(t).map(([e,t])=>({name:e,command:t.command,args:t.args}))}catch(e){I.error(`Failed to parse --mcp-servers JSON:`,e instanceof Error?e.message:String(e)),process.exit(1)}r=await t.parseAndRender(Ee,{mcpServers:n})}else r=Te;try{await te(t,r,{encoding:`utf-8`,flag:e.force?`w`:`wx`})}catch(e){throw e&&typeof e==`object`&&`code`in e&&e.code===`EEXIST`&&(I.error(`Config file already exists: ${t}`),I.info(`Use --force to overwrite`),process.exit(1)),e}I.info(`MCP configuration file created: ${t}`),I.info(`Next steps:`),I.info(`1. Edit the configuration file to add your MCP servers`),I.info(`2. Run: po-mcp-proxy mcp-serve --config ${t}`)}catch(e){I.error(`Error executing init:`,e instanceof Error?e.message:String(e)),process.exit(1)}});function R(e){return e instanceof Error?e.message:String(e)}const Oe=new A(`list-prompts`).description(`List all available prompts from connected MCP servers`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,r).option(`-s, --server <name>`,`Filter by server name`).option(`-j, --json`,`Output as JSON`,!1).action(async e=>{try{await M(e,async({clientManager:t})=>{let n=e.server?[t.getClient(e.server)].filter(e=>e!==void 0):t.getAllClients();if(e.server&&n.length===0)throw Error(`Server "${e.server}" not found`);let r={};if(await Promise.all(n.map(async t=>{try{r[t.serverName]=await t.listPrompts()}catch(n){r[t.serverName]=[],e.json||console.error(`Failed to list prompts from ${t.serverName}: ${R(n)}`)}})),e.json)console.log(JSON.stringify(r,null,2));else for(let[e,t]of Object.entries(r))if(console.log(`\n${e}:`),t.length===0)console.log(` No prompts available`);else for(let e of t)if(console.log(` - ${e.name}: ${e.description||`No description`}`),e.arguments&&e.arguments.length>0){let t=e.arguments.map(e=>`${e.name}${e.required?` (required)`:``}`).join(`, `);console.log(` args: ${t}`)}})}catch(e){console.error(`Error executing list-prompts: ${R(e)}`),process.exit(1)}});function ke(e){return e instanceof Error?e.message:String(e)}const Ae=new A(`list-resources`).description(`List all available resources from connected MCP servers`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,r).option(`-s, --server <name>`,`Filter by server name`).option(`-j, --json`,`Output as JSON`,!1).action(async e=>{try{await M(e,async({clientManager:t})=>{let n=e.server?[t.getClient(e.server)].filter(e=>e!==void 0):t.getAllClients();if(e.server&&n.length===0)throw Error(`Server "${e.server}" not found`);let r={},i=await Promise.all(n.map(async e=>{try{let t=await e.listResources();return{serverName:e.serverName,resources:t,error:null}}catch(t){return{serverName:e.serverName,resources:[],error:t}}}));for(let{serverName:t,resources:n,error:a}of i)a&&!e.json&&console.error(`Failed to list resources from ${t}: ${ke(a)}`),r[t]=n;if(e.json)console.log(JSON.stringify(r,null,2));else for(let[e,t]of Object.entries(r))if(console.log(`\n${e}:`),t.length===0)console.log(` No resources available`);else for(let e of t){let t=e.name?`${e.name} (${e.uri})`:e.uri;console.log(` - ${t}${e.description?`: ${e.description}`:``}`)}})}catch(e){console.error(`Error executing list-resources: ${ke(e)}`),process.exit(1)}});function je(e){return e instanceof Error?e.message:String(e)}function Me(e){for(let t of e.servers)if(console.log(`\n${t.server}:`),t.capabilities&&t.capabilities.length>0&&console.log(` capabilities: ${t.capabilities.join(`, `)}`),t.summary&&console.log(` summary: ${t.summary}`),t.tools.length===0)console.log(` no tools`);else for(let e of t.tools){let t=e.capabilities&&e.capabilities.length>0?` [${e.capabilities.join(`, `)}]`:``;console.log(` - ${e.name}${t}`),e.description&&console.log(` ${e.description}`)}}const Ne=new A(`search-tools`).description(`Search proxied MCP tools by capability or server`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,r).option(`-s, --server <name>`,`Filter by server name`).option(`--capability <name>`,`Filter by capability tag, summary, tool name, or description`).option(`--definitions-cache <path>`,`Path to definitions cache file`).option(`-j, --json`,`Output as JSON`,!1).action(async e=>{try{await M(e,async({container:t,config:n,clientManager:r,configFilePaths:i})=>{r.registerServerConfigs(n.mcpServers);let a=e.definitionsCache||p.getDefaultCachePath(i),o;try{o=await p.readFromFile(a)}catch{o=void 0}let s=t.createDefinitionsCacheService(r,void 0,{cacheData:o}),c=(await t.createSearchListToolsTool(r,s).execute({capability:e.capability,serverName:e.server})).content.find(e=>e.type===`text`),l=c?.type===`text`?JSON.parse(c.text):{servers:[]};if(e.json)console.log(JSON.stringify(l,null,2));else{if(!l.servers||l.servers.length===0)throw Error(`No tools matched the requested filters`);Me(l)}})}catch(e){console.error(`Error executing search-tools: ${je(e)}`),process.exit(1)}}),Pe=[`mcp-config.yaml`,`mcp-config.yml`,`mcp-config.json`],z=`/mcp`,B=`localhost`,V=`stdio`,H=`http`,U=`stdio-http`,W=`mcp-proxy-http`,Fe=`service`;async function Ie(){return _()}const G=`mcp-proxy-stdio-http-bridge`,K=`stdio-http-managed`,q=`manual`,Le=`MCP_PROXY_IDLE_SHUTDOWN_MINUTES`;async function J(){return Ie()}function Y(e){return e instanceof Error?e.message:String(e)}function Re(e){let t=process.env[Le],n=e??(t?Number.parseFloat(t):void 0);return n===void 0||!Number.isFinite(n)||n<=0?0:Math.round(n*6e4)}function ze(e){return e===V||e===H||e===U}function Be(e){return e===`meta`||e===`flat`||e===`search`||e===`group`}async function Ve(e){try{return await w(e,de.F_OK),!0}catch{return!1}}async function He(){try{let e=process.env.PROJECT_PATH;if(e)for(let t of Pe){let n=O(e,t);if(await Ve(n))return n}let t=process.cwd();for(let e=0;e<=3;e++){for(let e of Pe){let n=D(t,e);if(await Ve(n))return n}let e=E(t);if(e===t)break;t=e}return null}catch(e){throw Error(`Failed to discover MCP config file: ${Y(e)}`)}}async function Ue(e){try{let t=await T(e,`utf-8`),n=(e.endsWith(`.yaml`)||e.endsWith(`.yml`)?se.load(t):JSON.parse(t))?.proxy;if(!n||typeof n!=`object`)return{};let r=n;return{type:typeof r.type==`string`?r.type:void 0,port:typeof r.port==`number`&&Number.isInteger(r.port)&&r.port>0?r.port:void 0,host:typeof r.host==`string`?r.host:void 0,keepAlive:typeof r.keepAlive==`boolean`?r.keepAlive:void 0}}catch{return{}}}async function We(e){let t={};for(let n of e){let e=await Ue(n);e.type!==void 0&&(t.type=e.type),e.port!==void 0&&(t.port=e.port),e.host!==void 0&&(t.host=e.host),e.keepAlive!==void 0&&(t.keepAlive=e.keepAlive)}return t}async function Ge(e,n){let r=g();if(e.id)return e.id;if(n.length>0)try{let t=await r.createConfigFetcherService({configSources:C(n),useCache:e.cache!==!1}).fetchConfiguration(e.cache===!1);if(t.id)return t.id}catch(e){throw Error(`Failed to resolve server ID from config '${n.join(`, `)}': ${Y(e)}`)}return t()}function Ke(e){if(!ze(e))throw Error(`Unknown transport type: '${e}'. Valid options: ${V}, ${H}, ${U}`);return e}function qe(e){if(!Be(e))throw Error(`Unknown proxy mode: '${String(e)}'. Valid options: meta, flat, search, group`)}function Je(e){return e===K?K:q}function Ye(e,t,n){let r=process.env.MCP_PORT?Number(process.env.MCP_PORT):void 0;return{mode:t,port:e.port??(Number.isFinite(r)?r:void 0)??n?.port,host:e.host??process.env.MCP_HOST??n?.host??B}}function Xe(){let e=(e,t)=>{t===void 0?console.error(e):console.error(e,t)};return{trace:e,debug:e,info:e,warn:e,error:e}}function Ze(e,t,n){return{configFilePath:t.length>0?t:void 0,noCache:e.cache===!1,serverId:n,definitionsCachePath:e.definitionsCache,clearDefinitionsCache:e.clearDefinitionsCache,proxyMode:e.proxyMode}}function Qe(e,t,n,r){let i=Y(r);return e===V?`Failed to start MCP server with transport '${e}': ${i}`:`Failed to start MCP server with transport '${e}' on ${n===void 0?`${t} (dynamic port)`:`${t}:${n}`}: ${i}`}function $e(e,t,n,r,i,a=q){return{serverId:e,host:t.host??B,port:n,transport:`http`,shutdownToken:r,startedAt:(/* @__PURE__ */ new Date()).toISOString(),pid:process.pid,configPath:i,runtimeLifecycle:a}}function et(){return new le(process.env.PORT_REGISTRY_PATH)}function X(){return process.env.NODE_ENV??`development`}async function tt(e,t,n,r,i,a,o=n===void 0?ce:{min:n,max:n}){let s=et(),c=await s.reservePort({repositoryPath:await J(),serviceName:e,serviceType:Fe,environment:X(),pid:process.pid,host:t,preferredPort:n,portRange:o,force:!0,metadata:{transport:i,serverId:r,...a?{configPath:a}:{}}});if(!c.success||!c.record){let e=n===void 0?`dynamic port`:`port ${n}`;throw Error(c.error||`Failed to reserve ${e} in port registry`)}let l=!1;return{port:c.record.port,release:async()=>{if(l)return;l=!0;let t=await s.releasePort({repositoryPath:await J(),serviceName:e,serviceType:Fe,pid:process.pid,environment:X(),force:!0});if(!t.success&&t.error&&!t.error.includes(`No matching registry entry`))throw Error(t.error||`Failed to release port for ${e}`)}}}async function nt(e){e&&await e.release()}function rt(e,t,n,r,i){return{serverId:e,shutdownToken:t,onShutdownRequested:n,runtimeLifecycle:r,idleShutdownMs:i}}async function Z(e,t){try{await e.remove(t)}catch(e){throw Error(`Failed to remove runtime state for '${t}': ${Y(e)}`)}}async function it(e,t){try{await e.write(t)}catch(e){throw Error(`Failed to persist runtime state for '${t.serverId}': ${Y(e)}`)}}async function at(e,t,n,r){try{try{await e.stop()}catch(e){throw Error(`Failed to stop owned HTTP transport '${n}': ${Y(e)}`)}}finally{await r?.release({kill:!1}),await Z(t,n)}}async function ot(e,t,n){await n?.release({kill:!1}),await Z(e,t)}async function st(e,t,n,r){try{try{await e.stop()}catch(e){throw Error(`Failed to stop HTTP transport during cleanup for '${n}': ${Y(e)}`)}}finally{await r?.release({kill:!1}),await Z(t,n)}}async function Q(e,t,n={}){try{await e.start()}catch(e){throw Error(`Failed to start transport handler: ${Y(e)}`)}let r=!1,i=async n=>{if(!r){r=!0,console.error(`\nReceived ${n}, shutting down gracefully...`);try{await e.stop(),t&&await t(),process.exit(0)}catch(e){console.error(`Failed to gracefully stop transport during ${n}: ${Y(e)}`),process.exit(1)}}};process.on(`SIGINT`,async()=>await i(`SIGINT`)),process.on(`SIGTERM`,async()=>await i(`SIGTERM`)),n.shutdownOnStdinClose&&(process.stdin.on(`end`,async()=>await i(`stdin end`)),process.stdin.on(`close`,async()=>await i(`stdin close`)))}async function ct(e,n,r,a){i();let c=r[0],l=await m(e),u=new s,d=re(),f=e.serverId??t(),p=Je(process.env.MCP_PROXY_RUNTIME_LIFECYCLE),h=n.port,g=h===void 0?ce:{min:h,max:h},_=await tt(W,n.host??B,h,f,H,c,g),y=_.port,b={...n,port:y},x=await ie({repositoryPath:await J(),serviceName:`mcp-proxy-http`,serviceType:`service`,environment:X(),host:b.host??B,port:y,command:process.argv[1],args:process.argv.slice(2),...ee()?{processGroupId:process.pid,terminationMode:`process-group`}:{terminationMode:`direct`},metadata:{transport:H,serverId:f,runtimeLifecycle:p,...c?{configPath:c}:{}}}),S=async()=>{await nt(_??null),S=async()=>void 0},C=$e(f,b,y,d,c,p),w,T=!1,te=async()=>{if(!T){T=!0;try{await at(w,u,C.serverId,x),await S(),await l.dispose(),process.exit(0)}catch(e){throw Error(`Failed to stop HTTP runtime '${C.serverId}' from admin shutdown: ${Y(e)}`)}}};try{let e=rt(C.serverId,d,te,p,a);w=new o(()=>v(l),b,e)}catch(e){throw await S(),await x.release({kill:!1}),await l.dispose(),Error(`Failed to create HTTP runtime server: ${Y(e)}`)}try{await Q(w,async()=>{await S(),await l.dispose(),await ot(u,C.serverId,x)}),await it(u,C)}catch(e){throw await S(),await l.dispose(),await st(w,u,C.serverId,x),Error(`Failed to start HTTP runtime '${C.serverId}': ${Y(e)}`)}console.error(`Runtime state: http://${C.host}:${C.port} (${C.serverId})`)}async function lt(e){let t;try{t=await h(e),await Q(new u(t,Xe()),async()=>{await t?.dispose?.()},{shutdownOnStdinClose:!0})}catch(e){throw await t?.dispose?.(),Error(`Failed to start stdio transport: ${Y(e)}`)}}async function ut(e){if(e)try{return(await new s().read(e))?.runtimeLifecycle}catch{return}}function dt(e){if(!e)return d;let t=Number.parseInt(e,10);return Number.isInteger(t)&&t>0?t:d}function ft(e,t){let n=k.resolveRegistryPath(process.env.PROCESS_REGISTRY_PATH),r=ne(`sha1`).update(`${ae(e)}|${t}`).digest(`hex`);return D(E(n),`mcp-proxy-runtime-${r.slice(0,16)}.lock`)}async function pt(e,t,n){if(e.port!==void 0)return{endpoint:new URL(`http://${e.host??B}:${e.port}${z}`),runtimeLifecycle:q};let r=await J(),i=dt(t.timeoutMs)+1e4;return await oe(ft(r,W),async()=>mt(r,e,t,n),{staleAfterMs:i,retryDelayMs:250,maxRetries:Math.ceil(i/250)})}async function mt(e,t,n,r){let i=await c(e);if(i){let e=t.host??i.host,n=i.serverId===`unknown`?void 0:i.serverId;return{endpoint:new URL(`http://${e}:${i.port}${z}`),runtimeServerId:n,runtimeLifecycle:i.runtimeLifecycle??await ut(n)??q}}let a=await S({host:t.host??B,config:r,cache:n.cache,definitionsCache:n.definitionsCache,clearDefinitionsCache:n.clearDefinitionsCache,proxyMode:n.proxyMode,runtimeLifecycle:K,idleShutdownMinutes:n.idleShutdownMinutes});return{endpoint:new URL(`http://${a.host}:${a.port}${z}`),runtimeServerId:a.serverId,runtimeLifecycle:a.runtimeLifecycle??q}}async function ht(e,t,n){let{endpoint:r}=await pt(e,t,n);return r}function gt(e){return`runtime:${e}`}async function _t(e){if(e.runtimeLifecycle===K&&e.runtimeServerId)return await ie({repositoryPath:await J(),serviceName:`mcp-proxy-stdio-http-bridge:${re()}`,serviceType:`tool`,environment:X(),pid:process.pid,command:process.argv[1],args:process.argv.slice(2),tags:[G,gt(e.runtimeServerId)],metadata:{transport:U,runtimeServerId:e.runtimeServerId,runtimeLifecycle:e.runtimeLifecycle,endpoint:e.endpoint.toString()},force:!1})}function vt(e){return e.pid===process.pid}async function yt(e){return await new k(process.env.PROCESS_REGISTRY_PATH).listProcesses({repositoryPath:await J(),serviceType:`tool`,tags:[G,gt(e)],environment:X(),liveOnly:!0})}async function bt(e){return(await yt(e)).filter(e=>!vt(e)).length>0?!1:(await new Promise(e=>setTimeout(e,500)),(await yt(e)).filter(e=>!vt(e)).length===0)}async function xt(t){if(t.runtimeLifecycle!==K||!t.runtimeServerId)return;let n=t.runtimeServerId,r=ft(await J(),W);try{await oe(r,async()=>{await bt(n)&&await new e().stop({serverId:n,force:!0})})}catch(e){console.error(`Failed to stop managed stdio-http runtime; leaving it alive: ${Y(e)}`)}}async function St(e,t,n,r){let i=t.autoDisconnect?!0:r?.keepAlive!==void 0&&!r.keepAlive,a,o;try{a=await pt(e,t,n),o=await _t(a);let{endpoint:r}=a;await Q(new b({endpoint:r,resolveEndpoint:async()=>await ht(e,t,n)},Xe()),async()=>{try{await o?.release({kill:!1,releasePort:!1})}catch(e){console.error(`Failed to release stdio-http bridge lease; leaving runtime alive: ${Y(e)}`);return}i&&a&&await xt(a)},{shutdownOnStdinClose:!0})}catch(e){try{await o?.release({kill:!1,releasePort:!1})}catch(t){throw Error(`Failed to start stdio-http transport: ${Y(e)}; also failed to release bridge lease: ${Y(t)}`)}throw Error(`Failed to start stdio-http transport: ${Y(e)}`)}}async function Ct(e,t,n,r,i){try{if(e===V){await lt(r);return}if(e===H){await ct(r,Ye(t,y.HTTP,i),n,Re(t.idleShutdownMinutes));return}await St(Ye(t,y.HTTP,i),t,n,i)}catch(t){throw Error(`Failed to start transport '${e}': ${Y(t)}`)}}async function wt(e,t){try{let n=await S({id:e.id,host:e.host??B,port:e.port,config:t,cache:e.cache,definitionsCache:e.definitionsCache,clearDefinitionsCache:e.clearDefinitionsCache,proxyMode:e.proxyMode,timeoutMs:e.timeoutMs,idleShutdownMinutes:e.idleShutdownMinutes});x(n)}catch(t){console.error(`Failed to prestart HTTP runtime '${e.id||`generated-server-id`}': ${Y(t)}`),process.exit(1)}}const Tt=new A(`mcp-serve`).description(`Start MCP server with specified transport or prestart the HTTP runtime in the background`).option(`-t, --type <type>`,`Transport type: ${V}, ${H}, or ${U}`).option(`-p, --port <port>`,`Port to listen on (http) or backend port for stdio-http`,e=>Number.parseInt(e,10)).option(`--host <host>`,`Host to bind to (http) or backend host for stdio-http`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,r).option(`--no-cache`,`Disable configuration caching, always reload from config file`).option(`--definitions-cache <path>`,`Path to prefetched tool/prompt/skill definitions cache file`).option(`--clear-definitions-cache`,`Delete definitions cache before startup`,!1).option(`--proxy-mode <mode>`,`How mcp-proxy exposes downstream tools: meta, flat, search, or group`,`meta`).option(`--id <id>`,`Unique server identifier (overrides config file id, auto-generated if not provided)`).option(`--auto-disconnect`,`Stop the managed HTTP runtime when the last stdio-http bridge exits (default: keep runtime alive for reuse)`,!1).option(`--idle-shutdown-minutes <minutes>`,`Stop the HTTP runtime after N minutes with no MCP session and no request (0 disables; overrides ${Le})`,e=>Number.parseFloat(e)).option(`--prestart-http`,`Prestart the HTTP runtime in the background and exit after it becomes healthy`,!1).option(`--timeout-ms <ms>`,`How long to wait for the HTTP runtime to become healthy`,String(d)).action(async e=>{try{let t=a(e.config),n=t.length>0?null:await He(),r=n?[n]:t;if(e.prestartHttp){await wt(e,r);return}let i=await We(r),o=Ke((e.type??i.type??V).toLowerCase());qe(e.proxyMode),await Ct(o,e,r,Ze(e,r,await Ge(e,r)),i)}catch(t){let n=(e.type??V).toLowerCase(),r=ze(n)?n:V,i=process.env.MCP_PORT?Number(process.env.MCP_PORT):void 0,a=e.port??(Number.isFinite(i)?i:void 0);console.error(Qe(r,e.host??B,a,t)),process.exit(1)}}),Et=new A(`prefetch`).description(`Pre-download packages used by MCP servers (npx, pnpx, uvx, uv)`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,r).option(`-p, --parallel`,`Run prefetch commands in parallel`,!1).option(`-d, --dry-run`,`Show what would be prefetched without executing`,!1).option(`-f, --filter <type>`,`Filter by package manager type: npx, pnpx, uvx, or uv`).option(`--definitions-out <path>`,`Write discovered definitions to a JSON or YAML cache file`).option(`--skip-packages`,`Skip package prefetch and only build definitions cache`,!1).option(`--clear-definitions-cache`,`Delete the definitions cache file before continuing`,!1).action(async e=>{try{let r=g(),i=a(e.config),o=i.length>0?null:await n(),s=o?[o]:i;s.length===0&&(L.error(`No MCP configuration file found.`),L.info(`Use --config <path> to specify a config file, or run "po-mcp-proxy init" to create one.`),process.exit(1)),L.info(`Loading configuration from: ${s.join(`, `)}`);let c=await r.createConfigFetcherService({configSources:C(s),useCache:!1}).fetchConfiguration(!0),l=c.id||t(),u=p.generateConfigHash(c),d=e.definitionsOut||p.getDefaultCachePath(s),m=r.createPrefetchService({mcpConfig:c,filter:e.filter,parallel:e.parallel}),h=m.extractPackages(),_=!e.skipPackages,v=!!e.definitionsOut;if(e.clearDefinitionsCache&&(e.dryRun?L.info(`Would clear definitions cache: ${d}`):(await p.clearFile(d),L.success(`Cleared definitions cache: ${d}`))),_){if(h.length===0)L.warning(`No packages found to prefetch.`),L.info(`Prefetch supports: npx, pnpx, uvx, and uv run commands`);else{L.info(`Found ${h.length} package(s) to prefetch:`);for(let e of h)L.item(`${e.serverName}: ${e.packageManager} ${e.packageName}`)}}if(!_&&!v){L.warning(`Nothing to do. Use package prefetch or provide --definitions-out.`);return}if(e.dryRun){if(_&&h.length>0){L.newline(),L.header(`Dry run mode - commands that would be executed:`);for(let e of h)L.indent(e.fullCommand.join(` `))}v&&(L.newline(),L.info(`Would write definitions cache to: ${d}`));return}let y=!1;if(_&&h.length>0){L.newline(),L.info(`Prefetching packages...`);let e=await m.prefetch();if(L.newline(),e.failed===0?L.success(`Package prefetch complete: ${e.successful} succeeded, ${e.failed} failed`):L.warning(`Package prefetch complete: ${e.successful} succeeded, ${e.failed} failed`),e.failed>0){y=!0,L.newline(),L.error(`Failed packages:`);for(let t of e.results.filter(e=>!e.success))L.item(`${t.package.serverName} (${t.package.packageName}): ${t.output.trim()}`)}}if(v){L.newline(),L.info(`Collecting definitions cache...`);let e=await r.createClientManagerService(),t=c.skills?.paths||[],n=t.length>0?r.createSkillService(process.cwd(),t):void 0,i=r.createDefinitionsCacheService(e,n);await Promise.all(Object.entries(c.mcpServers).map(async([t,n])=>{try{await e.connectToServer(t,n),L.item(`Connected for definitions: ${t}`)}catch(e){L.warning(`Failed to connect for definitions: ${t} (${e instanceof Error?e.message:String(e)})`)}}));let a=await i.collectForCache({configPath:s[0],configHash:u,oneMcpVersion:f,serverId:l});await p.writeToFile(d,a),L.success(`Definitions cache written: ${d} (${Object.keys(a.servers).length} servers, ${a.skills.length} skills)`),a.failures.length>0&&L.warning(`Definitions cache completed with ${a.failures.length} server failure(s)`),await e.disconnectAll()}y&&process.exit(1)}catch(e){L.error(`Error executing prefetch: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}});function $(e){return e instanceof Error?e.message:String(e)}const Dt=new A(`read-resource`).description(`Read a resource by URI from a connected MCP server`).argument(`<uri>`,`Resource URI to read`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,r).option(`-s, --server <name>`,`Server name (required if resource exists on multiple servers)`).option(`-j, --json`,`Output as JSON`,!1).action(async(e,t)=>{try{await M(t,async({clientManager:n})=>{let r=n.getAllClients();if(t.server){let r=n.getClient(t.server);if(!r)throw Error(`Server "${t.server}" not found`);t.json||console.error(`Reading ${e} from ${t.server}...`);let i=await r.readResource(e);if(t.json)console.log(JSON.stringify(i,null,2));else for(let e of i.contents)`text`in e?console.log(e.text):console.log(JSON.stringify(e,null,2));return}let i=await Promise.all(r.map(async t=>{try{let n=(await t.listResources()).some(t=>t.uri===e);return{serverName:t.serverName,hasResource:n,error:null}}catch(e){return{serverName:t.serverName,hasResource:!1,error:e}}})),a=[];for(let{serverName:e,hasResource:t,error:n}of i)n?console.error(`Failed to list resources from ${e}: ${$(n)}`):t&&a.push(e);if(a.length===0)throw Error(`Resource "${e}" not found on any connected server`);if(a.length>1)throw Error(`Resource "${e}" found on multiple servers: ${a.join(`, `)}. Use --server to disambiguate`);let o=a[0],s=n.getClient(o);if(!s)throw Error(`Internal error: Server "${o}" not connected`);t.json||console.error(`Reading ${e} from ${o}...`);let c=await s.readResource(e);if(t.json)console.log(JSON.stringify(c,null,2));else for(let e of c.contents)`text`in e?console.log(e.text):console.log(JSON.stringify(e,null,2))})}catch(e){console.error(`Error executing read-resource: ${$(e)}`),process.exit(1)}});function Ot(e){return e instanceof Error?e.message:String(e)}function kt(e){console.log(`Stopped mcp-proxy server '${e.serverId}'.`),console.log(`Endpoint: http://${e.host}:${e.port}`),console.log(`Result: ${e.message}`)}const At=new A(`stop`).description(`Stop a running HTTP mcp-proxy server`).option(`--id <id>`,`Target server ID from the runtime registry`).option(`--host <host>`,`Target runtime host`).option(`--port <port>`,`Target runtime port`,e=>Number.parseInt(e,10)).option(`-c, --config <path>`,`Reserved for future config-based targeting support`).option(`--token <token>`,`Override the persisted shutdown token`).option(`--force`,`Skip server ID verification against the /health response`,!1).option(`-j, --json`,`Output as JSON`,!1).option(`--timeout <ms>`,`Maximum time to wait for shutdown completion`,e=>Number.parseInt(e,10),5e3).action(async e=>{try{e.config&&console.error(`Warning: --config is not used yet; runtime resolution uses the persisted registry.`);let t=await g().createStopServerService().stop({serverId:e.id,host:e.host,port:e.port,token:e.token,force:e.force,timeoutMs:e.timeout});if(e.json){console.log(JSON.stringify(t,null,2));return}kt(t)}catch(t){let n=`Error executing stop: ${Ot(t)}`;e.json?console.log(JSON.stringify({ok:!1,error:n},null,2)):console.error(n),process.exit(1)}});function jt(e){return e instanceof Error?e.message:String(e)}const Mt=new A(`use-tool`).description(`Execute an MCP tool with arguments`).argument(`<toolName>`,`Tool name to execute`).option(`-c, --config <path>`,`Path to MCP server configuration file (repeatable; later files override earlier ones)`,r).option(`-s, --server <name>`,`Server name (required if tool exists on multiple servers)`).option(`-a, --args <json>`,`Tool arguments as JSON string`,`{}`).option(`-t, --timeout <ms>`,`Request timeout in milliseconds for tool execution (default: 60000)`,Number.parseInt).option(`-j, --json`,`Output as JSON`,!1).action(async(e,t)=>{try{let n={};try{n=JSON.parse(t.args)}catch{console.error(`Error: Invalid JSON in --args`),process.exit(1)}await M(t,async({container:r,config:i,clientManager:a})=>{let o=a.getAllClients();if(t.server){let r=a.getClient(t.server);if(!r)throw Error(`Server "${t.server}" not found`);t.json||console.error(`Executing ${e} on ${t.server}...`);let i=t.timeout?{timeout:t.timeout}:void 0,o=await r.callTool(e,n,i);if(t.json)console.log(JSON.stringify(o,null,2));else{if(console.log(`
|
|
142
142
|
Result:`),o.content)for(let e of o.content)e.type===`text`?console.log(e.text):console.log(JSON.stringify(e,null,2));o.isError&&(console.error(`
|
|
143
143
|
⚠️ Tool execution returned an error`),process.exit(1))}return}let s=await Promise.all(o.map(async t=>{try{let n=(await t.listTools()).some(t=>t.name===e);return{serverName:t.serverName,hasTool:n,error:null}}catch(e){return{serverName:t.serverName,hasTool:!1,error:e}}})),c=[];for(let{serverName:e,hasTool:n,error:r}of s)r?t.json||console.error(`Failed to list tools from ${e}:`,r):n&&c.push(e);if(c.length===0){let n=i.skills?.paths||[];if(n.length>0)try{let i=process.env.PROJECT_PATH||process.cwd(),a=r.createSkillService(i,n),o=e.startsWith(`skill__`)?e.slice(7):e,s=await a.getSkill(o);if(s){let e={content:[{type:`text`,text:s.content}]};t.json?console.log(JSON.stringify(e,null,2)):(console.log(`
|
|
144
144
|
Skill content:`),console.log(s.content));return}}catch(n){t.json||console.error(`Failed to lookup skill "${e}":`,n)}throw Error(`Tool or skill "${e}" not found on any connected server or configured skill paths`)}if(c.length>1)throw Error(`Tool "${e}" found on multiple servers: ${c.join(`, `)}`);let l=c[0],u=a.getClient(l);if(!u)throw Error(`Internal error: Server "${l}" not connected`);t.json||console.error(`Executing ${e} on ${l}...`);let d=t.timeout?{timeout:t.timeout}:void 0,f=await u.callTool(e,n,d);if(t.json)console.log(JSON.stringify(f,null,2));else{if(console.log(`
|
|
145
145
|
Result:`),f.content)for(let e of f.content)e.type===`text`?console.log(e.text):console.log(JSON.stringify(e,null,2));f.isError&&(console.error(`
|
|
146
|
-
⚠️ Tool execution returned an error`),process.exit(1))}})}catch(e){console.error(`Error executing use-tool: ${jt(e)}`),process.exit(1)}});async function Nt(){try{let e=new A;e.name(`po-mcp-proxy`).description(`MCP proxy server package`).version(
|
|
146
|
+
⚠️ Tool execution returned an error`),process.exit(1))}})}catch(e){console.error(`Error executing use-tool: ${jt(e)}`),process.exit(1)}});async function Nt(){try{let e=new A;e.name(`po-mcp-proxy`).description(`MCP proxy server package`).version(f),e.addCommand(De),e.addCommand(Tt),e.addCommand(Ne),e.addCommand(Ce),e.addCommand(Mt),e.addCommand(Ae),e.addCommand(Dt),e.addCommand(Oe),e.addCommand(we),e.addCommand(Et),e.addCommand(At),e.addCommand(ve),await e.parseAsync(process.argv)}catch(e){console.error(`CLI execution failed: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}Nt().catch(e=>{console.error(`Fatal error: ${e instanceof Error?e.message:String(e)}`),process.exit(1)});export{};
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./src-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./src-CyntLpz1.cjs");exports.CALLBACK_BIND_WAIT_MS=e.Q,exports.CALLBACK_POLL_INTERVAL_MS=e.$,exports.CALLBACK_PORT_SPAN=e.et,exports.CALLBACK_TIMEOUT_MS=e.tt,exports.CallbackRendezvous=e.ut,exports.ConfigFetcherService=e.B,exports.DEFAULT_CALLBACK_PATH=e.nt,exports.DEFAULT_CALLBACK_PORT=e.rt,exports.DEFAULT_HTTP_RUNTIME_TIMEOUT_MS=e.g,exports.DefinitionsCacheService=e.j,exports.DescribeToolsTool=e.m,exports.FileTokenStore=e.q,exports.HttpTransportHandler=e.S,exports.McpClientManagerService=e.E,exports.McpOAuthProvider=e.K,exports.MemoryTokenStore=e.J,exports.OAuthCallbackServer=e.it,exports.OutputGuardService=e.O,exports.RESERVATION_STALE_MS=e.dt,exports.RuntimeStateService=e.T,exports.SearchListToolsTool=e.p,exports.SkillService=e.w,exports.StdioHttpTransportHandler=e.u,exports.StdioTransportHandler=e.d,exports.StopServerService=e.C,exports.TRANSPORT_MODE=e.t,exports.UseToolTool=e.f,exports.VAULT_REF_ERROR_MESSAGE=e.M,exports.acquireSharedCallbackServer=e.at,exports.cleanupStaleRegistries=e.P,exports.closeSharedCallbackServer=e.ot,exports.collectConfigPath=e.L,exports.createHttpTransportHandler=e.i,exports.createOAuthProvider=e.H,exports.createProxyContainer=e.a,exports.createProxyIoCContainer=e.o,exports.createProxyLogger=e.A,exports.createServer=e.n,exports.createSessionServer=e.r,exports.createStdioHttpTransportHandler=e.s,exports.createStdioTransportHandler=e.c,exports.findConfigFile=e.I,exports.findHealthyExistingRuntime=e._,exports.generateServerId=e.F,exports.getDefaultRendezvousRoot=e.ft,exports.getDefaultTokenStoreDir=e.Y,exports.getSharedCallbackServer=e.st,exports.hasVaultRef=e.N,exports.initializeSharedServices=e.l,exports.isAuthError=e.D,exports.parseMcpConfig=e.V,exports.prestartHttpRuntime=e.y,exports.probeRuntimeHealth=e.b,exports.readAuthEntryForUrl=e.X,exports.releaseSharedCallbackServer=e.ct,exports.resolveAuthScheme=e.U,exports.resolveBearerToken=e.W,exports.resolveCallbackPort=e.G,exports.resolveOutputGuardOptions=e.k,exports.resolveWorkspaceRoot=e.pt,exports.toConfigPaths=e.R,exports.toConfigSources=e.z,exports.withTokenStoreLock=e.Z,exports.workspaceCallbackPort=e.lt;
|
package/dist/index.d.cts
CHANGED
|
@@ -216,6 +216,26 @@ interface OAuthServerConfig {
|
|
|
216
216
|
clientName?: string;
|
|
217
217
|
clientUri?: string;
|
|
218
218
|
}
|
|
219
|
+
/**
|
|
220
|
+
* One `${vault:NAME}` reference a connection needs, handed to the host's secret resolver.
|
|
221
|
+
* @property field - Where the reference sits: a header value, an env value, or `bearerToken`
|
|
222
|
+
* @property key - The header or env name, absent for `bearerToken`
|
|
223
|
+
* @property name - The referenced secret name
|
|
224
|
+
* @property origin - The URL origin the secret is sent to (http and sse)
|
|
225
|
+
* @property command - The child command the secret is given to (stdio)
|
|
226
|
+
* @property args - The child arguments (stdio)
|
|
227
|
+
*/
|
|
228
|
+
interface McpSecretTarget {
|
|
229
|
+
serverName: string;
|
|
230
|
+
field: 'header' | 'env' | 'bearerToken';
|
|
231
|
+
key?: string;
|
|
232
|
+
name: string;
|
|
233
|
+
transport: McpServerTransportType;
|
|
234
|
+
origin?: string;
|
|
235
|
+
command?: string;
|
|
236
|
+
args?: string[];
|
|
237
|
+
signal?: AbortSignal;
|
|
238
|
+
}
|
|
219
239
|
/**
|
|
220
240
|
* Authentication options shared by every URL-based transport.
|
|
221
241
|
* @property auth - `oauth`, `bearer`, `false`, or non-secret API-key header mapping
|
|
@@ -1595,6 +1615,12 @@ export declare function parseMcpConfig(rawConfig: unknown, env?: NodeJS.ProcessE
|
|
|
1595
1615
|
*/
|
|
1596
1616
|
export declare function cleanupStaleRegistries(): Promise<void>;
|
|
1597
1617
|
//#endregion
|
|
1618
|
+
//#region src/utils/vaultRefs.d.ts
|
|
1619
|
+
/** Error message for every reference failure. Never carries a name or a value. */
|
|
1620
|
+
export declare const VAULT_REF_ERROR_MESSAGE = "MCP secret reference could not be resolved.";
|
|
1621
|
+
/** True when the text mentions a vault reference, well formed or not. */
|
|
1622
|
+
export declare function hasVaultRef(value: unknown): boolean;
|
|
1623
|
+
//#endregion
|
|
1598
1624
|
//#region src/utils/workspaceRoot.d.ts
|
|
1599
1625
|
/**
|
|
1600
1626
|
* Workspace Root Discovery
|
|
@@ -1792,6 +1818,11 @@ interface McpClientManagerAuthOptions {
|
|
|
1792
1818
|
auth: McpApiKeyAuth;
|
|
1793
1819
|
signal?: AbortSignal;
|
|
1794
1820
|
}) => Promise<Readonly<Record<string, string>> | undefined>;
|
|
1821
|
+
/**
|
|
1822
|
+
* Resolve one `${vault:NAME}` reference for a connection attempt. Returning undefined
|
|
1823
|
+
* fails the connection. The resolved value is used on a copy of the configuration only.
|
|
1824
|
+
*/
|
|
1825
|
+
resolveSecret?: (target: McpSecretTarget) => Promise<string | undefined>;
|
|
1795
1826
|
}
|
|
1796
1827
|
interface McpServerStateChange {
|
|
1797
1828
|
serverName: string;
|
|
@@ -1838,6 +1869,7 @@ export declare class McpClientManagerService {
|
|
|
1838
1869
|
private readonly callbackTimeoutMs?;
|
|
1839
1870
|
private readonly callbackServer?;
|
|
1840
1871
|
private readonly resolveUrlCredentials?;
|
|
1872
|
+
private readonly resolveSecret?;
|
|
1841
1873
|
constructor(logger?: LoggerLike, repositoryPath?: string, outputGuard?: OutputGuardService, authOptions?: McpClientManagerAuthOptions, workspaceRoot?: string, env?: NodeJS.ProcessEnv, executionCwd?: string, outputSchemaValidation?: OutputSchemaValidationOptions | undefined, clientCapabilities?: ClientCapabilities);
|
|
1842
1874
|
/**
|
|
1843
1875
|
* Subscribe to downstream server lifecycle transitions.
|
|
@@ -2946,4 +2978,4 @@ export declare function createSessionServer(shared: SharedServices): Promise<Ser
|
|
|
2946
2978
|
*/
|
|
2947
2979
|
export declare function createServer(options?: ServerOptions): Promise<Server>;
|
|
2948
2980
|
//#endregion
|
|
2949
|
-
export type { AuthEntry, BrokeredResult, CachedCapabilityDiscoveryResult, CachedFileSkillInfo, CachedPromptSkillInfo, CachedServerDefinition, CallbackRendezvousOptions, CallbackResult, CapabilityDiscoveryState, ConfigFetcherOptions, ConfigMergeStrategy, ConfigSource, ConfigSourceFormat, CreateOAuthProviderOptions, DefinitionsCacheFile, HealthProbeOptions, HealthProbeResult, HostRecord, HttpTransportAdminOptions, HttpTransportHealthResponse, HttpTransportShutdownResponse, LoggerLike, McpApiKeyAuth, McpClientConnection, McpClientLifecycleState, McpClientManagerAuthOptions, McpHttpConfig, McpOAuthProviderOptions, McpOutputSchemaWarning, McpPromptInfo, McpRequestOptions, McpResourceInfo, McpServerConfig, McpServerState, McpServerStateChange, McpServerTransportConfig, McpServerTransportType, McpSseConfig, McpStdioConfig, McpToolCallOptions, McpToolInfo, McpUrlAuthConfig, OAuthCallbackServerOptions, OAuthCallbackSink, OAuthServerConfig, OutputGuardOptions, OutputGuardReport, OutputSchemaValidationOptions, PrestartHttpOptions, PrestartHttpResult, PromptConfig, PromptSkillConfig, ProxyContainer, ProxyLoggerHandle, ProxyLoggerOptions, ProxyMode, RemoteMcpConfiguration, ResolvedAuthScheme, RuntimeHealthPayload, RuntimeLifecycle, RuntimeLookupOptions, RuntimeStateManager, RuntimeStateRecord, ServerOptions, SharedServices, Skill, SkillMetadata, SkillsConfig, StopServerRequest, StopServerResult, TokenStore, Tool, ToolDefinition, TransportConfig, TransportHandler, TransportMode };
|
|
2981
|
+
export type { AuthEntry, BrokeredResult, CachedCapabilityDiscoveryResult, CachedFileSkillInfo, CachedPromptSkillInfo, CachedServerDefinition, CallbackRendezvousOptions, CallbackResult, CapabilityDiscoveryState, ConfigFetcherOptions, ConfigMergeStrategy, ConfigSource, ConfigSourceFormat, CreateOAuthProviderOptions, DefinitionsCacheFile, HealthProbeOptions, HealthProbeResult, HostRecord, HttpTransportAdminOptions, HttpTransportHealthResponse, HttpTransportShutdownResponse, LoggerLike, McpApiKeyAuth, McpClientConnection, McpClientLifecycleState, McpClientManagerAuthOptions, McpHttpConfig, McpOAuthProviderOptions, McpOutputSchemaWarning, McpPromptInfo, McpRequestOptions, McpResourceInfo, McpSecretTarget, McpServerConfig, McpServerState, McpServerStateChange, McpServerTransportConfig, McpServerTransportType, McpSseConfig, McpStdioConfig, McpToolCallOptions, McpToolInfo, McpUrlAuthConfig, OAuthCallbackServerOptions, OAuthCallbackSink, OAuthServerConfig, OutputGuardOptions, OutputGuardReport, OutputSchemaValidationOptions, PrestartHttpOptions, PrestartHttpResult, PromptConfig, PromptSkillConfig, ProxyContainer, ProxyLoggerHandle, ProxyLoggerOptions, ProxyMode, RemoteMcpConfiguration, ResolvedAuthScheme, RuntimeHealthPayload, RuntimeLifecycle, RuntimeLookupOptions, RuntimeStateManager, RuntimeStateRecord, ServerOptions, SharedServices, Skill, SkillMetadata, SkillsConfig, StopServerRequest, StopServerResult, TokenStore, Tool, ToolDefinition, TransportConfig, TransportHandler, TransportMode };
|
package/dist/index.d.mts
CHANGED
|
@@ -216,6 +216,26 @@ interface OAuthServerConfig {
|
|
|
216
216
|
clientName?: string;
|
|
217
217
|
clientUri?: string;
|
|
218
218
|
}
|
|
219
|
+
/**
|
|
220
|
+
* One `${vault:NAME}` reference a connection needs, handed to the host's secret resolver.
|
|
221
|
+
* @property field - Where the reference sits: a header value, an env value, or `bearerToken`
|
|
222
|
+
* @property key - The header or env name, absent for `bearerToken`
|
|
223
|
+
* @property name - The referenced secret name
|
|
224
|
+
* @property origin - The URL origin the secret is sent to (http and sse)
|
|
225
|
+
* @property command - The child command the secret is given to (stdio)
|
|
226
|
+
* @property args - The child arguments (stdio)
|
|
227
|
+
*/
|
|
228
|
+
interface McpSecretTarget {
|
|
229
|
+
serverName: string;
|
|
230
|
+
field: 'header' | 'env' | 'bearerToken';
|
|
231
|
+
key?: string;
|
|
232
|
+
name: string;
|
|
233
|
+
transport: McpServerTransportType;
|
|
234
|
+
origin?: string;
|
|
235
|
+
command?: string;
|
|
236
|
+
args?: string[];
|
|
237
|
+
signal?: AbortSignal;
|
|
238
|
+
}
|
|
219
239
|
/**
|
|
220
240
|
* Authentication options shared by every URL-based transport.
|
|
221
241
|
* @property auth - `oauth`, `bearer`, `false`, or non-secret API-key header mapping
|
|
@@ -1595,6 +1615,12 @@ export declare function parseMcpConfig(rawConfig: unknown, env?: NodeJS.ProcessE
|
|
|
1595
1615
|
*/
|
|
1596
1616
|
export declare function cleanupStaleRegistries(): Promise<void>;
|
|
1597
1617
|
//#endregion
|
|
1618
|
+
//#region src/utils/vaultRefs.d.ts
|
|
1619
|
+
/** Error message for every reference failure. Never carries a name or a value. */
|
|
1620
|
+
export declare const VAULT_REF_ERROR_MESSAGE = "MCP secret reference could not be resolved.";
|
|
1621
|
+
/** True when the text mentions a vault reference, well formed or not. */
|
|
1622
|
+
export declare function hasVaultRef(value: unknown): boolean;
|
|
1623
|
+
//#endregion
|
|
1598
1624
|
//#region src/utils/workspaceRoot.d.ts
|
|
1599
1625
|
/**
|
|
1600
1626
|
* Workspace Root Discovery
|
|
@@ -1792,6 +1818,11 @@ interface McpClientManagerAuthOptions {
|
|
|
1792
1818
|
auth: McpApiKeyAuth;
|
|
1793
1819
|
signal?: AbortSignal;
|
|
1794
1820
|
}) => Promise<Readonly<Record<string, string>> | undefined>;
|
|
1821
|
+
/**
|
|
1822
|
+
* Resolve one `${vault:NAME}` reference for a connection attempt. Returning undefined
|
|
1823
|
+
* fails the connection. The resolved value is used on a copy of the configuration only.
|
|
1824
|
+
*/
|
|
1825
|
+
resolveSecret?: (target: McpSecretTarget) => Promise<string | undefined>;
|
|
1795
1826
|
}
|
|
1796
1827
|
interface McpServerStateChange {
|
|
1797
1828
|
serverName: string;
|
|
@@ -1838,6 +1869,7 @@ export declare class McpClientManagerService {
|
|
|
1838
1869
|
private readonly callbackTimeoutMs?;
|
|
1839
1870
|
private readonly callbackServer?;
|
|
1840
1871
|
private readonly resolveUrlCredentials?;
|
|
1872
|
+
private readonly resolveSecret?;
|
|
1841
1873
|
constructor(logger?: LoggerLike, repositoryPath?: string, outputGuard?: OutputGuardService, authOptions?: McpClientManagerAuthOptions, workspaceRoot?: string, env?: NodeJS.ProcessEnv, executionCwd?: string, outputSchemaValidation?: OutputSchemaValidationOptions | undefined, clientCapabilities?: ClientCapabilities);
|
|
1842
1874
|
/**
|
|
1843
1875
|
* Subscribe to downstream server lifecycle transitions.
|
|
@@ -2946,4 +2978,4 @@ export declare function createSessionServer(shared: SharedServices): Promise<Ser
|
|
|
2946
2978
|
*/
|
|
2947
2979
|
export declare function createServer(options?: ServerOptions): Promise<Server>;
|
|
2948
2980
|
//#endregion
|
|
2949
|
-
export type { AuthEntry, BrokeredResult, CachedCapabilityDiscoveryResult, CachedFileSkillInfo, CachedPromptSkillInfo, CachedServerDefinition, CallbackRendezvousOptions, CallbackResult, CapabilityDiscoveryState, ConfigFetcherOptions, ConfigMergeStrategy, ConfigSource, ConfigSourceFormat, CreateOAuthProviderOptions, DefinitionsCacheFile, HealthProbeOptions, HealthProbeResult, HostRecord, HttpTransportAdminOptions, HttpTransportHealthResponse, HttpTransportShutdownResponse, LoggerLike, McpApiKeyAuth, McpClientConnection, McpClientLifecycleState, McpClientManagerAuthOptions, McpHttpConfig, McpOAuthProviderOptions, McpOutputSchemaWarning, McpPromptInfo, McpRequestOptions, McpResourceInfo, McpServerConfig, McpServerState, McpServerStateChange, McpServerTransportConfig, McpServerTransportType, McpSseConfig, McpStdioConfig, McpToolCallOptions, McpToolInfo, McpUrlAuthConfig, OAuthCallbackServerOptions, OAuthCallbackSink, OAuthServerConfig, OutputGuardOptions, OutputGuardReport, OutputSchemaValidationOptions, PrestartHttpOptions, PrestartHttpResult, PromptConfig, PromptSkillConfig, ProxyContainer, ProxyLoggerHandle, ProxyLoggerOptions, ProxyMode, RemoteMcpConfiguration, ResolvedAuthScheme, RuntimeHealthPayload, RuntimeLifecycle, RuntimeLookupOptions, RuntimeStateManager, RuntimeStateRecord, ServerOptions, SharedServices, Skill, SkillMetadata, SkillsConfig, StopServerRequest, StopServerResult, TokenStore, Tool, ToolDefinition, TransportConfig, TransportHandler, TransportMode };
|
|
2981
|
+
export type { AuthEntry, BrokeredResult, CachedCapabilityDiscoveryResult, CachedFileSkillInfo, CachedPromptSkillInfo, CachedServerDefinition, CallbackRendezvousOptions, CallbackResult, CapabilityDiscoveryState, ConfigFetcherOptions, ConfigMergeStrategy, ConfigSource, ConfigSourceFormat, CreateOAuthProviderOptions, DefinitionsCacheFile, HealthProbeOptions, HealthProbeResult, HostRecord, HttpTransportAdminOptions, HttpTransportHealthResponse, HttpTransportShutdownResponse, LoggerLike, McpApiKeyAuth, McpClientConnection, McpClientLifecycleState, McpClientManagerAuthOptions, McpHttpConfig, McpOAuthProviderOptions, McpOutputSchemaWarning, McpPromptInfo, McpRequestOptions, McpResourceInfo, McpSecretTarget, McpServerConfig, McpServerState, McpServerStateChange, McpServerTransportConfig, McpServerTransportType, McpSseConfig, McpStdioConfig, McpToolCallOptions, McpToolInfo, McpUrlAuthConfig, OAuthCallbackServerOptions, OAuthCallbackSink, OAuthServerConfig, OutputGuardOptions, OutputGuardReport, OutputSchemaValidationOptions, PrestartHttpOptions, PrestartHttpResult, PromptConfig, PromptSkillConfig, ProxyContainer, ProxyLoggerHandle, ProxyLoggerOptions, ProxyMode, RemoteMcpConfiguration, ResolvedAuthScheme, RuntimeHealthPayload, RuntimeLifecycle, RuntimeLookupOptions, RuntimeStateManager, RuntimeStateRecord, ServerOptions, SharedServices, Skill, SkillMetadata, SkillsConfig, StopServerRequest, StopServerResult, TokenStore, Tool, ToolDefinition, TransportConfig, TransportHandler, TransportMode };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{
|
|
1
|
+
export{Q as CALLBACK_BIND_WAIT_MS,$ as CALLBACK_POLL_INTERVAL_MS,et as CALLBACK_PORT_SPAN,tt as CALLBACK_TIMEOUT_MS,ut as CallbackRendezvous,B as ConfigFetcherService,nt as DEFAULT_CALLBACK_PATH,rt as DEFAULT_CALLBACK_PORT,g as DEFAULT_HTTP_RUNTIME_TIMEOUT_MS,j as DefinitionsCacheService,m as DescribeToolsTool,q as FileTokenStore,S as HttpTransportHandler,E as McpClientManagerService,K as McpOAuthProvider,J as MemoryTokenStore,it as OAuthCallbackServer,O as OutputGuardService,dt as RESERVATION_STALE_MS,T as RuntimeStateService,p as SearchListToolsTool,w as SkillService,u as StdioHttpTransportHandler,d as StdioTransportHandler,C as StopServerService,t as TRANSPORT_MODE,f as UseToolTool,M as VAULT_REF_ERROR_MESSAGE,at as acquireSharedCallbackServer,P as cleanupStaleRegistries,ot as closeSharedCallbackServer,L as collectConfigPath,i as createHttpTransportHandler,H as createOAuthProvider,a as createProxyContainer,o as createProxyIoCContainer,A as createProxyLogger,n as createServer,r as createSessionServer,s as createStdioHttpTransportHandler,c as createStdioTransportHandler,I as findConfigFile,_ as findHealthyExistingRuntime,F as generateServerId,ft as getDefaultRendezvousRoot,Y as getDefaultTokenStoreDir,st as getSharedCallbackServer,N as hasVaultRef,l as initializeSharedServices,D as isAuthError,V as parseMcpConfig,y as prestartHttpRuntime,b as probeRuntimeHealth,X as readAuthEntryForUrl,ct as releaseSharedCallbackServer,U as resolveAuthScheme,W as resolveBearerToken,G as resolveCallbackPort,k as resolveOutputGuardOptions,pt as resolveWorkspaceRoot,R as toConfigPaths,z as toConfigSources,Z as withTokenStoreLock,lt as workspaceCallbackPort}from"./src-BwFgoC11.mjs";
|