@explyt/ai-agent 0.2.0 → 0.2.1
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/README.md +3 -3
- package/THIRD-PARTY-NOTICES.md +34 -5
- package/dist/cli/engine.js +8 -5
- package/dist/cli/index.js +2 -2
- package/dist/cli/update.js +7 -3
- package/dist/extensions/ask-user-question.js +1 -1
- package/dist/extensions/bash.js +1 -1
- package/dist/extensions/custom-provider.js +1 -1
- package/dist/extensions/hello.js +1 -1
- package/dist/extensions/identity.js +1 -1
- package/dist/extensions/mcp.js +1 -1
- package/dist/extensions/misc-hacks.js +1 -1
- package/dist/extensions/policy.js +1 -1
- package/dist/extensions/rules.js +1 -1
- package/dist/extensions/session-title.js +1 -1
- package/dist/extensions/skills.js +1 -1
- package/dist/extensions/subagents.js +1 -1
- package/dist/extensions/tui.js +1 -1
- package/dist/extensions/update-notice.js +1 -1
- package/dist/extensions/web-access.js +1 -1
- package/dist/extensions/write.js +1 -0
- package/dist/mcp-adapter.js +4 -4
- package/dist/rpiv-ask-user-question/{chunk-GAM3ZAHN.js → chunk-JNDW3P3A.js} +2 -2
- package/dist/rpiv-ask-user-question/index.js +3 -3
- package/dist/vendor/model-probe/rules.json +102 -0
- package/dist/vendor/model-probe/src/index.js +983 -0
- package/dist/vendor/model-probe/src/opencode-models-snapshot.js +8 -0
- package/dist/vendor/model-probe/src/opencode-models.js +6 -0
- package/dist/vendor/pi-ai-compat.js +2 -0
- package/dist/vendor/pi-coding-agent.js +159 -0
- package/dist/vendor/pi-web-access-deps/modelcontextprotocol__sdk__client__index.js.js +9 -0
- package/dist/vendor/pi-web-access-deps/modelcontextprotocol__sdk__client__streamableHttp.js.js +9 -0
- package/dist/vendor/pi-web-access.js +24958 -0
- package/dist/vendor/typebox/chunk-6XHASRAZ.js +4819 -0
- package/dist/vendor/typebox/index.js +703 -0
- package/dist/vendor/typebox/value.js +3736 -0
- package/package.json +12 -4
package/dist/mcp-adapter.js
CHANGED
|
@@ -7,7 +7,7 @@ var Cf=Object.defineProperty;var je=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&
|
|
|
7
7
|
`),o=n.length,i=r.length,s=Array.from({length:o+1},()=>Array(i+1).fill(0));for(let d=o-1;d>=0;d--)for(let l=i-1;l>=0;l--){let f=s[d],p=s[d+1];!f||!p||(f[l]=n[d]===r[l]?(p[l+1]??0)+1:Math.max(p[l]??0,f[l+1]??0))}let a=["--- before","+++ after"],c=0,u=0;for(;c<o||u<i;){if(c<o&&u<i&&n[c]===r[u]){a.push(` ${n[c]}`),c++,u++;continue}if(u<i&&(c===o||(s[c]?.[u+1]??0)>=(s[c+1]?.[u]??0))){a.push(`+ ${r[u]}`),u++;continue}c<o&&(a.push(`- ${n[c]}`),c++)}return a.join(`
|
|
8
8
|
`)}function Ii(t,e){let n=Fe(t),r=Mn(t),o=n?pc(r):"",i=pc(e);return{path:t,existed:n,changed:o!==i,beforeText:o,afterText:i,diffText:Dp(o,i)}}function Mn(t){if(!Fe(t))return{};try{let e=so(no(t,"utf-8"));return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}catch{return{}}}function lr(t,e){bp(to(t),{recursive:!0});let n=`${t}.${process.pid}.tmp`;wp(n,`${JSON.stringify(e,null,2)}
|
|
9
9
|
`,"utf-8"),Cp(n,t)}function dr(t){let e=t.mcpServers??t["mcp-servers"]??{};return!e||typeof e!="object"||Array.isArray(e)?{}:e}function fr(t,e){delete t["mcp-servers"],t.mcpServers=e}function bc(t,e,n,r){let o=mc(e),i={};if(Fe(o))try{let f=so(no(o,"utf-8"));if(!f||typeof f!="object"||Array.isArray(f))throw new Error("root value must be an object");i=f}catch(f){throw new Error(`Failed to read project MCP override at ${o}: ${f instanceof Error?f.message:String(f)}`,{cause:f})}let s=i.mcpServers!==void 0?"mcpServers":i["mcp-servers"]!==void 0?"mcp-servers":"mcpServers",a=i[s];if(a!==void 0&&(!a||typeof a!="object"||Array.isArray(a)))throw new Error(`Failed to update project MCP override at ${o}: ${s} must be an object`);let c=a??{},u=c[n];if(u!==void 0&&(!u||typeof u!="object"||Array.isArray(u)))throw new Error(`Failed to update project MCP override at ${o}: server "${n}" must be an object`);let d=u,l;if(r)l={...d,disabled:!0};else{l=Object.fromEntries(Object.entries(d??{}).filter(([p])=>p!=="disabled"));let f={mcpServers:{}};for(let p of xn(t,e)){if(p.readPath===o)continue;let g=xt(p.readPath,`MCP config from ${p.readPath}`);g&&(f=bn(f,ki(g,e)))}if(i.imports!==void 0){if(!Array.isArray(i.imports)||i.imports.some(p=>typeof p!="string"||!Object.hasOwn(ur,p)))throw new Error(`Failed to update project MCP override at ${o}: imports contains an unsupported config kind`);f=bn(f,ki({mcpServers:{},imports:i.imports},e))}U(f.mcpServers[n])&&(l.disabled=!1)}return!d&&Object.keys(l).length===0||JSON.stringify(d)===JSON.stringify(l)?{path:o,changed:!1}:(Object.keys(l).length===0?delete c[n]:c[n]=l,i[s]=c,lr(o,i),{path:o,changed:!0})}function Np(t,e){let n=t.toLowerCase();if(n.includes("repoprompt")||n==="rp")return!0;let r=e.command?.toLowerCase()??"";return r.includes("repoprompt")||r.includes("rp-mcp")||r.endsWith("repoprompt_cli")?!0:(e.args??[]).some(o=>typeof o=="string"&&o.toLowerCase().includes("repoprompt"))}function Lp(t=process.cwd()){let e=Ft(t);for(;;){if(Fe(ye(e,".git"))||Fe(ye(e,"package.json"))||Fe(ye(e,Oi))||Fe(ye(e,".pi")))return e;let n=to(e);if(n===e)return null;e=n}}function jp(t){return{command:t,args:[],lifecycle:"lazy"}}function Bp(t,e=process.cwd()){for(let i of t.sources){if(i.kind!=="shared"||i.serverCount===0)continue;let s=xt(i.path,`MCP config from ${i.path}`);if(s){for(let[a,c]of Object.entries(s.mcpServers))if(Np(a,c))return{configured:!0,configuredPath:i.path}}}let n=Pp.find(i=>Fe(i));if(!n)return{configured:!1};let r=Lp(e),o=r?ye(r,Oi):eo;return{configured:!1,executablePath:n,targetPath:o,serverName:"repoprompt",entry:jp(n)}}function Cc(t,e){let n=ro(e),r=Mn(n),o=Array.isArray(r.imports)?r.imports.filter(a=>typeof a=="string"):[],i=[...new Set([...o,...t])],s={...r,imports:i};return fr(s,dr(s)),Ii(n,s)}function xc(t,e){let n=ro(e),r=Mn(n),o=Array.isArray(r.imports)?r.imports.filter(c=>typeof c=="string"):[],i=[...new Set([...o,...t])],s=i.filter(c=>!o.includes(c));if(s.length===0)return{path:n,added:[]};r.imports=i;let a=dr(r);return fr(r,a),lr(n,r),{path:n,added:s}}function Mc(){return{mcpServers:{}}}function Tc(t=process.cwd()){let e=Cn(t),n={mcpServers:Mc().mcpServers};return Ii(e,n)}function Ac(t=process.cwd()){let e=Cn(t),n={mcpServers:Mc().mcpServers};return lr(e,n),e}function _i(t,e,n){let o={...Mn(t)},i=dr(o);return i[e]=n,fr(o,i),Ii(t,o)}function Ui(t,e,n){let r=Mn(t),o=dr(r);return o[e]=n,fr(r,o),lr(t,r),t}function Di(t,e=process.cwd()){let n=new Map,r=ro(t);if($i(t,e)==="on")for(let o of Object.keys(ur)){let i=zt(o,e,`Failed to inspect imported MCP config from ${o}:`);if(i)for(let s of Object.keys(qt(i.value,o)))n.set(s,{path:r,kind:"import",importKind:o})}for(let o of xn(t,e)){let i=xt(o.readPath,`MCP config from ${o.readPath}`);if(i){if(i.imports?.length)for(let s of i.imports){let a=zt(s,e,`Failed to inspect imported MCP config from ${s}:`);if(!a)continue;let c=qt(a.value,s);for(let u of Object.keys(c))n.has(u)||n.set(u,{path:r,kind:"import",importKind:s})}for(let s of Object.keys(i.mcpServers))n.set(s,{path:o.writePath,kind:o.kind,...o.importKind!==void 0?{importKind:o.importKind}:{}})}}return n}function Pc(t,e,n){let r=new Map;for(let[o,i]of t){let s=e.get(o);if(!s)continue;let a=s.path;r.has(a)||r.set(a,[]),r.get(a).push({name:o,value:i,prov:s})}for(let[o,i]of r){let s=Mn(o),a=dr(s);for(let{name:c,value:u,prov:d}of i)if(d.kind==="import"){let l=n.mcpServers[c];l&&(a[c]={...l,directTools:u})}else a[c]&&(a[c]={...a[c],directTools:u});fr(s,a),lr(o,s)}}function Rc(t,e=process.cwd()){if(t==null)return;if(typeof t!="string")throw new Error("settings.oauthDir must be a string");let n=t.trim();if(n)return Ft(e,n)}var eo,Tp,Oi,Ap,Pp,gc,ur,kp,Tn=je(()=>{tt();Ya();rc();ue();be();eo=ye(Ke(),".config","mcp","mcp.json"),Tp=[ye(Ke(),".agents","mcp.json"),ye(Ke(),".agents","mcp","mcp.json")],Oi=".mcp.json",Ap="mcp.json",Pp=[ye(Ke(),"RepoPrompt","repoprompt_cli"),"/Applications/Repo Prompt.app/Contents/MacOS/repoprompt-mcp"],gc=[{id:"deepwiki",name:"DeepWiki",summary:"Ask questions about public GitHub repositories.",entry:{url:"https://mcp.deepwiki.com/mcp",protocolVersion:"auto"}},{id:"context7",name:"Context7",summary:"Look up current library documentation and examples.",entry:{url:"https://mcp.context7.com/mcp",protocolVersion:"auto"}},{id:"parallel-search",name:"Parallel Search",summary:"Search the web and fetch pages without an API key.",entry:{url:"https://search.parallel.ai/mcp",protocolVersion:"auto",directTools:!0}},{id:"notion",name:"Notion",summary:"Search and work with your Notion workspace.",entry:{url:"https://mcp.notion.com/mcp",auth:"oauth",protocolVersion:"auto"}},{id:"github",name:"GitHub",summary:"Work with GitHub through your Copilot account.",entry:{url:"https://api.githubcopilot.com/mcp",auth:"oauth",protocolVersion:"auto"}},{id:"chrome-devtools",name:"Chrome DevTools",summary:"Inspect and automate a local Chrome browser.",entry:{command:"npx",args:["-y","chrome-devtools-mcp@1.6.0"]}}],ur={cursor:[ye(Ke(),".cursor","mcp.json")],"claude-code":[ye(Ke(),".claude","mcp.json"),ye(Ke(),".claude.json"),ye(Ke(),".claude","claude_desktop_config.json")],"claude-desktop":[ye(Ke(),"Library","Application Support","Claude","claude_desktop_config.json")],codex:[ye(Ke(),".codex","config.toml"),ye(Ke(),".codex","config.json")],opencode:[ye(Ke(),".config","opencode","opencode.json"),"./opencode.json"],windsurf:[ye(Ke(),".windsurf","mcp.json")],vscode:[".vscode/mcp.json"]};kp=["headers","bearerToken","bearerTokenEnv","bearerTokenStore","requestHeadersCommand"]});function ho(t){let e=t._meta,n=Fg(e);if(n===void 0&&(n=e?.[Hg]),typeof n=="string"&&n.startsWith("ui://"))return n;if(n!==void 0)throw new Error(`Invalid UI resource URI: ${JSON.stringify(n)}`)}function Kc(t){if(!t)return"";let e=[];return t.camera&&e.push("camera"),t.microphone&&e.push("microphone"),t.geolocation&&e.push("geolocation"),t.clipboardWrite&&e.push("clipboard-write"),e.join("; ")}function Fg(t){let e=t?.ui;if(!(!e||typeof e!="object"))return e.resourceUri}var Pn,Hg,Rn=je(()=>{Pn="text/html;profile=mcp-app",Hg="ui/resourceUri"});function Ce(t){let e=t.replace(/[^a-zA-Z0-9]/g,"_").replace(/_+/g,"_").replace(/^_+/,"").replace(/_+$/,"").toLowerCase();return(!e||/^\d/.test(e))&&(e="resource"+(e?"_"+e:"")),e}var It=je(()=>{});function Zt(t){if(!t||typeof t!="object")return;let e=t.ui;if(!e||typeof e!="object"||Array.isArray(e))return;let n=e.visibility;if(n===void 0)return;if(!Array.isArray(n))return[];let r=[];for(let o of n){if(o!=="model"&&o!=="app")return[];r.includes(o)||r.push(o)}return r}function ke(t){return t===void 0||t.includes("model")}function Us(t){return t===void 0||t.includes("app")}var en=je(()=>{});import{existsSync as gl,readFileSync as ml,writeFileSync as Ty,renameSync as Ay,mkdirSync as Py}from"node:fs";import{dirname as Ry}from"node:path";import{createHash as Ey}from"node:crypto";function No(){return Qe("mcp-cache.json")}function ze(){let t=No();if(!gl(t))return null;try{let e=JSON.parse(ml(t,"utf-8"));return!e||typeof e!="object"||e.version!==Do||!e.servers||typeof e.servers!="object"?null:e}catch{return null}}function Lo(t){let e=No(),n=Ry(e);Py(n,{recursive:!0});let r={version:Do,servers:{}};try{if(gl(e)){let i=JSON.parse(ml(e,"utf-8"));i&&i.version===Do&&i.servers&&(r.servers={...i.servers})}}catch{}r.version=Do,r.servers={...r.servers,...t.servers};let o=`${e}.${process.pid}.tmp`;Ty(o,JSON.stringify(r),"utf-8"),Ay(o,e)}function Ns(t,e=process.env){let n={command:t.command,args:t.args,socket:vn(t.socket,e),env:yn(t.env,e),cwd:vn(t.cwd,e),url:He(t,e),headers:yn(t.headers,e),requestHeadersCommand:t.requestHeadersCommand?{command:le(t.requestHeadersCommand.command,e),args:t.requestHeadersCommand.args?.map(o=>le(o,e)),env:yn(t.requestHeadersCommand.env,e),timeoutMs:t.requestHeadersCommand.timeoutMs}:void 0,auth:t.auth,protocolVersion:t.protocolVersion,bearerToken:Qr(t,e),bearerTokenEnv:t.bearerTokenEnv,exposeResources:t.exposeResources,includeTools:t.includeTools,excludeTools:t.excludeTools},r=Ds(n);return Ey("sha256").update(r).digest("hex")}function $e(t,e,n=ky,r=process.env){let o;try{o=Ns(e,r)}catch{return!1}if(!t||t.configHash!==o||!t.cachedAt||typeof t.cachedAt!="number")return!1;let i=t.ttlMs;if(typeof i=="number"&&Number.isSafeInteger(i)&&i>=0){if(i===0)return!1;let s=Date.now()-t.cachedAt,a=n>0?Math.min(n,i):i;return s<a}return!(n>0&&Date.now()-t.cachedAt>n)}function tn(t){let e=new Set,n=new Map;for(let r of t)if(r=r.replace(/\/+$/,""),r.includes("/")){let[o,i]=r.split("/",2);if(o&&i){let s=n.get(o)??new Set;s.add(i),n.set(o,s)}else o&&e.add(o)}else r&&e.add(r);return{servers:e,tools:n}}function Fn(t,e,n){let r=[],o=t.settings?.directTools,i=n?tn(n):null;for(let[s,a]of Object.entries(t.mcpServers)){if(U(a)||!(i?i.servers.has(s)||i.tools.has(s):a.directTools!==void 0?!!a.directTools:!!o))continue;let u=e?.servers?.[s];(!u||!$e(u,a))&&r.push(s)}return r}function hl(t,e,n,r,o,i,s){let a=[],c=new Set,u=pe(r,n),l=Array.isArray(r.includeTools)&&r.includeTools.length>0||Array.isArray(r.excludeTools)&&r.excludeTools.length>0?s??(o&&i?Tr(o,i,n):void 0):void 0;for(let f of e.tools??[]){if(!f?.name||!ke(f.uiVisibility)||!Ee(f.name,t,u,r.includeTools,r.excludeTools,l))continue;let p=se(f.name,t,u);c.has(p)||(c.add(p),a.push({name:p,originalName:f.name,description:f.description??"",...f.inputSchema!==void 0?{inputSchema:f.inputSchema}:{},...f.uiResourceUri!==void 0?{uiResourceUri:f.uiResourceUri}:{},...f.uiVisibility!==void 0?{uiVisibility:f.uiVisibility}:{},...f.uiStreamMode!==void 0?{uiStreamMode:f.uiStreamMode}:{}}))}if(r.exposeResources!==!1)for(let f of e.resources??[]){if(!f?.name||!f?.uri)continue;let p=`read_${Ce(f.name)}`;if(!Ee(p,t,u,r.includeTools,r.excludeTools,l))continue;let g=se(p,t,u);c.has(g)||(c.add(g),a.push({name:g,originalName:p,description:f.description??`Read resource: ${f.uri}`,resourceUri:f.uri}))}return a}function Tr(t,e,n){let r=new Set;for(let[o,i]of Object.entries(t)){let s=e.servers[o];if(!s||!$e(s,i)||U(i))continue;let a=pe(i,n);for(let c of s.tools??[])if(ke(c.uiVisibility))for(let u of ce(c.name,o,a,!1))r.add(u);if(i.exposeResources!==!1)for(let c of s.resources??[]){let u=`read_${Ce(c.name)}`;for(let d of ce(u,o,a,!1))r.add(d)}}return mn(r)}function yl(t){return t.filter(e=>e?.name).map(e=>{let n=Oy(e),r=Zt(e._meta),o=Zr(e._meta);return{name:e.name,...e.description!==void 0?{description:e.description}:{},...e.inputSchema!==void 0?{inputSchema:e.inputSchema}:{},...n!==void 0?{uiResourceUri:n}:{},...r!==void 0?{uiVisibility:r}:{},...o!==void 0?{uiStreamMode:o}:{}}})}function vl(t){return t.filter(e=>e?.name&&e?.uri).map(e=>({uri:e.uri,name:e.name,...e.description!==void 0?{description:e.description}:{}}))}function Sl(t){return(t??[]).filter(e=>e?.name).map(e=>({name:e.name,...e.title!==void 0?{title:e.title}:{},...e.description!==void 0?{description:e.description}:{},...Array.isArray(e.arguments)?{arguments:e.arguments.filter(n=>n?.name).map(n=>({name:n.name,...n.description!==void 0?{description:n.description}:{},...n.required!==void 0?{required:n.required}:{}}))}:{}}))}function ut(t,e,n,r){let o=pe(r,n);return(e??[]).filter(i=>i?.name).map(i=>{let s=Array.isArray(i.arguments)?i.arguments.filter(a=>a?.name).map(a=>({name:a.name,...a.description!==void 0?{description:a.description}:{},...a.required!==void 0?{required:a.required}:{}})):[];return{serverName:t,originalName:i.name,commandName:wi(i.name,t,o),...i.title!==void 0?{title:i.title}:{},description:i.description??"",arguments:s}})}function Ds(t){if(t==null||typeof t!="object"){let r=JSON.stringify(t);return r===void 0?"undefined":r}if(Array.isArray(t))return`[${t.map(r=>Ds(r)).join(",")}]`;let e=t;return`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${Ds(e[r])}`).join(",")}}`}function Oy(t){try{return ho({_meta:t._meta})}catch{return}}var Do,ky,nt=je(()=>{tt();Rn();ue();It();be();en();Do=1,ky=10080*60*1e3});import{matchesKey as qn}from"@earendil-works/pi-tui";function Yy(t){let e=t?.getUserBindings?.()["mcp.panel.save"];return e!==void 0?{keys:Array.isArray(e)?e:[e],configured:!0}:{keys:[],configured:!1}}function Fo(t){let e=Yy(t);return t?{selectUp:n=>t.matches(n,"tui.select.up"),selectDown:n=>t.matches(n,"tui.select.down"),selectConfirm:n=>t.matches(n,"tui.select.confirm"),save:n=>e.keys.length>0?e.keys.some(r=>qn(n,r)):!e.configured&&qn(n,"ctrl+s"),saveLabel:()=>e.keys[0]??(e.configured?null:"ctrl+s")}:{selectUp:n=>qn(n,"up"),selectDown:n=>qn(n,"down"),selectConfirm:n=>qn(n,"return"),save:n=>qn(n,"ctrl+s"),saveLabel:()=>"ctrl+s"}}var Js=je(()=>{});var _l={};Ea(_l,{McpSetupPanel:()=>Vo,createMcpSetupPanel:()=>ev});import{matchesKey as Ws,truncateToWidth as $l,visibleWidth as Il}from"@earendil-works/pi-tui";function qe(t,e){return t?`\x1B[${t}m${e}\x1B[0m`:e}function vt(t,e){if(e<=8)return[t];let n=t.split(/\s+/).filter(Boolean),r=[],o="";for(let i of n){let s=o?`${o} ${i}`:i;if(Il(s)<=e){o=s;continue}o&&r.push(o),o=i}return o&&r.push(o),r.length>0?r:[""]}function ev(t,e,n,r,o){return new Vo(t,e,n,r,o)}var Xy,Qy,Zy,zo,qo,Vo,Ul=je(()=>{Js();tt();Tn();Xy={border:"2",title:"36",selected:"32",hint:"2",success:"32",warning:"33",muted:"2;3"},Qy=24,Zy=60,zo=7,qo=74;Vo=class t{constructor(e,n,r,o,i){this.discovery=e;this.callbacks=n;this.options=r;this.done=i;this.tui=o,this.keys=Fo(r.keybindings),this.screen=r.mode;for(let s of e.imports)this.selectedImports.add(s.kind);this.resetInactivityTimeout()}discovery;callbacks;options;done;screen;actionCursor=0;importCursor=0;pathCursor=0;selectedImports=new Set;busy=!1;notice=null;tui;t=Xy;keys;inactivityTimeout=null;static INACTIVITY_MS=6e4;resetInactivityTimeout(){this.inactivityTimeout&&clearTimeout(this.inactivityTimeout),this.inactivityTimeout=setTimeout(()=>{this.cleanup(),this.done()},t.INACTIVITY_MS)}cleanup(){this.inactivityTimeout&&(clearTimeout(this.inactivityTimeout),this.inactivityTimeout=null)}getActions(){let e=[];this.screen==="empty"&&e.push({id:"run-setup",label:"Run setup",description:"Inspect detected configs, adopt imports, and scaffold a minimal `.mcp.json`."}),this.discovery.imports.length>0&&e.push({id:"adopt-imports",label:"Adopt detected compatibility imports",description:`Choose which host-specific MCP configs Pi should import into its own override file. ${this.discovery.imports.length} source${this.discovery.imports.length===1?"":"s"} found.`}),e.push({id:"view-example",label:"View example `.mcp.json`",description:"Preview a working shared MCP config you can paste or adapt."}),this.discovery.sources.some(n=>n.id==="shared-project"&&n.exists)||e.push({id:"scaffold-project",label:"Scaffold project `.mcp.json`",description:"Write a minimal project config using the standard shared MCP file path, then reload Pi."}),e.push({id:"show-precedence",label:"Explain config precedence",description:"Show the read order and where Pi writes compatibility settings."}),this.getDetectedPaths().length>0&&e.push({id:"open-paths",label:"Open detected config paths",description:"Browse the actual config files that Pi discovered on this machine."});for(let n of gc)e.push({id:"add-known-server",label:n.name,description:n.summary,preset:n});return!this.discovery.repoPrompt.configured&&this.discovery.repoPrompt.executablePath&&this.discovery.repoPrompt.targetPath&&this.discovery.repoPrompt.entry&&this.discovery.repoPrompt.serverName&&e.push({id:"add-repoprompt",label:"Add RepoPrompt to shared MCP config",description:"Write a standard MCP entry for RepoPrompt to the recommended shared target, then reload MCP in-session."}),e.push({id:"close",label:"Close",description:"Exit the onboarding flow."}),e}getDetectedPaths(){let e=[...this.discovery.sources.filter(n=>n.exists).map(n=>n.path),...this.discovery.imports.map(n=>n.path)];return[...new Set(e)]}getSelectedAction(){return this.getActions()[this.actionCursor]}handleInput(e){if(this.resetInactivityTimeout(),this.busy||(this.notice=null),Ws(e,"ctrl+c")){this.cleanup(),this.done();return}if(Ws(e,"escape")){if(this.screen==="imports"||this.screen==="paths"){this.screen=this.discovery.hasAnyConfig?"setup":"empty",this.tui.requestRender();return}this.cleanup(),this.done();return}if(this.busy)return;if(this.screen==="imports"){this.handleImportsInput(e);return}if(this.screen==="paths"){this.handlePathsInput(e);return}let n=this.getActions();if(this.keys.selectUp(e)){this.actionCursor=Math.max(0,this.actionCursor-1),this.tui.requestRender();return}if(this.keys.selectDown(e)){this.actionCursor=Math.min(n.length-1,this.actionCursor+1),this.tui.requestRender();return}if(this.keys.selectConfirm(e)){let r=this.getSelectedAction();r&&this.runAction(r)}}handleImportsInput(e){let n=this.discovery.imports;if(this.keys.selectUp(e)){this.importCursor=Math.max(0,this.importCursor-1),this.tui.requestRender();return}if(this.keys.selectDown(e)){this.importCursor=Math.min(n.length-1,this.importCursor+1),this.tui.requestRender();return}if(Ws(e,"space")){let r=n[this.importCursor];if(!r)return;this.selectedImports.has(r.kind)?this.selectedImports.delete(r.kind):this.selectedImports.add(r.kind),this.tui.requestRender();return}this.keys.selectConfirm(e)&&this.applySelectedImports()}handlePathsInput(e){let n=this.getDetectedPaths();if(this.keys.selectUp(e)){this.pathCursor=Math.max(0,this.pathCursor-1),this.tui.requestRender();return}if(this.keys.selectDown(e)){this.pathCursor=Math.min(n.length-1,this.pathCursor+1),this.tui.requestRender();return}if(this.keys.selectConfirm(e)){let r=n[this.pathCursor];if(!r)return;this.runBusy(async()=>{await this.callbacks.openPath(r),this.notice={text:`Opened ${r}`,tone:"success"}})}}async runAction(e){if(e.id==="run-setup"){this.screen="setup",this.actionCursor=0,this.tui.requestRender();return}if(e.id==="adopt-imports"){this.screen="imports",this.importCursor=0,this.tui.requestRender();return}if(e.id==="open-paths"){this.screen="paths",this.pathCursor=0,this.tui.requestRender();return}if(e.id==="scaffold-project"){await this.runBusy(async()=>{let n=await this.callbacks.scaffoldProjectConfig();this.callbacks.markSetupCompleted(),this.notice={text:`Wrote starter config to ${n.path}. Pi will reload after this panel closes.`,tone:"success"}});return}if(e.id==="add-repoprompt"){await this.runBusy(async()=>{let n=await this.callbacks.addRepoPrompt();this.callbacks.markSetupCompleted(),this.notice={text:`Added ${n.serverName} to ${n.path}. Pi will reload after this panel closes.`,tone:"success"}});return}if(e.id==="add-known-server"&&e.preset){let n=e.preset;await this.runBusy(async()=>{let r=await this.callbacks.addKnownServer(n);this.callbacks.markSetupCompleted(),this.notice={text:`Added ${r.serverName} to ${r.path}. Pi will reload after this panel closes.`,tone:"success"}});return}if(e.id==="close"){this.cleanup(),this.done();return}this.notice={text:"Review the details below. Press Enter on an action with a side effect to apply it.",tone:"muted"},this.tui.requestRender()}async applySelectedImports(){let e=this.discovery.imports.filter(n=>this.selectedImports.has(n.kind)).map(n=>n.kind);if(e.length===0){this.notice={text:"Select at least one compatibility import first.",tone:"warning"},this.tui.requestRender();return}await this.runBusy(async()=>{let n=await this.callbacks.adoptImports(e);this.callbacks.markSetupCompleted(),this.notice=n.added.length>0?{text:`Added ${n.added.join(", ")} to ${n.path}. Pi will reload after this panel closes.`,tone:"success"}:{text:`No changes needed in ${n.path}.`,tone:"muted"},this.screen=this.discovery.hasAnyConfig?"setup":"empty",this.actionCursor=0})}async runBusy(e){this.busy=!0,this.notice={text:"Working...",tone:"muted"},this.tui.requestRender();try{await e()}catch(n){this.notice={text:n instanceof Error?n.message:String(n),tone:"warning"}}finally{this.busy=!1,this.tui.requestRender()}}render(e){let r=Math.max(Qy,e)-2,o=this.contentWidth(r),i=[],s=qe(this.t.border,"\u2500".repeat(r));i.push(`\u250C${s}\u2510`),i.push(this.padLine(qe(this.t.title,"MCP setup"),r));for(let a of vt(this.discoverySummaryLine(),o))i.push(this.padLine(a,r));for(let a of vt(this.secondarySummaryLine(),o))i.push(this.padLine(qe(this.t.muted,a),r));if(i.push(this.padLine("",r)),this.notice){let a=this.notice.tone==="success"?this.t.success:this.notice.tone==="warning"?this.t.warning:this.t.hint;for(let c of vt(this.notice.text,o))i.push(this.padLine(qe(a,c),r));i.push(this.padLine("",r))}return i.push(`\u251C${s}\u2524`),this.screen==="imports"?i.push(...this.renderImports(r)):this.screen==="paths"?i.push(...this.renderPaths(r)):i.push(...this.renderActions(r)),i.push(`\u2514${s}\u2518`),i}renderActions(e){let n=[],r=this.getActions(),o=e<Zy,{start:i,end:s}=o?this.visibleActionRange(r.length):{start:0,end:r.length};i>0&&n.push(this.padLine(qe(this.t.muted,`\u2026 ${i} more above`),e));for(let u=i;u<s;u++){let d=r[u];if(!d)continue;d.id==="add-known-server"&&(u===i||r[u-1]?.id!=="add-known-server")&&n.push(this.padLine(qe(this.t.title,"Add a known server"),e));let f=u===this.actionCursor?qe(this.t.selected,"\u203A"):" ";n.push(this.padLine(`${f} ${$l(d.label,this.contentWidth(e)-2)}`,e))}s<r.length&&n.push(this.padLine(qe(this.t.muted,`\u2026 ${r.length-s} more below`),e)),n.push(this.padLine("",e));let a=this.getActionPreview(this.getSelectedAction(),this.previewWidth(e));for(let u of a)n.push(this.padLine(u,e));n.push(this.padLine("",e));let c=o?"Enter select \xB7 Esc back":"Enter selects, Esc goes back, Ctrl+C closes.";return n.push(this.padLine(qe(this.t.muted,c),e)),n}renderImports(e){let n=[];n.push(this.padLine("Select compatibility imports. Space toggles, Enter saves, Esc goes back.",e)),n.push(this.padLine("",e));for(let i=0;i<this.discovery.imports.length;i++){let s=this.discovery.imports[i];if(!s)continue;let a=this.selectedImports.has(s.kind)?"[x]":"[ ]",c=i===this.importCursor?qe(this.t.selected,"\u203A"):" ";n.push(this.padLine(`${c} ${a} ${s.kind} ${s.path}`,e))}n.push(this.padLine("",e));let r=this.discovery.imports.filter(i=>this.selectedImports.has(i.kind)).map(i=>i.kind),o=this.callbacks.previewImports(r);for(let i of this.formatWritePreview("Compatibility import write preview",o,[],this.previewWidth(e)))n.push(this.padLine(i,e));return n}renderPaths(e){let n=[];n.push(this.padLine("Select a detected config path to open. Enter opens it, Esc goes back.",e)),n.push(this.padLine("",e));let r=this.getDetectedPaths();for(let o=0;o<r.length;o++){let i=o===this.pathCursor?qe(this.t.selected,"\u203A"):" ",s=r[o];s!==void 0&&n.push(this.padLine(`${i} ${s}`,e))}return n}discoverySummaryLine(){if(!this.discovery.hasAnyConfig)return qe(this.t.warning,this.options.onboardingState.setupCompleted?"No MCP servers are active right now.":"No MCP config is active yet.");if(this.discovery.totalServerCount===0&&(this.discovery.imports.length>0||this.discovery.repoPrompt.executablePath))return qe(this.t.warning,"Pi found MCP-related setup options, but none are active in Pi yet.");let e=this.discovery.sources.filter(r=>r.kind==="shared"&&r.serverCount>0).length,n=this.discovery.sources.filter(r=>r.kind==="pi"&&r.serverCount>0).length;return qe(this.t.hint,`Detected ${this.discovery.totalServerCount} configured servers across ${e} shared and ${n} Pi-owned source${e+n===1?"":"s"}.`)}secondarySummaryLine(){let e=this.discovery.hostConfigs.length>0?` Host discovery is ${this.discovery.hostConfigDiscovery}; ${this.discovery.hostConfigs.length} host source${this.discovery.hostConfigs.length===1?"":"s"} detected.`:"",n=this.discovery.conflicts.length>0?` ${this.discovery.conflicts.length} same-name conflict${this.discovery.conflicts.length===1?"":"s"} reported.`:"";return this.discovery.hasAnyConfig?this.discovery.totalServerCount===0&&this.discovery.imports.length>0?`Detected ${this.discovery.imports.length} compatibility import source${this.discovery.imports.length===1?"":"s"}. Adopt them into Pi or inspect the underlying files.${e}${n}`:`Shared MCP files are preferred. Pi-owned files are only for compatibility imports and adapter-specific overrides.${e}${n}`:`Create a shared .mcp.json, adopt host imports, or quick-add RepoPrompt from this screen.${e}${n}`}visibleActionRange(e){if(e<=zo)return{start:0,end:e};let n=Math.floor(zo/2),r=Math.min(Math.max(0,this.actionCursor-n),Math.max(0,e-zo));return{start:r,end:Math.min(e,r+zo)}}contentWidth(e){return Math.max(8,e-4)}previewWidth(e){return Math.max(12,Math.min(qo,this.contentWidth(e)))}getActionPreview(e,n=qo){switch(e?.id){case"run-setup":return this.formatPreview(["Run setup to adopt host-specific imports, inspect detected paths, and scaffold a minimal `.mcp.json` if needed."],n);case"adopt-imports":return this.formatWritePreview("Compatibility import write preview",this.callbacks.previewImports(this.discovery.imports.filter(r=>this.selectedImports.has(r.kind)).map(r=>r.kind)),[`Detected imports: ${this.discovery.imports.map(r=>`${r.kind} (${r.serverCount} servers)`).join(", ")}`,"Selected imports are written into the Pi agent dir config as Pi-owned compatibility state."],n);case"view-example":return this.formatPreview(["Example shared `.mcp.json`:","{",' "mcpServers": {',' "chrome-devtools": {',' "command": "npx",',' "args": ["-y", "chrome-devtools-mcp@1.6.0"]'," }"," }","}","","Use Scaffold project `.mcp.json` when you want a safe empty shell instead of a live example server."],n);case"show-precedence":return this.formatPreview(["Read order (later entries win):","0. detected host configs (opt-in lowest-precedence fallback)","1. ~/.config/mcp/mcp.json","2. ~/.agents/mcp.json","3. ~/.agents/mcp/mcp.json","4. <Pi agent dir>/mcp.json","5. .mcp.json",`6. ${bt()}/mcp.json`,`Host discovery: ${this.discovery.hostConfigDiscovery}. Conflicts reported: ${this.discovery.conflicts.length}.`,...this.discovery.conflicts.slice(0,8).map(r=>`${r.serverName}: ${r.sources.map(o=>o.path).join(" -> ")} (winner: ${r.winner.path})`),"Pi writes compatibility imports and adapter-only overrides to Pi-owned files."],n);case"open-paths":return this.formatPreview(this.getDetectedPaths().length>0?["Detected paths:",...this.getDetectedPaths()]:["No config paths were detected."],n);case"add-repoprompt":{let r=this.discovery.repoPrompt,o=this.callbacks.previewRepoPrompt();return o?this.formatWritePreview("RepoPrompt write preview",o,[`Executable: ${r.executablePath??"not found"}`,`Target: ${r.targetPath??"n/a"}`,`Server name: ${r.serverName??"repoprompt"}`],n):this.formatPreview(["RepoPrompt is not available to add from this setup screen."],n)}case"add-known-server":{let r=e.preset;return r?this.formatWritePreview(`${r.name} write preview`,this.callbacks.previewKnownServer(r),[r.summary],n):this.formatPreview(["Known server preset is unavailable."],n)}case"scaffold-project":return this.formatWritePreview("Starter project `.mcp.json` write preview",this.callbacks.previewStarterProject(),["This writes a minimal `.mcp.json` in the current project using the shared MCP layout.","It intentionally avoids adding a fake placeholder server that would fail on first reload."],n);default:return this.formatPreview(["Close the setup flow."],n)}}formatPreview(e,n=qo){let r=[];for(let o of e)r.push(...vt(o,n));return r}formatWritePreview(e,n,r=[],o=qo){let i=[];for(let u of r)i.push(...vt(u,o));r.length>0&&i.push(""),i.push(...vt(`${e}: ${n.path}`,o)),i.push(...vt(n.existed?"Existing file detected. Showing exact before/after diff.":"New file will be created. Showing exact content diff.",o)),i.push("");let s=n.diffText.split(`
|
|
10
|
-
`),a=18,c=s.slice(0,a);for(let u of c)i.push(...vt(u,o));return s.length>a&&i.push(...vt(`\u2026 ${s.length-a} more diff line${s.length-a===1?"":"s"}`,o)),i}padLine(e,n){let o=Math.max(0,n-4),i=$l(e,o,"\u2026",!0),s=Il(i),a=Math.max(0,o-s);return`\u2502${" ".repeat(2)}${i}${" ".repeat(a)}${" ".repeat(2)}\u2502`}invalidate(){}dispose(){this.cleanup()}}});var Ys={};Ea(Ys,{createMcpPanel:()=>iv});import{matchesKey as De,truncateToWidth as Dl,visibleWidth as Vn}from"@earendil-works/pi-tui";import{copyToClipboard as tv}from"@earendil-works/pi-coding-agent";function K(t,e){return t?`\x1B[${t}m${e}\x1B[0m`:e}function rv(t,e){let n=[];for(let r=0;r<e;r++){let o=Nl[r%Nl.length];o&&n.push(K(o,r<t?"\u25CF":"\u25CB"))}return n.join(" ")}function Ko(t,e){let n=t.toLowerCase(),r=e.toLowerCase();if(r.includes(n))return 100+n.length/r.length*50;let o=0,i=0,s=0;for(let a=0;a<r.length&&i<n.length;a++)r[a]===n[i]?(o+=10+s,s+=5,i++):s=0;return i===n.length?o:0}function Pe(t){return de(t??"")}function ov(t){let e=Ei(t),n="",r=!1;for(let o=0;o<e.length;o++){let s=e.slice(o).match(/^(?:\x1b\[[0-?]*[ -/]*[@-~]|\x1b[@-Z\\-_])/);if(s){n+=s[0],o+=s[0].length-1;continue}let a=e.charCodeAt(o);if(a<=31||a===127||a>=128&&a<=159){r=!0;continue}r&&n&&!n.endsWith(" ")&&(n+=" "),r=!1,n+=e[o]}return n}function Jo(t){let e=JSON.stringify(t.inputSchema??{}).length,n=t.description?.length??0;return Math.ceil((t.name.length+n+e)/4)+10}function iv(t,e,n,r,o,i,s){return new Gs(t,e,n,r,o,i,s??{})}var nv,Nl,Gs,Xs=je(()=>{Js();ue();It();be();nt();en();nv={border:"2",title:"2",selected:"36",direct:"32",needsAuth:"33",placeholder:"2;3",description:"2",hint:"2",confirm:"32",cancel:"31"};Nl=["38;2;178;129;214","38;2;215;135;175","38;2;254;188;56","38;2;228;192;15","38;2;137;210;129","38;2;0;175;175","38;2;23;143;185"];Gs=class t{constructor(e,n,r,o,i,s,a={}){this.config=e;this.cache=n;this.callbacks=o;this.done=s;this.tui=i,this.noticeLines=a.noticeLines??[],this.authOnly=a.authOnly===!0,this.keys=Fo(a.keybindings),this.prefix=e.settings?.toolPrefix??"server";for(let[c,u]of Object.entries(e.mcpServers)){if(this.authOnly&&!o.canAuthenticate(c))continue;let d=r.get(c),l=this.cache?.servers?.[c],f=l&&$e(l,u)?l:void 0,p=e.settings?.directTools,g=!1;u.directTools!==void 0?g=u.directTools:p&&(g=p);let y=[];if(f&&!this.authOnly&&!U(u)){for(let S of f.tools??[]){if(!ke(S.uiVisibility)||!Ee(S.name,c,this.prefix,u.includeTools,u.excludeTools,this.getOtherCurrentCandidates(c,u,f,S.name)))continue;let R=g===!0||Array.isArray(g)&&g.includes(S.name);y.push({name:S.name,description:S.description??"",isDirect:R,wasDirect:R,estimatedTokens:Jo(S)})}if(u.exposeResources!==!1)for(let S of f.resources??[]){let R=`read_${Ce(S.name)}`;if(!Ee(R,c,this.prefix,u.includeTools,u.excludeTools,this.getOtherCurrentCandidates(c,u,f,R)))continue;let h=g===!0||Array.isArray(g)&&g.includes(R),M={name:R,...S.description!==void 0?{description:S.description}:{}};y.push({name:R,description:S.description??`Read resource: ${S.uri}`,isDirect:h,wasDirect:h,estimatedTokens:Jo(M)})}}let w=o.getConnectionStatus(c),b=o.getFailureMessage?.(c)??null,v=0,m=0;for(let S of y)S.isDirect&&(v++,m+=S.estimatedTokens);this.servers.push({name:c,expanded:!1,source:d?.kind??"user",...d?.importKind!==void 0?{importKind:d.importKind}:{},...u.includeTools!==void 0?{includeTools:u.includeTools}:{},...u.excludeTools!==void 0?{excludeTools:u.excludeTools}:{},exposeResources:u.exposeResources!==!1,connectionStatus:w,failureMessage:b,tools:y,directCount:v,directTokens:m,hasCachedData:!!f})}this.rebuildVisibleItems(),this.resetInactivityTimeout()}config;cache;callbacks;done;noticeLines;prefix;servers=[];cursorIndex=0;nameQuery="";descSearchActive=!1;descQuery="";dirty=!1;confirmingDiscard=!1;discardSelected=1;importNotice=null;authNotice=null;authInFlight=null;inactivityTimeout=null;visibleItems=[];tui;t=nv;authOnly;keys;static MAX_VISIBLE=12;static INACTIVITY_MS=6e4;resetInactivityTimeout(){this.inactivityTimeout&&clearTimeout(this.inactivityTimeout),this.inactivityTimeout=setTimeout(()=>{this.cleanup(),this.done({cancelled:!0,changes:new Map})},t.INACTIVITY_MS)}cleanup(){this.inactivityTimeout&&(clearTimeout(this.inactivityTimeout),this.inactivityTimeout=null)}rebuildVisibleItems(){let e=this.descSearchActive?this.descQuery:this.nameQuery,n=this.descSearchActive?"desc":"name";this.visibleItems=[];for(let r=0;r<this.servers.length;r++){let o=this.servers[r];if(o){if(e&&this.authOnly){(n==="name"?Ko(e,o.name):0)>0&&this.visibleItems.push({type:"server",serverIndex:r});continue}if(this.visibleItems.push({type:"server",serverIndex:r}),o.expanded||e)for(let i=0;i<o.tools.length;i++){let s=o.tools[i];s&&(e&&(n==="name"?Math.max(Ko(e,s.name),Ko(e,o.name)*.6):Ko(e,s.description))===0||this.visibleItems.push({type:"tool",serverIndex:r,toolIndex:i}))}}}e&&!this.authOnly&&(this.visibleItems=this.visibleItems.filter(r=>r.type==="server"?this.visibleItems.some(o=>o.type==="tool"&&o.serverIndex===r.serverIndex):!0))}updateDirty(){this.dirty=this.servers.some(e=>e.tools.some(n=>n.isDirect!==n.wasDirect))}buildResult(){let e=new Map;for(let n of this.servers){if(!n.tools.some(i=>i.isDirect!==i.wasDirect))continue;let o=n.tools.filter(i=>i.isDirect);o.length===n.tools.length&&n.tools.length>0?e.set(n.name,!0):o.length===0?e.set(n.name,!1):e.set(n.name,o.map(i=>i.name))}return{changes:e,cancelled:!1}}handleInput(e){if(this.resetInactivityTimeout(),this.importNotice=null,this.authInFlight||(this.authNotice=null),this.confirmingDiscard){this.handleDiscardInput(e);return}if(De(e,"ctrl+c")){this.cleanup(),this.done({cancelled:!0,changes:new Map});return}if(this.keys.save(e)){this.cleanup(),this.done(this.buildResult());return}if(this.descSearchActive){if(De(e,"escape")||this.keys.selectConfirm(e)){this.descSearchActive=!1,this.descQuery="",this.rebuildVisibleItems(),this.cursorIndex=Math.min(this.cursorIndex,Math.max(0,this.visibleItems.length-1));return}if(De(e,"backspace")){this.descQuery.length>0&&(this.descQuery=this.descQuery.slice(0,-1),this.rebuildVisibleItems(),this.cursorIndex=Math.min(this.cursorIndex,Math.max(0,this.visibleItems.length-1)));return}if(this.keys.selectUp(e)){this.moveCursor(-1);return}if(this.keys.selectDown(e)){this.moveCursor(1);return}if(De(e,"space")){let n=this.visibleItems[this.cursorIndex];n&&this.toggleItem(n);return}if(e.length===1&&e.charCodeAt(0)>=32){this.descQuery+=e,this.rebuildVisibleItems(),this.cursorIndex=Math.min(this.cursorIndex,Math.max(0,this.visibleItems.length-1));return}return}if(De(e,"escape")){if(this.nameQuery){this.nameQuery="",this.rebuildVisibleItems(),this.cursorIndex=Math.min(this.cursorIndex,Math.max(0,this.visibleItems.length-1));return}if(this.dirty){this.confirmingDiscard=!0,this.discardSelected=1;return}this.cleanup(),this.done({cancelled:!0,changes:new Map});return}if(this.keys.selectUp(e)){this.moveCursor(-1);return}if(this.keys.selectDown(e)){this.moveCursor(1);return}if(De(e,"space")){let n=this.visibleItems[this.cursorIndex];n&&!this.authOnly&&this.toggleItem(n);return}if(this.keys.selectConfirm(e)){let n=this.visibleItems[this.cursorIndex];if(!n)return;let r=this.servers[n.serverIndex];if(!r)return;if(n.type==="server"){if(r.connectionStatus==="disabled")return;if(this.authOnly||r.connectionStatus==="needs-auth"){this.authenticateServer(r);return}r.expanded=!r.expanded,this.rebuildVisibleItems(),this.cursorIndex=Math.min(this.cursorIndex,Math.max(0,this.visibleItems.length-1))}else if(n.toolIndex!==void 0){let o=r.tools[n.toolIndex];if(!o)return;this.toggleToolDirect(r,o),o.isDirect&&r.source==="import"&&(this.importNotice=`Imported from ${Pe(r.importKind??"external")} \u2014 will copy to user config on save`),this.updateDirty()}return}if(De(e,"ctrl+a")){let n=this.visibleItems[this.cursorIndex];n&&this.authenticateSelectedServer(n);return}if(De(e,"ctrl+r")){let n=this.visibleItems[this.cursorIndex];if(!n)return;let r=this.servers[n.serverIndex];r&&this.reconnectServer(r);return}if(De(e,"ctrl+y")){let n=this.visibleItems[this.cursorIndex];if(!n)return;let r=this.servers[n.serverIndex];if(!r||r.connectionStatus!=="failed"||!r.failureMessage)return;let o=Pe(r.name),i=Pe(r.failureMessage);tv(i).then(()=>{this.authNotice=`Copied error for ${o} to clipboard`,this.tui.requestRender()}).catch(s=>{let a=Pe(s instanceof Error?s.message:String(s));this.authNotice=`Failed to copy error for ${o}: ${a}`,this.tui.requestRender()});return}if(e==="?"){if(this.authOnly)return;this.descSearchActive=!0,this.descQuery="",this.rebuildVisibleItems(),this.cursorIndex=Math.min(this.cursorIndex,Math.max(0,this.visibleItems.length-1));return}if(De(e,"backspace")){this.nameQuery.length>0&&(this.nameQuery=this.nameQuery.slice(0,-1),this.rebuildVisibleItems(),this.cursorIndex=Math.min(this.cursorIndex,Math.max(0,this.visibleItems.length-1)));return}if(e.length===1&&e.charCodeAt(0)>=32){this.nameQuery+=e,this.rebuildVisibleItems(),this.cursorIndex=Math.min(this.cursorIndex,Math.max(0,this.visibleItems.length-1));return}}authenticateSelectedServer(e){let n=this.servers[e.serverIndex];n&&this.authenticateServer(n)}authenticateServer(e){if(this.authInFlight||e.connectionStatus==="connecting"||e.connectionStatus==="disabled")return;let n=Pe(e.name);if(!this.callbacks.canAuthenticate(e.name)){this.authNotice=`${n} does not use OAuth authentication.`;return}this.authInFlight=e.name,this.authNotice=`Authenticating ${n}...`,this.tui.requestRender(),this.callbacks.authenticate(e.name).then(r=>{if(e.connectionStatus=this.callbacks.getConnectionStatus(e.name),r.ok){this.authNotice=`OAuth finished for ${n}. Reconnecting...`,this.authInFlight=null,this.tui.requestRender(),this.reconnectServer(e,{afterAuth:!0});return}let o=Pe(r.message);this.authNotice=`OAuth failed for ${n}${o?`: ${o}`:". Check the notification for details."}`,this.authInFlight=null,this.tui.requestRender()}).catch(r=>{let o=Pe(r instanceof Error?r.message:String(r));e.connectionStatus=this.callbacks.getConnectionStatus(e.name),this.authNotice=`OAuth failed for ${n}: ${o}`,this.authInFlight=null,this.tui.requestRender()})}reconnectServer(e,n={}){if(e.connectionStatus==="connecting"||e.connectionStatus==="disabled")return;let r=Pe(e.name);e.connectionStatus="connecting",this.tui.requestRender(),this.callbacks.reconnect(e.name).then(o=>{if(e.connectionStatus=this.callbacks.getConnectionStatus(e.name),e.failureMessage=this.callbacks.getFailureMessage?.(e.name)??null,e.connectionStatus==="connected"){let i=this.callbacks.refreshCacheAfterReconnect(e.name);i&&(this.cache??={version:1,servers:{}},this.cache.servers[e.name]=i,this.rebuildServerTools(e,i)),e.hasCachedData=!0}n.afterAuth&&(this.authNotice=o&&e.connectionStatus==="connected"?`OAuth finished for ${r}. Reconnected.`:`OAuth finished for ${r}, but reconnect did not complete. Press ctrl+r to retry.`),this.tui.requestRender()}).catch(o=>{e.connectionStatus="failed";let i=Pe(o instanceof Error?o.message:String(o));this.authNotice=`Reconnect failed for ${r}: ${i}`,this.tui.requestRender()})}toggleItem(e){if(this.authOnly)return;let n=this.servers[e.serverIndex];if(n){if(e.type==="server"){let r=!n.tools.every(i=>i.isDirect);n.source==="import"&&r&&(this.importNotice=`Imported from ${Pe(n.importKind??"external")} \u2014 will copy to user config on save`);let o=0;for(let i of n.tools)i.isDirect=r,r&&(o+=i.estimatedTokens);n.directCount=r?n.tools.length:0,n.directTokens=o}else if(e.toolIndex!==void 0){let r=n.tools[e.toolIndex];if(!r)return;this.toggleToolDirect(n,r),r.isDirect&&n.source==="import"&&(this.importNotice=`Imported from ${Pe(n.importKind??"external")} \u2014 will copy to user config on save`)}this.updateDirty()}}toggleToolDirect(e,n){n.isDirect=!n.isDirect,e.directCount+=n.isDirect?1:-1,e.directTokens+=n.isDirect?n.estimatedTokens:-n.estimatedTokens}handleDiscardInput(e){if(De(e,"ctrl+c")){this.cleanup(),this.done({cancelled:!0,changes:new Map});return}if(De(e,"escape")||e==="n"||e==="N"){this.confirmingDiscard=!1;return}if(this.keys.selectConfirm(e)){this.cleanup(),this.discardSelected===0?this.done({cancelled:!0,changes:new Map}):this.done(this.buildResult());return}if(e==="y"||e==="Y"){this.cleanup(),this.done({cancelled:!0,changes:new Map});return}(De(e,"left")||De(e,"right")||De(e,"tab"))&&(this.discardSelected=this.discardSelected===0?1:0)}moveCursor(e){this.visibleItems.length!==0&&(this.cursorIndex=Math.max(0,Math.min(this.visibleItems.length-1,this.cursorIndex+e)))}getOtherCurrentCandidates(e,n,r,o){let i=new Set;for(let[s,a]of Object.entries(this.config.mcpServers)){if(U(a))continue;let c=this.cache?.servers?.[s],u=s===e?r:c&&$e(c,a)?c:void 0;if(!u)continue;let d=pe(a,this.prefix);for(let l of u.tools??[])if(ke(l.uiVisibility))for(let f of ce(l.name,s,d,!1))i.add(f);if(a.exposeResources!==!1)for(let l of u.resources??[]){let f=`read_${Ce(l.name)}`;for(let p of ce(f,s,d,!1))i.add(p)}}for(let s of ce(o,e,pe(n,this.prefix),!1))i.delete(s);return i}rebuildServerTools(e,n){let r=new Map;for(let i of e.tools)r.set(i.name,i.isDirect);let o=[];for(let i of n.tools??[]){if(!ke(i.uiVisibility)||!Ee(i.name,e.name,this.prefix,e.includeTools,e.excludeTools,this.getOtherCurrentCandidates(e.name,e,n,i.name)))continue;let s=r.get(i.name),a=s!==void 0?s:!1;o.push({name:i.name,description:i.description??"",isDirect:a,wasDirect:s!==void 0?e.tools.find(c=>c.name===i.name)?.wasDirect??!1:!1,estimatedTokens:Jo(i)})}if(e.exposeResources)for(let i of n.resources??[]){let s=`read_${Ce(i.name)}`;if(!Ee(s,e.name,this.prefix,e.includeTools,e.excludeTools,this.getOtherCurrentCandidates(e.name,e,n,s)))continue;let a=r.get(s),c=a!==void 0?a:!1,u={name:s,...i.description!==void 0?{description:i.description}:{}};o.push({name:s,description:i.description??`Read resource: ${i.uri}`,isDirect:c,wasDirect:a!==void 0?e.tools.find(d=>d.name===s)?.wasDirect??!1:!1,estimatedTokens:Jo(u)})}e.tools=o,e.directCount=0,e.directTokens=0;for(let i of o)i.isDirect&&(e.directCount++,e.directTokens+=i.estimatedTokens);this.rebuildVisibleItems(),this.updateDirty()}render(e){let n=e-2,r=[],o=this.t,i=P=>`\x1B[1m${P}\x1B[22m`,s=P=>`\x1B[3m${P}\x1B[23m`,a=P=>`\x1B[7m${P}\x1B[27m`,c=P=>K(o.border,"\u2502")+Dl(" "+ov(P),n,"\u2026",!0)+K(o.border,"\u2502"),u=()=>K(o.border,"\u2502")+" ".repeat(n)+K(o.border,"\u2502"),d=()=>K(o.border,"\u251C"+"\u2500".repeat(n)+"\u2524"),l=this.authOnly?" MCP OAuth ":" MCP Servers ",f=n-Vn(l),p=Math.floor(f/2),g=f-p;r.push(K(o.border,"\u256D"+"\u2500".repeat(p))+K(o.title,l)+K(o.border,"\u2500".repeat(g)+"\u256E")),r.push(u());let y=K(o.selected,"\u2502"),w=K(o.border,"\u25CE");if(this.descSearchActive?r.push(c(`${w} ${K(o.needsAuth,"desc:")} ${this.descQuery}${y}`)):this.nameQuery?r.push(c(`${w} ${this.nameQuery}${y}`)):r.push(c(`${w} ${K(o.placeholder,s("search..."))}`)),r.push(u()),this.noticeLines.length>0){for(let P of this.noticeLines)r.push(c(K(o.hint,s(Pe(P)))));r.push(u())}if(r.push(d()),this.servers.length===0)r.push(u()),r.push(c(K(o.hint,s(this.authOnly?"No OAuth-capable MCP servers configured.":"No MCP servers configured.")))),r.push(u());else{let P=t.MAX_VISIBLE,C=this.visibleItems.length,E=Math.max(0,Math.min(this.cursorIndex-Math.floor(P/2),C-P)),L=Math.min(E+P,C);r.push(u());for(let H=E;H<L;H++){let $=this.visibleItems[H];if(!$)continue;let O=H===this.cursorIndex,T=this.servers[$.serverIndex];if(T){if($.type==="server"){if(r.push(c(this.renderServerRow(T,O))),O&&T.connectionStatus==="failed"&&T.failureMessage)for(let G of this.wrapText(Pe(T.failureMessage),n-6))r.push(c(` ${K(o.cancel,G)}`))}else if($.toolIndex!==void 0){let G=T.tools[$.toolIndex];G&&r.push(c(this.renderToolRow(G,O,n)))}}}if(r.push(u()),C>P){let H=Math.round((this.cursorIndex+1)/C*10);r.push(c(`${rv(H,10)} ${K(o.hint,`${this.cursorIndex+1}/${C}`)}`)),r.push(u())}this.importNotice&&(r.push(c(K(o.needsAuth,s(Pe(this.importNotice))))),r.push(u())),this.authNotice&&(r.push(c(K(o.needsAuth,s(Pe(this.authNotice))))),r.push(u()))}if(r.push(d()),r.push(u()),this.confirmingDiscard){let P=this.discardSelected===0?a(i(K(o.cancel," Discard "))):K(o.hint," Discard "),C=this.discardSelected===1?a(i(K(o.confirm," Keep & Close "))):K(o.hint," Keep & Close ");r.push(c(`Discard unsaved changes? ${P} ${C}`))}else if(this.authOnly)r.push(c(K(o.description,"select a server to authenticate")));else{let P=0,C=0;for(let L of this.servers)P+=L.directCount,C+=L.directTokens;let E=P>0?`${P} direct ~${C.toLocaleString()} tokens`:"no direct tools";r.push(c(K(o.description,E+(this.dirty?K(o.needsAuth," (unsaved)"):""))))}r.push(u());let b=this.keys.saveLabel(),v=this.authOnly?[s("\u2191\u2193")+" navigate",s("\u23CE")+" auth",s("ctrl+a")+" auth",s("esc")+" clear/close",s("ctrl+c")+" quit"]:[s("\u2191\u2193")+" navigate",s("space")+" toggle",s("\u23CE")+" expand/auth",s("ctrl+a")+" auth",s("ctrl+r")+" reconnect",...this.selectedServerHasFailureMessage()?[s("ctrl+y")+" copy error"]:[],s("?")+" desc search",...b?[s(b)+" save"]:[],s("esc")+" clear/close",s("ctrl+c")+" quit"],m=" ",S=2,R=n-2,h="",M=0;for(let P of v){let C=Vn(P),E=M===0?C:S+C;M>0&&M+E>R?(r.push(c(K(o.hint,h))),h=P,M=C):(h+=(M>0?m:"")+P,M+=E)}return h&&r.push(c(K(o.hint,h))),r.push(K(o.border,"\u2570"+"\u2500".repeat(n)+"\u256F")),r}renderServerRow(e,n){let r=this.t,o=w=>`\x1B[1m${w}\x1B[22m`,i=e.expanded?"\u25BE":"\u25B8",s=n?K(r.selected,i):K(r.border,e.expanded?i:"\xB7"),a=Pe(e.name),c=Pe(e.importKind??"import"),u=n?o(K(r.selected,a)):a,d=e.source==="import"?K(r.description,` (${c})`):"",l=this.renderConnectionStatus(e);if(!e.hasCachedData&&!this.authOnly)return`${s} ${u}${d} ${K(r.description,"(not cached)")}${l}`;let f=e.directCount,p=e.tools.length,g=K(r.description,"\u25CB");f===p&&p>0?g=K(r.direct,"\u25CF"):f>0&&(g=K(r.needsAuth,"\u25D0"));let y="";return p>0&&(y=`${f}/${p}`,f>0&&(y+=` ~${e.directTokens.toLocaleString()}`),y=K(r.description,y)),`${s} ${g} ${u}${d} ${y}${l}`}selectedServerHasFailureMessage(){let e=this.visibleItems[this.cursorIndex];if(!e)return!1;let n=this.servers[e.serverIndex];return n?.connectionStatus==="failed"&&!!n.failureMessage}wrapText(e,n){let r=Math.max(8,n),o=e.split(/\s+/).filter(Boolean),i=[],s="",a=c=>{let u=c;for(;Vn(u)>r;){let d="",l=0;for(;l<u.length&&Vn(d+u.charAt(l))<=r;)d+=u.charAt(l),l++;d||(d=u.charAt(0)),i.push(d),u=u.slice(d.length)}return u};for(let c of o){let u=s?`${s} ${c}`:c;Vn(u)<=r?s=u:(s&&i.push(s),s=a(c))}return s&&i.push(s),i.length>0?i:[e]}renderConnectionStatus(e){let n=this.t;return this.authInFlight===e.name?` ${K(n.needsAuth,"authenticating")}`:e.connectionStatus==="disabled"?` ${K(n.description,"disabled")}`:e.connectionStatus==="needs-auth"?` ${K(n.needsAuth,"needs auth")}`:e.connectionStatus==="connecting"?` ${K(n.needsAuth,"connecting")}`:e.connectionStatus==="failed"?` ${K(n.cancel,"failed")}`:this.authOnly&&e.connectionStatus==="connected"?` ${K(n.direct,"connected")}`:this.authOnly?` ${K(n.description,"idle")}`:""}renderToolRow(e,n,r){let o=this.t,i=g=>`\x1B[1m${g}\x1B[22m`,s=e.isDirect?K(o.direct,"\u25CF"):K(o.description,"\u25CB"),a=n?K(o.selected,"\u25B8"):" ",c=Pe(e.name),u=Pe(e.description),d=n?i(K(o.selected,c)):c,l=7+Vn(c),f=Math.max(0,r-l-8),p=f>5&&u?K(o.description,"\u2014 "+Dl(u,f,"\u2026")):"";return` ${a} ${s} ${d} ${p}`}invalidate(){}dispose(){this.cleanup()}}});import{Type as oe}from"typebox";ue();Tn();ue();Tn();import{existsSync as By}from"node:fs";var pt=class extends Error{code;context;recoveryHint;cause;constructor(e,n){super(e),this.name="McpUiError",this.code=n.code,this.context=n.context??{},this.recoveryHint=n.recoveryHint,this.cause=n.cause,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}toJSON(){return{name:this.name,code:this.code,message:this.message,context:this.context,recoveryHint:this.recoveryHint,stack:this.stack}}},co=class extends pt{constructor(e,n,r){super(`Failed to fetch UI resource "${e}": ${n}`,{code:"RESOURCE_FETCH_ERROR",context:{uri:e,...r?.server!==void 0?{server:r.server}:{}},recoveryHint:"Check that the MCP server is connected and the resource URI is valid.",...r?.cause!==void 0?{cause:r.cause}:{}}),this.name="ResourceFetchError"}},An=class extends pt{constructor(e,n,r){super(`Invalid UI resource "${e}": ${n}`,{code:"RESOURCE_PARSE_ERROR",context:{uri:e,...r?.server!==void 0?{server:r.server}:{},...r?.mimeType!==void 0?{mimeType:r.mimeType}:{}},recoveryHint:"Ensure the resource returns valid HTML with the correct MIME type."}),this.name="ResourceParseError"}};var pr=class extends pt{denied;constructor(e,n){let r=n.denied?`Tool calls for "${e}" were denied for this session`:`Tool call approval required for "${e}"`;super(r,{code:n.denied?"CONSENT_DENIED":"CONSENT_REQUIRED",context:{server:e},recoveryHint:n.denied?"The user denied tool access. Start a new session to try again.":"Prompt the user for consent before calling tools."}),this.name="ConsentError",this.denied=n.denied??!1}};var gr=class extends pt{constructor(e,n){super(`UI server error: ${e}`,{code:"SERVER_ERROR",context:n?.port!==void 0?{port:n.port}:{},recoveryHint:"Check if the port is available. Another process may be using it.",...n?.cause!==void 0?{cause:n.cause}:{}}),this.name="ServerError"}};function Ec(t,e){if(t instanceof pt)return new pt(t.message,{code:t.code,context:{...t.context,...e},...t.recoveryHint!==void 0?{recoveryHint:t.recoveryHint}:{},...t.cause!==void 0?{cause:t.cause}:{}});let n=t instanceof Error?t:void 0,r=t instanceof Error?t.message:String(t);return new pt(r,{code:"UNKNOWN_ERROR",...e!==void 0?{context:e}:{},...n!==void 0?{cause:n}:{}})}var kc={debug:0,info:1,warn:2,error:3},Hp={debug:"[MCP-UI:DEBUG]",info:"[MCP-UI]",warn:"[MCP-UI:WARN]",error:"[MCP-UI:ERROR]"},Ni=class{minLevel="info";handlers=[];defaultContext={};setLevel(e){this.minLevel=e}setDefaultContext(e){this.defaultContext=e}addHandler(e){this.handlers.push(e)}clearHandlers(){this.handlers=[]}shouldLog(e){return kc[e]>=kc[this.minLevel]}emit(e,n,r,o){if(!this.shouldLog(e))return;let i={level:e,message:n,context:{...this.defaultContext,...r},...o!==void 0?{error:o}:{},timestamp:new Date},s=Hp[e],a=Fp(i.context),c=a?`${s} ${n} ${a}`:`${s} ${n}`;e==="error"?console.error(c,o??""):e==="warn"?console.warn(c):e==="debug"?console.debug(c):console.log(c);for(let u of this.handlers)try{u(i)}catch{}}debug(e,n){this.emit("debug",e,n)}info(e,n){this.emit("info",e,n)}warn(e,n){this.emit("warn",e,n)}error(e,n,r){this.emit("error",e,r,n)}child(e){return new Li(this,e)}},Li=class t{constructor(e,n){this.parent=e;this.context=n}parent;context;debug(e,n){this.parent.debug(e,{...this.context,...n})}info(e,n){this.parent.info(e,{...this.context,...n})}warn(e,n){this.parent.warn(e,{...this.context,...n})}error(e,n,r){this.parent.error(e,n,{...this.context,...r})}child(e){return new t(this.parent,{...this.context,...e})}};function Fp(t){if(!t||Object.keys(t).length===0)return"";let e=[];for(let[n,r]of Object.entries(t))r!=null&&e.push(`${n}=${typeof r=="string"?r:JSON.stringify(r)}`);return e.length>0?`(${e.join(", ")})`:""}var X=new Ni;(process.env.MCP_UI_DEBUG==="1"||process.env.MCP_UI_DEBUG==="true")&&X.setLevel("debug");var uo=class{constructor(e="once-per-server"){this.mode=e;this.log.debug("Initialized",{mode:e})}mode;approvedServers=new Set;deniedServers=new Set;log=X.child({component:"ConsentManager"});requiresPrompt(e){return this.mode==="never"?!1:this.deniedServers.has(e)||this.mode==="always"?!0:!this.approvedServers.has(e)}shouldCacheConsent(){return this.mode!=="always"}registerDecision(e,n){if(this.deniedServers.delete(e),this.approvedServers.delete(e),n){this.approvedServers.add(e),this.log.debug("Consent granted",{server:e});return}this.deniedServers.add(e),this.log.debug("Consent denied",{server:e})}ensureApproved(e){if(this.mode!=="never"){if(this.deniedServers.has(e))throw new pr(e,{denied:!0});if(!this.approvedServers.has(e))throw new pr(e,{requiresApproval:!0});this.mode==="always"&&this.approvedServers.delete(e)}}clear(e){if(e){this.approvedServers.delete(e),this.deniedServers.delete(e),this.log.debug("Cleared consent for server",{server:e});return}this.approvedServers.clear(),this.deniedServers.clear(),this.log.debug("Cleared all consent records")}};ue();import{SdkError as wy,SdkErrorCode as pl}from"@modelcontextprotocol/client";import{mkdirSync as ey,statSync as ty}from"node:fs";import{isDeepStrictEqual as ul}from"node:util";import{Client as ny,SdkError as ry,SdkErrorCode as oy,SdkHttpError as Is,SSEClientTransport as iy,StreamableHTTPClientTransport as sy,UnauthorizedError as ay}from"@modelcontextprotocol/client";import{StdioClientTransport as cy}from"@modelcontextprotocol/client/stdio";import{createConnection as zp}from"node:net";import{ReadBuffer as qp,serializeMessage as Vp}from"@modelcontextprotocol/client";var lo=class{constructor(e){this.socketPath=e}socketPath;socket;readBuffer=new qp;onclose;onerror;onmessage;async start(){if(this.socket)throw new Error("UnixSocketClientTransport already started");await new Promise((e,n)=>{let r=zp(this.socketPath);this.socket=r;let o=!1;r.once("connect",()=>{o=!0,e()}),r.on("data",i=>{try{for(this.readBuffer.append(i);;){let s=this.readBuffer.readMessage();if(s===null)break;this.onmessage?.(s)}}catch(s){let a=s instanceof Error?s:new Error(String(s));this.onerror?.(a),this.close()}}),r.on("error",i=>{o||n(i),this.onerror?.(i)}),r.on("close",()=>{this.socket===r&&(this.socket=void 0),this.readBuffer.clear(),this.onclose?.()})})}async close(){let e=this.socket;this.socket=void 0,this.readBuffer.clear(),!(!e||e.destroyed)&&await new Promise(n=>{let r=setTimeout(()=>e.destroy(),2e3);r.unref(),e.once("close",()=>{clearTimeout(r),n()}),e.end()})}async send(e){let n=this.socket;if(!n||n.destroyed)throw new Error("Unix socket is not connected");await new Promise((r,o)=>{n.write(Vp(e),i=>{i?o(i):r()})})}};var po="2026-07-28",Kp="2025-06-18",Oc="application/json, text/event-stream",Jp="text/event-stream",Wp=new Set([400,401,404,405,406,415]),Gp=new Set([404,405,406,415]),Yp=new Set([202,401,503]),Xp={jsonrpc:"2.0",id:1,method:"server/discover",params:{}},Qp={jsonrpc:"2.0",id:1,method:"initialize",params:{protocolVersion:Kp,capabilities:{},clientInfo:{name:"pi-mcp-probe",version:"2.1.2"}}},Zp={kind:"modern",request:{method:"POST",headers:{Accept:Oc,"Content-Type":"application/json","MCP-Protocol-Version":po,"Mcp-Method":"server/discover"},body:JSON.stringify(Xp)},allowJson:!0},eg={kind:"legacy-post",request:{method:"POST",headers:{Accept:Oc,"Content-Type":"application/json"},body:JSON.stringify(Qp)},allowJson:!0},tg={kind:"legacy-sse",request:{headers:{Accept:Jp}},allowJson:!1};function ng(t){if(typeof t!="object"||t===null||t.jsonrpc!=="2.0")return null;if("result"in t){let e=t.result;return{kind:"result",protocolVersion:typeof e=="object"&&e!==null?e.protocolVersion:void 0}}return"error"in t?{kind:"error"}:null}function rg(t){return/(?:^|,)\s*Bearer\b/i.test(t.headers.get("www-authenticate")??"")}function og(t){let e=t.headers.get("content-type")?.split(";",1)[0]?.trim().toLowerCase();return e==="text/html"?"HTML":e||"an untyped response"}async function ig(t){try{return ng(JSON.parse(await t.text()))}catch{return null}}async function sg(t,e){let n=t.headers.get("content-type")?.toLowerCase().startsWith("text/event-stream");if(t.ok&&n)return{kind:"mcp",result:{isMcp:!0,classification:"endpoint responded with an MCP event stream"}};let r=e.allowJson||t.status===401?await ig(t):null;return t.ok&&e.allowJson&&r?e.kind==="modern"&&(r.kind==="error"||r.protocolVersion!==po)?{kind:"unsupported-modern"}:{kind:"mcp",result:{isMcp:!0,classification:e.kind==="modern"?`endpoint supports stateless MCP ${po} server/discover`:"endpoint responded with a JSON-RPC 2.0 envelope"}}:t.status===401&&rg(t)&&r?{kind:"mcp",result:{isMcp:!0,classification:e.kind==="modern"?`endpoint requires Bearer authentication during MCP ${po} server/discover probing`:"endpoint requires Bearer authentication and responded with a JSON-RPC 2.0 error"}}:{kind:"unrecognized"}}async function ji(t,e){let n=await fetch(t,{...e.request,signal:AbortSignal.timeout(5e3)});return{response:n,outcome:await sg(n,e)}}function go(t){let e=`endpoint returned ${og(t)} (${t.status})`;return{isMcp:!1,classification:t.status===503?`${e} \u2014 server is temporarily unavailable; MCP endpoint shape could not be determined`:t.status===202?`${e} \u2014 MCP endpoint shape could not be determined`:t.status===401?`${e} \u2014 authentication may be required; MCP endpoint shape could not be determined`:`${e} \u2014 this URL does not appear to speak MCP`}}function fo(t){return Yp.has(t.status)?go(t):void 0}async function $c(t){let{response:e,outcome:n}=await ji(t,Zp);if(n.kind==="mcp")return n.result;let r=fo(e);if(n.kind!=="unsupported-modern"&&!Wp.has(e.status))return r??go(e);let{response:o,outcome:i}=await ji(t,eg);if(i.kind==="mcp")return i.result;if(r??=fo(o),!Gp.has(o.status))return fo(o)??r??go(o);let{response:s,outcome:a}=await ji(t,tg);return a.kind==="mcp"?a.result:fo(s)??r??go(s)}ue();tt();import{existsSync as Jt,readFileSync as Hi,realpathSync as ag,readdirSync as cg,statSync as ug,writeFileSync as Dc,renameSync as lg,mkdirSync as dg,openSync as fg,readSync as pg,closeSync as gg,unlinkSync as mg}from"node:fs";import{join as Kt,dirname as hg,extname as yg,resolve as vg,sep as Ic}from"node:path";function D(t){if(t?.aborted)throw t.reason instanceof Error?t.reason:new Error(String(t.reason??"MCP request aborted"))}async function ve(t,e){return e?(D(e),await new Promise((n,r)=>{let o=!1,i=()=>e.removeEventListener("abort",s),s=()=>{o||(o=!0,i(),r(e.reason instanceof Error?e.reason:new Error(String(e.reason??"MCP request aborted"))))};e.addEventListener("abort",s,{once:!0}),t.then(a=>{o||(o=!0,i(),n(a))},a=>{o||(o=!0,i(),r(a))})})):t}import Nc from"cross-spawn";var Bi=2,Sg=1440*60*1e3,wg=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z][0-9A-Za-z.-]*)?(?:\+[0-9A-Za-z][0-9A-Za-z.-]*)?$/;async function Lc(t,e,n){D(n);let r=t==="npx"?bg(e):t==="npm"?Cg(e):null;if(!r)return null;let o=jc(r.packageSpec),i=JSON.stringify([t,r.packageSpec,r.binName??""]),a=$g()?.entries?.[i];if(a&&Date.now()-a.resolvedAt<Sg&&Jt(a.resolvedBin)&&(!o?.exactVersion||a.packageVersion===o.exactVersion))return{binPath:a.resolvedBin,extraArgs:r.extraArgs,isJs:a.isJs};let c=_c(r.packageSpec,r.binName);if(c)return Uc(i,c),{binPath:c.resolvedBin,extraArgs:r.extraArgs,isJs:c.isJs};await Mg(r.packageSpec,n);let u=_c(r.packageSpec,r.binName);return u?(Uc(i,u),{binPath:u.resolvedBin,extraArgs:r.extraArgs,isJs:u.isJs}):null}function bg(t){let e=t.indexOf("--"),n=e>=0?t.slice(0,e):t,r=e>=0?t.slice(e+1):[],o=[],i,s=!1,a=!1;for(let l=0;l<n.length;l++){let f=n[l];if(f===void 0)return null;if(a){o.push(f);continue}if(!(f==="-y"||f==="--yes")){if(f==="-p"||f==="--package"){let p=n[l+1];if(!p||p.startsWith("-"))return null;i||(i=p),s=!0,l++;continue}if(f.startsWith("--package=")){let p=f.slice(10);if(!p)return null;i||(i=p),s=!0;continue}if(f.startsWith("-"))return null;o.push(f),a=!0}}let c=e>=0&&r.length>0?["--",...r]:r;if(s){let l=o[0];if(!i||!l)return null;let f=o.slice(1).concat(c);return{packageSpec:i,binName:l,extraArgs:f}}let u=o[0];if(!u)return null;let d=o.slice(1).concat(c);return{packageSpec:u,extraArgs:d}}function Cg(t){if(t[0]!=="exec")return null;let e=t.slice(1),n=e.indexOf("--");if(n<0)return null;let r=e.slice(0,n),o=e.slice(n+1),i;for(let c=0;c<r.length;c++){let u=r[c];if(u===void 0)return null;if(!(u==="-y"||u==="--yes")){if(u==="--package"){let d=r[c+1];if(!d||d.startsWith("-"))return null;i||(i=d),c++;continue}if(u.startsWith("--package=")){let d=u.slice(10);if(!d)return null;i||(i=d);continue}if(u.startsWith("-"))return null}}let s=o[0];if(!i||!s)return null;let a=o.slice(1);return{packageSpec:i,binName:s,extraArgs:a}}function _c(t,e){let n=kg();if(!n)return null;let r=jc(t);if(!r)return null;let{packageName:o,exactVersion:i}=r,s=Pg(n,o,i);if(!s)return null;let a=Kt(s,"package.json");if(!Jt(a))return null;let c=null;try{c=JSON.parse(Hi(a,"utf-8"))}catch{return null}let u=c?.bin;if(!u)return null;let d=Tg(o,e),l,f;if(typeof u=="string")l=Ag(o),f=u;else{for(let b of d)if(u[b]){l=b,f=u[b];break}if(!f){let b=Object.entries(u)[0];b&&(l=b[0],f=b[1])}}if(!f)return null;let p=Rg(s),g=l?Kt(p,".bin",l):null,y=g&&Jt(g)?Ig(g):"";if(!y&&(y=vg(s,f),!Jt(y)))return null;let w=Eg(y);return{resolvedBin:y,resolvedAt:Date.now(),...c?.version!==void 0?{packageVersion:c.version}:{},isJs:w}}var xg=3e4;async function Mg(t,e){D(e);try{await new Promise((n,r)=>{let o=Nc("npm",["exec","--yes","--package",t,"--","node","-e","1"],{stdio:"ignore"}),i=setTimeout(()=>{o.kill(),r(new Error("timeout"))},xg),s=()=>{o.kill(),r(e?.reason instanceof Error?e.reason:new Error("MCP request aborted"))};e?.addEventListener("abort",s,{once:!0}),i.unref(),o.on("close",()=>{clearTimeout(i),e?.removeEventListener("abort",s),n()}),o.on("error",a=>{clearTimeout(i),e?.removeEventListener("abort",s),r(a)})})}catch{e?.aborted&&D(e)}D(e)}function Tg(t,e){let n=[];if(e&&n.push(e),t.startsWith("@")){let r=t.split("/")[1]??"",o=t.split("/")[0]?.replace("@","")??"";r&&n.push(r),o&&r&&n.push(`${o}-${r}`)}else n.push(t);return[...new Set(n.filter(Boolean))]}function jc(t){let e=t.trim();if(!e)return null;let n,r;if(e.startsWith("@")){let i=e.indexOf("/");if(i<0)return null;let s=e.lastIndexOf("@");s>i?(n=e.slice(0,s),r=e.slice(s+1)):n=e}else{let i=e.indexOf("@");i>=0?(n=e.slice(0,i),r=e.slice(i+1)):n=e}if(!n)return null;let o=r?.replace(/^=/,"").replace(/^v/i,"");return{packageName:n,...o&&wg.test(o)?{exactVersion:o}:{}}}function Ag(t){return t.startsWith("@")?t.split("/")[1]??t.replace("@","").replace("/","-"):t}function Pg(t,e,n){let r=Kt(t,"_npx");if(!Jt(r))return null;let o=e.startsWith("@")?e.split("/"):[e],i=cg(r,{withFileTypes:!0}).filter(s=>s.isDirectory()).map(s=>{let a=Kt(r,s.name),c=_g(a);return{name:s.name,mtime:c}}).sort((s,a)=>a.mtime-s.mtime);for(let s of i){let a=Kt(r,s.name,"node_modules",...o),c=Kt(a,"package.json");if(Jt(c)){if(n)try{if(JSON.parse(Hi(c,"utf-8")).version!==n)continue}catch{continue}return a}}return null}function Rg(t){let e=t.split(Ic),n=e.lastIndexOf("node_modules");return n>=0?e.slice(0,n+1).join(Ic):Kt(t,"..")}function Eg(t){let e=yg(t).toLowerCase();if(e===".js"||e===".mjs"||e===".cjs")return!0;try{let n=fg(t,"r");try{let r=Buffer.alloc(256);pg(n,r,0,256,0);let o=r.toString("utf-8").split(`
|
|
10
|
+
`),a=18,c=s.slice(0,a);for(let u of c)i.push(...vt(u,o));return s.length>a&&i.push(...vt(`\u2026 ${s.length-a} more diff line${s.length-a===1?"":"s"}`,o)),i}padLine(e,n){let o=Math.max(0,n-4),i=$l(e,o,"\u2026",!0),s=Il(i),a=Math.max(0,o-s);return`\u2502${" ".repeat(2)}${i}${" ".repeat(a)}${" ".repeat(2)}\u2502`}invalidate(){}dispose(){this.cleanup()}}});var Ys={};Ea(Ys,{createMcpPanel:()=>iv});import{matchesKey as De,truncateToWidth as Dl,visibleWidth as Vn}from"@earendil-works/pi-tui";import{copyToClipboard as tv}from"./vendor/pi-coding-agent.js";function K(t,e){return t?`\x1B[${t}m${e}\x1B[0m`:e}function rv(t,e){let n=[];for(let r=0;r<e;r++){let o=Nl[r%Nl.length];o&&n.push(K(o,r<t?"\u25CF":"\u25CB"))}return n.join(" ")}function Ko(t,e){let n=t.toLowerCase(),r=e.toLowerCase();if(r.includes(n))return 100+n.length/r.length*50;let o=0,i=0,s=0;for(let a=0;a<r.length&&i<n.length;a++)r[a]===n[i]?(o+=10+s,s+=5,i++):s=0;return i===n.length?o:0}function Pe(t){return de(t??"")}function ov(t){let e=Ei(t),n="",r=!1;for(let o=0;o<e.length;o++){let s=e.slice(o).match(/^(?:\x1b\[[0-?]*[ -/]*[@-~]|\x1b[@-Z\\-_])/);if(s){n+=s[0],o+=s[0].length-1;continue}let a=e.charCodeAt(o);if(a<=31||a===127||a>=128&&a<=159){r=!0;continue}r&&n&&!n.endsWith(" ")&&(n+=" "),r=!1,n+=e[o]}return n}function Jo(t){let e=JSON.stringify(t.inputSchema??{}).length,n=t.description?.length??0;return Math.ceil((t.name.length+n+e)/4)+10}function iv(t,e,n,r,o,i,s){return new Gs(t,e,n,r,o,i,s??{})}var nv,Nl,Gs,Xs=je(()=>{Js();ue();It();be();nt();en();nv={border:"2",title:"2",selected:"36",direct:"32",needsAuth:"33",placeholder:"2;3",description:"2",hint:"2",confirm:"32",cancel:"31"};Nl=["38;2;178;129;214","38;2;215;135;175","38;2;254;188;56","38;2;228;192;15","38;2;137;210;129","38;2;0;175;175","38;2;23;143;185"];Gs=class t{constructor(e,n,r,o,i,s,a={}){this.config=e;this.cache=n;this.callbacks=o;this.done=s;this.tui=i,this.noticeLines=a.noticeLines??[],this.authOnly=a.authOnly===!0,this.keys=Fo(a.keybindings),this.prefix=e.settings?.toolPrefix??"server";for(let[c,u]of Object.entries(e.mcpServers)){if(this.authOnly&&!o.canAuthenticate(c))continue;let d=r.get(c),l=this.cache?.servers?.[c],f=l&&$e(l,u)?l:void 0,p=e.settings?.directTools,g=!1;u.directTools!==void 0?g=u.directTools:p&&(g=p);let y=[];if(f&&!this.authOnly&&!U(u)){for(let S of f.tools??[]){if(!ke(S.uiVisibility)||!Ee(S.name,c,this.prefix,u.includeTools,u.excludeTools,this.getOtherCurrentCandidates(c,u,f,S.name)))continue;let R=g===!0||Array.isArray(g)&&g.includes(S.name);y.push({name:S.name,description:S.description??"",isDirect:R,wasDirect:R,estimatedTokens:Jo(S)})}if(u.exposeResources!==!1)for(let S of f.resources??[]){let R=`read_${Ce(S.name)}`;if(!Ee(R,c,this.prefix,u.includeTools,u.excludeTools,this.getOtherCurrentCandidates(c,u,f,R)))continue;let h=g===!0||Array.isArray(g)&&g.includes(R),M={name:R,...S.description!==void 0?{description:S.description}:{}};y.push({name:R,description:S.description??`Read resource: ${S.uri}`,isDirect:h,wasDirect:h,estimatedTokens:Jo(M)})}}let w=o.getConnectionStatus(c),b=o.getFailureMessage?.(c)??null,v=0,m=0;for(let S of y)S.isDirect&&(v++,m+=S.estimatedTokens);this.servers.push({name:c,expanded:!1,source:d?.kind??"user",...d?.importKind!==void 0?{importKind:d.importKind}:{},...u.includeTools!==void 0?{includeTools:u.includeTools}:{},...u.excludeTools!==void 0?{excludeTools:u.excludeTools}:{},exposeResources:u.exposeResources!==!1,connectionStatus:w,failureMessage:b,tools:y,directCount:v,directTokens:m,hasCachedData:!!f})}this.rebuildVisibleItems(),this.resetInactivityTimeout()}config;cache;callbacks;done;noticeLines;prefix;servers=[];cursorIndex=0;nameQuery="";descSearchActive=!1;descQuery="";dirty=!1;confirmingDiscard=!1;discardSelected=1;importNotice=null;authNotice=null;authInFlight=null;inactivityTimeout=null;visibleItems=[];tui;t=nv;authOnly;keys;static MAX_VISIBLE=12;static INACTIVITY_MS=6e4;resetInactivityTimeout(){this.inactivityTimeout&&clearTimeout(this.inactivityTimeout),this.inactivityTimeout=setTimeout(()=>{this.cleanup(),this.done({cancelled:!0,changes:new Map})},t.INACTIVITY_MS)}cleanup(){this.inactivityTimeout&&(clearTimeout(this.inactivityTimeout),this.inactivityTimeout=null)}rebuildVisibleItems(){let e=this.descSearchActive?this.descQuery:this.nameQuery,n=this.descSearchActive?"desc":"name";this.visibleItems=[];for(let r=0;r<this.servers.length;r++){let o=this.servers[r];if(o){if(e&&this.authOnly){(n==="name"?Ko(e,o.name):0)>0&&this.visibleItems.push({type:"server",serverIndex:r});continue}if(this.visibleItems.push({type:"server",serverIndex:r}),o.expanded||e)for(let i=0;i<o.tools.length;i++){let s=o.tools[i];s&&(e&&(n==="name"?Math.max(Ko(e,s.name),Ko(e,o.name)*.6):Ko(e,s.description))===0||this.visibleItems.push({type:"tool",serverIndex:r,toolIndex:i}))}}}e&&!this.authOnly&&(this.visibleItems=this.visibleItems.filter(r=>r.type==="server"?this.visibleItems.some(o=>o.type==="tool"&&o.serverIndex===r.serverIndex):!0))}updateDirty(){this.dirty=this.servers.some(e=>e.tools.some(n=>n.isDirect!==n.wasDirect))}buildResult(){let e=new Map;for(let n of this.servers){if(!n.tools.some(i=>i.isDirect!==i.wasDirect))continue;let o=n.tools.filter(i=>i.isDirect);o.length===n.tools.length&&n.tools.length>0?e.set(n.name,!0):o.length===0?e.set(n.name,!1):e.set(n.name,o.map(i=>i.name))}return{changes:e,cancelled:!1}}handleInput(e){if(this.resetInactivityTimeout(),this.importNotice=null,this.authInFlight||(this.authNotice=null),this.confirmingDiscard){this.handleDiscardInput(e);return}if(De(e,"ctrl+c")){this.cleanup(),this.done({cancelled:!0,changes:new Map});return}if(this.keys.save(e)){this.cleanup(),this.done(this.buildResult());return}if(this.descSearchActive){if(De(e,"escape")||this.keys.selectConfirm(e)){this.descSearchActive=!1,this.descQuery="",this.rebuildVisibleItems(),this.cursorIndex=Math.min(this.cursorIndex,Math.max(0,this.visibleItems.length-1));return}if(De(e,"backspace")){this.descQuery.length>0&&(this.descQuery=this.descQuery.slice(0,-1),this.rebuildVisibleItems(),this.cursorIndex=Math.min(this.cursorIndex,Math.max(0,this.visibleItems.length-1)));return}if(this.keys.selectUp(e)){this.moveCursor(-1);return}if(this.keys.selectDown(e)){this.moveCursor(1);return}if(De(e,"space")){let n=this.visibleItems[this.cursorIndex];n&&this.toggleItem(n);return}if(e.length===1&&e.charCodeAt(0)>=32){this.descQuery+=e,this.rebuildVisibleItems(),this.cursorIndex=Math.min(this.cursorIndex,Math.max(0,this.visibleItems.length-1));return}return}if(De(e,"escape")){if(this.nameQuery){this.nameQuery="",this.rebuildVisibleItems(),this.cursorIndex=Math.min(this.cursorIndex,Math.max(0,this.visibleItems.length-1));return}if(this.dirty){this.confirmingDiscard=!0,this.discardSelected=1;return}this.cleanup(),this.done({cancelled:!0,changes:new Map});return}if(this.keys.selectUp(e)){this.moveCursor(-1);return}if(this.keys.selectDown(e)){this.moveCursor(1);return}if(De(e,"space")){let n=this.visibleItems[this.cursorIndex];n&&!this.authOnly&&this.toggleItem(n);return}if(this.keys.selectConfirm(e)){let n=this.visibleItems[this.cursorIndex];if(!n)return;let r=this.servers[n.serverIndex];if(!r)return;if(n.type==="server"){if(r.connectionStatus==="disabled")return;if(this.authOnly||r.connectionStatus==="needs-auth"){this.authenticateServer(r);return}r.expanded=!r.expanded,this.rebuildVisibleItems(),this.cursorIndex=Math.min(this.cursorIndex,Math.max(0,this.visibleItems.length-1))}else if(n.toolIndex!==void 0){let o=r.tools[n.toolIndex];if(!o)return;this.toggleToolDirect(r,o),o.isDirect&&r.source==="import"&&(this.importNotice=`Imported from ${Pe(r.importKind??"external")} \u2014 will copy to user config on save`),this.updateDirty()}return}if(De(e,"ctrl+a")){let n=this.visibleItems[this.cursorIndex];n&&this.authenticateSelectedServer(n);return}if(De(e,"ctrl+r")){let n=this.visibleItems[this.cursorIndex];if(!n)return;let r=this.servers[n.serverIndex];r&&this.reconnectServer(r);return}if(De(e,"ctrl+y")){let n=this.visibleItems[this.cursorIndex];if(!n)return;let r=this.servers[n.serverIndex];if(!r||r.connectionStatus!=="failed"||!r.failureMessage)return;let o=Pe(r.name),i=Pe(r.failureMessage);tv(i).then(()=>{this.authNotice=`Copied error for ${o} to clipboard`,this.tui.requestRender()}).catch(s=>{let a=Pe(s instanceof Error?s.message:String(s));this.authNotice=`Failed to copy error for ${o}: ${a}`,this.tui.requestRender()});return}if(e==="?"){if(this.authOnly)return;this.descSearchActive=!0,this.descQuery="",this.rebuildVisibleItems(),this.cursorIndex=Math.min(this.cursorIndex,Math.max(0,this.visibleItems.length-1));return}if(De(e,"backspace")){this.nameQuery.length>0&&(this.nameQuery=this.nameQuery.slice(0,-1),this.rebuildVisibleItems(),this.cursorIndex=Math.min(this.cursorIndex,Math.max(0,this.visibleItems.length-1)));return}if(e.length===1&&e.charCodeAt(0)>=32){this.nameQuery+=e,this.rebuildVisibleItems(),this.cursorIndex=Math.min(this.cursorIndex,Math.max(0,this.visibleItems.length-1));return}}authenticateSelectedServer(e){let n=this.servers[e.serverIndex];n&&this.authenticateServer(n)}authenticateServer(e){if(this.authInFlight||e.connectionStatus==="connecting"||e.connectionStatus==="disabled")return;let n=Pe(e.name);if(!this.callbacks.canAuthenticate(e.name)){this.authNotice=`${n} does not use OAuth authentication.`;return}this.authInFlight=e.name,this.authNotice=`Authenticating ${n}...`,this.tui.requestRender(),this.callbacks.authenticate(e.name).then(r=>{if(e.connectionStatus=this.callbacks.getConnectionStatus(e.name),r.ok){this.authNotice=`OAuth finished for ${n}. Reconnecting...`,this.authInFlight=null,this.tui.requestRender(),this.reconnectServer(e,{afterAuth:!0});return}let o=Pe(r.message);this.authNotice=`OAuth failed for ${n}${o?`: ${o}`:". Check the notification for details."}`,this.authInFlight=null,this.tui.requestRender()}).catch(r=>{let o=Pe(r instanceof Error?r.message:String(r));e.connectionStatus=this.callbacks.getConnectionStatus(e.name),this.authNotice=`OAuth failed for ${n}: ${o}`,this.authInFlight=null,this.tui.requestRender()})}reconnectServer(e,n={}){if(e.connectionStatus==="connecting"||e.connectionStatus==="disabled")return;let r=Pe(e.name);e.connectionStatus="connecting",this.tui.requestRender(),this.callbacks.reconnect(e.name).then(o=>{if(e.connectionStatus=this.callbacks.getConnectionStatus(e.name),e.failureMessage=this.callbacks.getFailureMessage?.(e.name)??null,e.connectionStatus==="connected"){let i=this.callbacks.refreshCacheAfterReconnect(e.name);i&&(this.cache??={version:1,servers:{}},this.cache.servers[e.name]=i,this.rebuildServerTools(e,i)),e.hasCachedData=!0}n.afterAuth&&(this.authNotice=o&&e.connectionStatus==="connected"?`OAuth finished for ${r}. Reconnected.`:`OAuth finished for ${r}, but reconnect did not complete. Press ctrl+r to retry.`),this.tui.requestRender()}).catch(o=>{e.connectionStatus="failed";let i=Pe(o instanceof Error?o.message:String(o));this.authNotice=`Reconnect failed for ${r}: ${i}`,this.tui.requestRender()})}toggleItem(e){if(this.authOnly)return;let n=this.servers[e.serverIndex];if(n){if(e.type==="server"){let r=!n.tools.every(i=>i.isDirect);n.source==="import"&&r&&(this.importNotice=`Imported from ${Pe(n.importKind??"external")} \u2014 will copy to user config on save`);let o=0;for(let i of n.tools)i.isDirect=r,r&&(o+=i.estimatedTokens);n.directCount=r?n.tools.length:0,n.directTokens=o}else if(e.toolIndex!==void 0){let r=n.tools[e.toolIndex];if(!r)return;this.toggleToolDirect(n,r),r.isDirect&&n.source==="import"&&(this.importNotice=`Imported from ${Pe(n.importKind??"external")} \u2014 will copy to user config on save`)}this.updateDirty()}}toggleToolDirect(e,n){n.isDirect=!n.isDirect,e.directCount+=n.isDirect?1:-1,e.directTokens+=n.isDirect?n.estimatedTokens:-n.estimatedTokens}handleDiscardInput(e){if(De(e,"ctrl+c")){this.cleanup(),this.done({cancelled:!0,changes:new Map});return}if(De(e,"escape")||e==="n"||e==="N"){this.confirmingDiscard=!1;return}if(this.keys.selectConfirm(e)){this.cleanup(),this.discardSelected===0?this.done({cancelled:!0,changes:new Map}):this.done(this.buildResult());return}if(e==="y"||e==="Y"){this.cleanup(),this.done({cancelled:!0,changes:new Map});return}(De(e,"left")||De(e,"right")||De(e,"tab"))&&(this.discardSelected=this.discardSelected===0?1:0)}moveCursor(e){this.visibleItems.length!==0&&(this.cursorIndex=Math.max(0,Math.min(this.visibleItems.length-1,this.cursorIndex+e)))}getOtherCurrentCandidates(e,n,r,o){let i=new Set;for(let[s,a]of Object.entries(this.config.mcpServers)){if(U(a))continue;let c=this.cache?.servers?.[s],u=s===e?r:c&&$e(c,a)?c:void 0;if(!u)continue;let d=pe(a,this.prefix);for(let l of u.tools??[])if(ke(l.uiVisibility))for(let f of ce(l.name,s,d,!1))i.add(f);if(a.exposeResources!==!1)for(let l of u.resources??[]){let f=`read_${Ce(l.name)}`;for(let p of ce(f,s,d,!1))i.add(p)}}for(let s of ce(o,e,pe(n,this.prefix),!1))i.delete(s);return i}rebuildServerTools(e,n){let r=new Map;for(let i of e.tools)r.set(i.name,i.isDirect);let o=[];for(let i of n.tools??[]){if(!ke(i.uiVisibility)||!Ee(i.name,e.name,this.prefix,e.includeTools,e.excludeTools,this.getOtherCurrentCandidates(e.name,e,n,i.name)))continue;let s=r.get(i.name),a=s!==void 0?s:!1;o.push({name:i.name,description:i.description??"",isDirect:a,wasDirect:s!==void 0?e.tools.find(c=>c.name===i.name)?.wasDirect??!1:!1,estimatedTokens:Jo(i)})}if(e.exposeResources)for(let i of n.resources??[]){let s=`read_${Ce(i.name)}`;if(!Ee(s,e.name,this.prefix,e.includeTools,e.excludeTools,this.getOtherCurrentCandidates(e.name,e,n,s)))continue;let a=r.get(s),c=a!==void 0?a:!1,u={name:s,...i.description!==void 0?{description:i.description}:{}};o.push({name:s,description:i.description??`Read resource: ${i.uri}`,isDirect:c,wasDirect:a!==void 0?e.tools.find(d=>d.name===s)?.wasDirect??!1:!1,estimatedTokens:Jo(u)})}e.tools=o,e.directCount=0,e.directTokens=0;for(let i of o)i.isDirect&&(e.directCount++,e.directTokens+=i.estimatedTokens);this.rebuildVisibleItems(),this.updateDirty()}render(e){let n=e-2,r=[],o=this.t,i=P=>`\x1B[1m${P}\x1B[22m`,s=P=>`\x1B[3m${P}\x1B[23m`,a=P=>`\x1B[7m${P}\x1B[27m`,c=P=>K(o.border,"\u2502")+Dl(" "+ov(P),n,"\u2026",!0)+K(o.border,"\u2502"),u=()=>K(o.border,"\u2502")+" ".repeat(n)+K(o.border,"\u2502"),d=()=>K(o.border,"\u251C"+"\u2500".repeat(n)+"\u2524"),l=this.authOnly?" MCP OAuth ":" MCP Servers ",f=n-Vn(l),p=Math.floor(f/2),g=f-p;r.push(K(o.border,"\u256D"+"\u2500".repeat(p))+K(o.title,l)+K(o.border,"\u2500".repeat(g)+"\u256E")),r.push(u());let y=K(o.selected,"\u2502"),w=K(o.border,"\u25CE");if(this.descSearchActive?r.push(c(`${w} ${K(o.needsAuth,"desc:")} ${this.descQuery}${y}`)):this.nameQuery?r.push(c(`${w} ${this.nameQuery}${y}`)):r.push(c(`${w} ${K(o.placeholder,s("search..."))}`)),r.push(u()),this.noticeLines.length>0){for(let P of this.noticeLines)r.push(c(K(o.hint,s(Pe(P)))));r.push(u())}if(r.push(d()),this.servers.length===0)r.push(u()),r.push(c(K(o.hint,s(this.authOnly?"No OAuth-capable MCP servers configured.":"No MCP servers configured.")))),r.push(u());else{let P=t.MAX_VISIBLE,C=this.visibleItems.length,E=Math.max(0,Math.min(this.cursorIndex-Math.floor(P/2),C-P)),L=Math.min(E+P,C);r.push(u());for(let H=E;H<L;H++){let $=this.visibleItems[H];if(!$)continue;let O=H===this.cursorIndex,T=this.servers[$.serverIndex];if(T){if($.type==="server"){if(r.push(c(this.renderServerRow(T,O))),O&&T.connectionStatus==="failed"&&T.failureMessage)for(let G of this.wrapText(Pe(T.failureMessage),n-6))r.push(c(` ${K(o.cancel,G)}`))}else if($.toolIndex!==void 0){let G=T.tools[$.toolIndex];G&&r.push(c(this.renderToolRow(G,O,n)))}}}if(r.push(u()),C>P){let H=Math.round((this.cursorIndex+1)/C*10);r.push(c(`${rv(H,10)} ${K(o.hint,`${this.cursorIndex+1}/${C}`)}`)),r.push(u())}this.importNotice&&(r.push(c(K(o.needsAuth,s(Pe(this.importNotice))))),r.push(u())),this.authNotice&&(r.push(c(K(o.needsAuth,s(Pe(this.authNotice))))),r.push(u()))}if(r.push(d()),r.push(u()),this.confirmingDiscard){let P=this.discardSelected===0?a(i(K(o.cancel," Discard "))):K(o.hint," Discard "),C=this.discardSelected===1?a(i(K(o.confirm," Keep & Close "))):K(o.hint," Keep & Close ");r.push(c(`Discard unsaved changes? ${P} ${C}`))}else if(this.authOnly)r.push(c(K(o.description,"select a server to authenticate")));else{let P=0,C=0;for(let L of this.servers)P+=L.directCount,C+=L.directTokens;let E=P>0?`${P} direct ~${C.toLocaleString()} tokens`:"no direct tools";r.push(c(K(o.description,E+(this.dirty?K(o.needsAuth," (unsaved)"):""))))}r.push(u());let b=this.keys.saveLabel(),v=this.authOnly?[s("\u2191\u2193")+" navigate",s("\u23CE")+" auth",s("ctrl+a")+" auth",s("esc")+" clear/close",s("ctrl+c")+" quit"]:[s("\u2191\u2193")+" navigate",s("space")+" toggle",s("\u23CE")+" expand/auth",s("ctrl+a")+" auth",s("ctrl+r")+" reconnect",...this.selectedServerHasFailureMessage()?[s("ctrl+y")+" copy error"]:[],s("?")+" desc search",...b?[s(b)+" save"]:[],s("esc")+" clear/close",s("ctrl+c")+" quit"],m=" ",S=2,R=n-2,h="",M=0;for(let P of v){let C=Vn(P),E=M===0?C:S+C;M>0&&M+E>R?(r.push(c(K(o.hint,h))),h=P,M=C):(h+=(M>0?m:"")+P,M+=E)}return h&&r.push(c(K(o.hint,h))),r.push(K(o.border,"\u2570"+"\u2500".repeat(n)+"\u256F")),r}renderServerRow(e,n){let r=this.t,o=w=>`\x1B[1m${w}\x1B[22m`,i=e.expanded?"\u25BE":"\u25B8",s=n?K(r.selected,i):K(r.border,e.expanded?i:"\xB7"),a=Pe(e.name),c=Pe(e.importKind??"import"),u=n?o(K(r.selected,a)):a,d=e.source==="import"?K(r.description,` (${c})`):"",l=this.renderConnectionStatus(e);if(!e.hasCachedData&&!this.authOnly)return`${s} ${u}${d} ${K(r.description,"(not cached)")}${l}`;let f=e.directCount,p=e.tools.length,g=K(r.description,"\u25CB");f===p&&p>0?g=K(r.direct,"\u25CF"):f>0&&(g=K(r.needsAuth,"\u25D0"));let y="";return p>0&&(y=`${f}/${p}`,f>0&&(y+=` ~${e.directTokens.toLocaleString()}`),y=K(r.description,y)),`${s} ${g} ${u}${d} ${y}${l}`}selectedServerHasFailureMessage(){let e=this.visibleItems[this.cursorIndex];if(!e)return!1;let n=this.servers[e.serverIndex];return n?.connectionStatus==="failed"&&!!n.failureMessage}wrapText(e,n){let r=Math.max(8,n),o=e.split(/\s+/).filter(Boolean),i=[],s="",a=c=>{let u=c;for(;Vn(u)>r;){let d="",l=0;for(;l<u.length&&Vn(d+u.charAt(l))<=r;)d+=u.charAt(l),l++;d||(d=u.charAt(0)),i.push(d),u=u.slice(d.length)}return u};for(let c of o){let u=s?`${s} ${c}`:c;Vn(u)<=r?s=u:(s&&i.push(s),s=a(c))}return s&&i.push(s),i.length>0?i:[e]}renderConnectionStatus(e){let n=this.t;return this.authInFlight===e.name?` ${K(n.needsAuth,"authenticating")}`:e.connectionStatus==="disabled"?` ${K(n.description,"disabled")}`:e.connectionStatus==="needs-auth"?` ${K(n.needsAuth,"needs auth")}`:e.connectionStatus==="connecting"?` ${K(n.needsAuth,"connecting")}`:e.connectionStatus==="failed"?` ${K(n.cancel,"failed")}`:this.authOnly&&e.connectionStatus==="connected"?` ${K(n.direct,"connected")}`:this.authOnly?` ${K(n.description,"idle")}`:""}renderToolRow(e,n,r){let o=this.t,i=g=>`\x1B[1m${g}\x1B[22m`,s=e.isDirect?K(o.direct,"\u25CF"):K(o.description,"\u25CB"),a=n?K(o.selected,"\u25B8"):" ",c=Pe(e.name),u=Pe(e.description),d=n?i(K(o.selected,c)):c,l=7+Vn(c),f=Math.max(0,r-l-8),p=f>5&&u?K(o.description,"\u2014 "+Dl(u,f,"\u2026")):"";return` ${a} ${s} ${d} ${p}`}invalidate(){}dispose(){this.cleanup()}}});import{Type as oe}from"./vendor/typebox/index.js";ue();Tn();ue();Tn();import{existsSync as By}from"node:fs";var pt=class extends Error{code;context;recoveryHint;cause;constructor(e,n){super(e),this.name="McpUiError",this.code=n.code,this.context=n.context??{},this.recoveryHint=n.recoveryHint,this.cause=n.cause,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}toJSON(){return{name:this.name,code:this.code,message:this.message,context:this.context,recoveryHint:this.recoveryHint,stack:this.stack}}},co=class extends pt{constructor(e,n,r){super(`Failed to fetch UI resource "${e}": ${n}`,{code:"RESOURCE_FETCH_ERROR",context:{uri:e,...r?.server!==void 0?{server:r.server}:{}},recoveryHint:"Check that the MCP server is connected and the resource URI is valid.",...r?.cause!==void 0?{cause:r.cause}:{}}),this.name="ResourceFetchError"}},An=class extends pt{constructor(e,n,r){super(`Invalid UI resource "${e}": ${n}`,{code:"RESOURCE_PARSE_ERROR",context:{uri:e,...r?.server!==void 0?{server:r.server}:{},...r?.mimeType!==void 0?{mimeType:r.mimeType}:{}},recoveryHint:"Ensure the resource returns valid HTML with the correct MIME type."}),this.name="ResourceParseError"}};var pr=class extends pt{denied;constructor(e,n){let r=n.denied?`Tool calls for "${e}" were denied for this session`:`Tool call approval required for "${e}"`;super(r,{code:n.denied?"CONSENT_DENIED":"CONSENT_REQUIRED",context:{server:e},recoveryHint:n.denied?"The user denied tool access. Start a new session to try again.":"Prompt the user for consent before calling tools."}),this.name="ConsentError",this.denied=n.denied??!1}};var gr=class extends pt{constructor(e,n){super(`UI server error: ${e}`,{code:"SERVER_ERROR",context:n?.port!==void 0?{port:n.port}:{},recoveryHint:"Check if the port is available. Another process may be using it.",...n?.cause!==void 0?{cause:n.cause}:{}}),this.name="ServerError"}};function Ec(t,e){if(t instanceof pt)return new pt(t.message,{code:t.code,context:{...t.context,...e},...t.recoveryHint!==void 0?{recoveryHint:t.recoveryHint}:{},...t.cause!==void 0?{cause:t.cause}:{}});let n=t instanceof Error?t:void 0,r=t instanceof Error?t.message:String(t);return new pt(r,{code:"UNKNOWN_ERROR",...e!==void 0?{context:e}:{},...n!==void 0?{cause:n}:{}})}var kc={debug:0,info:1,warn:2,error:3},Hp={debug:"[MCP-UI:DEBUG]",info:"[MCP-UI]",warn:"[MCP-UI:WARN]",error:"[MCP-UI:ERROR]"},Ni=class{minLevel="info";handlers=[];defaultContext={};setLevel(e){this.minLevel=e}setDefaultContext(e){this.defaultContext=e}addHandler(e){this.handlers.push(e)}clearHandlers(){this.handlers=[]}shouldLog(e){return kc[e]>=kc[this.minLevel]}emit(e,n,r,o){if(!this.shouldLog(e))return;let i={level:e,message:n,context:{...this.defaultContext,...r},...o!==void 0?{error:o}:{},timestamp:new Date},s=Hp[e],a=Fp(i.context),c=a?`${s} ${n} ${a}`:`${s} ${n}`;e==="error"?console.error(c,o??""):e==="warn"?console.warn(c):e==="debug"?console.debug(c):console.log(c);for(let u of this.handlers)try{u(i)}catch{}}debug(e,n){this.emit("debug",e,n)}info(e,n){this.emit("info",e,n)}warn(e,n){this.emit("warn",e,n)}error(e,n,r){this.emit("error",e,r,n)}child(e){return new Li(this,e)}},Li=class t{constructor(e,n){this.parent=e;this.context=n}parent;context;debug(e,n){this.parent.debug(e,{...this.context,...n})}info(e,n){this.parent.info(e,{...this.context,...n})}warn(e,n){this.parent.warn(e,{...this.context,...n})}error(e,n,r){this.parent.error(e,n,{...this.context,...r})}child(e){return new t(this.parent,{...this.context,...e})}};function Fp(t){if(!t||Object.keys(t).length===0)return"";let e=[];for(let[n,r]of Object.entries(t))r!=null&&e.push(`${n}=${typeof r=="string"?r:JSON.stringify(r)}`);return e.length>0?`(${e.join(", ")})`:""}var X=new Ni;(process.env.MCP_UI_DEBUG==="1"||process.env.MCP_UI_DEBUG==="true")&&X.setLevel("debug");var uo=class{constructor(e="once-per-server"){this.mode=e;this.log.debug("Initialized",{mode:e})}mode;approvedServers=new Set;deniedServers=new Set;log=X.child({component:"ConsentManager"});requiresPrompt(e){return this.mode==="never"?!1:this.deniedServers.has(e)||this.mode==="always"?!0:!this.approvedServers.has(e)}shouldCacheConsent(){return this.mode!=="always"}registerDecision(e,n){if(this.deniedServers.delete(e),this.approvedServers.delete(e),n){this.approvedServers.add(e),this.log.debug("Consent granted",{server:e});return}this.deniedServers.add(e),this.log.debug("Consent denied",{server:e})}ensureApproved(e){if(this.mode!=="never"){if(this.deniedServers.has(e))throw new pr(e,{denied:!0});if(!this.approvedServers.has(e))throw new pr(e,{requiresApproval:!0});this.mode==="always"&&this.approvedServers.delete(e)}}clear(e){if(e){this.approvedServers.delete(e),this.deniedServers.delete(e),this.log.debug("Cleared consent for server",{server:e});return}this.approvedServers.clear(),this.deniedServers.clear(),this.log.debug("Cleared all consent records")}};ue();import{SdkError as wy,SdkErrorCode as pl}from"@modelcontextprotocol/client";import{mkdirSync as ey,statSync as ty}from"node:fs";import{isDeepStrictEqual as ul}from"node:util";import{Client as ny,SdkError as ry,SdkErrorCode as oy,SdkHttpError as Is,SSEClientTransport as iy,StreamableHTTPClientTransport as sy,UnauthorizedError as ay}from"@modelcontextprotocol/client";import{StdioClientTransport as cy}from"@modelcontextprotocol/client/stdio";import{createConnection as zp}from"node:net";import{ReadBuffer as qp,serializeMessage as Vp}from"@modelcontextprotocol/client";var lo=class{constructor(e){this.socketPath=e}socketPath;socket;readBuffer=new qp;onclose;onerror;onmessage;async start(){if(this.socket)throw new Error("UnixSocketClientTransport already started");await new Promise((e,n)=>{let r=zp(this.socketPath);this.socket=r;let o=!1;r.once("connect",()=>{o=!0,e()}),r.on("data",i=>{try{for(this.readBuffer.append(i);;){let s=this.readBuffer.readMessage();if(s===null)break;this.onmessage?.(s)}}catch(s){let a=s instanceof Error?s:new Error(String(s));this.onerror?.(a),this.close()}}),r.on("error",i=>{o||n(i),this.onerror?.(i)}),r.on("close",()=>{this.socket===r&&(this.socket=void 0),this.readBuffer.clear(),this.onclose?.()})})}async close(){let e=this.socket;this.socket=void 0,this.readBuffer.clear(),!(!e||e.destroyed)&&await new Promise(n=>{let r=setTimeout(()=>e.destroy(),2e3);r.unref(),e.once("close",()=>{clearTimeout(r),n()}),e.end()})}async send(e){let n=this.socket;if(!n||n.destroyed)throw new Error("Unix socket is not connected");await new Promise((r,o)=>{n.write(Vp(e),i=>{i?o(i):r()})})}};var po="2026-07-28",Kp="2025-06-18",Oc="application/json, text/event-stream",Jp="text/event-stream",Wp=new Set([400,401,404,405,406,415]),Gp=new Set([404,405,406,415]),Yp=new Set([202,401,503]),Xp={jsonrpc:"2.0",id:1,method:"server/discover",params:{}},Qp={jsonrpc:"2.0",id:1,method:"initialize",params:{protocolVersion:Kp,capabilities:{},clientInfo:{name:"pi-mcp-probe",version:"2.1.2"}}},Zp={kind:"modern",request:{method:"POST",headers:{Accept:Oc,"Content-Type":"application/json","MCP-Protocol-Version":po,"Mcp-Method":"server/discover"},body:JSON.stringify(Xp)},allowJson:!0},eg={kind:"legacy-post",request:{method:"POST",headers:{Accept:Oc,"Content-Type":"application/json"},body:JSON.stringify(Qp)},allowJson:!0},tg={kind:"legacy-sse",request:{headers:{Accept:Jp}},allowJson:!1};function ng(t){if(typeof t!="object"||t===null||t.jsonrpc!=="2.0")return null;if("result"in t){let e=t.result;return{kind:"result",protocolVersion:typeof e=="object"&&e!==null?e.protocolVersion:void 0}}return"error"in t?{kind:"error"}:null}function rg(t){return/(?:^|,)\s*Bearer\b/i.test(t.headers.get("www-authenticate")??"")}function og(t){let e=t.headers.get("content-type")?.split(";",1)[0]?.trim().toLowerCase();return e==="text/html"?"HTML":e||"an untyped response"}async function ig(t){try{return ng(JSON.parse(await t.text()))}catch{return null}}async function sg(t,e){let n=t.headers.get("content-type")?.toLowerCase().startsWith("text/event-stream");if(t.ok&&n)return{kind:"mcp",result:{isMcp:!0,classification:"endpoint responded with an MCP event stream"}};let r=e.allowJson||t.status===401?await ig(t):null;return t.ok&&e.allowJson&&r?e.kind==="modern"&&(r.kind==="error"||r.protocolVersion!==po)?{kind:"unsupported-modern"}:{kind:"mcp",result:{isMcp:!0,classification:e.kind==="modern"?`endpoint supports stateless MCP ${po} server/discover`:"endpoint responded with a JSON-RPC 2.0 envelope"}}:t.status===401&&rg(t)&&r?{kind:"mcp",result:{isMcp:!0,classification:e.kind==="modern"?`endpoint requires Bearer authentication during MCP ${po} server/discover probing`:"endpoint requires Bearer authentication and responded with a JSON-RPC 2.0 error"}}:{kind:"unrecognized"}}async function ji(t,e){let n=await fetch(t,{...e.request,signal:AbortSignal.timeout(5e3)});return{response:n,outcome:await sg(n,e)}}function go(t){let e=`endpoint returned ${og(t)} (${t.status})`;return{isMcp:!1,classification:t.status===503?`${e} \u2014 server is temporarily unavailable; MCP endpoint shape could not be determined`:t.status===202?`${e} \u2014 MCP endpoint shape could not be determined`:t.status===401?`${e} \u2014 authentication may be required; MCP endpoint shape could not be determined`:`${e} \u2014 this URL does not appear to speak MCP`}}function fo(t){return Yp.has(t.status)?go(t):void 0}async function $c(t){let{response:e,outcome:n}=await ji(t,Zp);if(n.kind==="mcp")return n.result;let r=fo(e);if(n.kind!=="unsupported-modern"&&!Wp.has(e.status))return r??go(e);let{response:o,outcome:i}=await ji(t,eg);if(i.kind==="mcp")return i.result;if(r??=fo(o),!Gp.has(o.status))return fo(o)??r??go(o);let{response:s,outcome:a}=await ji(t,tg);return a.kind==="mcp"?a.result:fo(s)??r??go(s)}ue();tt();import{existsSync as Jt,readFileSync as Hi,realpathSync as ag,readdirSync as cg,statSync as ug,writeFileSync as Dc,renameSync as lg,mkdirSync as dg,openSync as fg,readSync as pg,closeSync as gg,unlinkSync as mg}from"node:fs";import{join as Kt,dirname as hg,extname as yg,resolve as vg,sep as Ic}from"node:path";function D(t){if(t?.aborted)throw t.reason instanceof Error?t.reason:new Error(String(t.reason??"MCP request aborted"))}async function ve(t,e){return e?(D(e),await new Promise((n,r)=>{let o=!1,i=()=>e.removeEventListener("abort",s),s=()=>{o||(o=!0,i(),r(e.reason instanceof Error?e.reason:new Error(String(e.reason??"MCP request aborted"))))};e.addEventListener("abort",s,{once:!0}),t.then(a=>{o||(o=!0,i(),n(a))},a=>{o||(o=!0,i(),r(a))})})):t}import Nc from"cross-spawn";var Bi=2,Sg=1440*60*1e3,wg=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z][0-9A-Za-z.-]*)?(?:\+[0-9A-Za-z][0-9A-Za-z.-]*)?$/;async function Lc(t,e,n){D(n);let r=t==="npx"?bg(e):t==="npm"?Cg(e):null;if(!r)return null;let o=jc(r.packageSpec),i=JSON.stringify([t,r.packageSpec,r.binName??""]),a=$g()?.entries?.[i];if(a&&Date.now()-a.resolvedAt<Sg&&Jt(a.resolvedBin)&&(!o?.exactVersion||a.packageVersion===o.exactVersion))return{binPath:a.resolvedBin,extraArgs:r.extraArgs,isJs:a.isJs};let c=_c(r.packageSpec,r.binName);if(c)return Uc(i,c),{binPath:c.resolvedBin,extraArgs:r.extraArgs,isJs:c.isJs};await Mg(r.packageSpec,n);let u=_c(r.packageSpec,r.binName);return u?(Uc(i,u),{binPath:u.resolvedBin,extraArgs:r.extraArgs,isJs:u.isJs}):null}function bg(t){let e=t.indexOf("--"),n=e>=0?t.slice(0,e):t,r=e>=0?t.slice(e+1):[],o=[],i,s=!1,a=!1;for(let l=0;l<n.length;l++){let f=n[l];if(f===void 0)return null;if(a){o.push(f);continue}if(!(f==="-y"||f==="--yes")){if(f==="-p"||f==="--package"){let p=n[l+1];if(!p||p.startsWith("-"))return null;i||(i=p),s=!0,l++;continue}if(f.startsWith("--package=")){let p=f.slice(10);if(!p)return null;i||(i=p),s=!0;continue}if(f.startsWith("-"))return null;o.push(f),a=!0}}let c=e>=0&&r.length>0?["--",...r]:r;if(s){let l=o[0];if(!i||!l)return null;let f=o.slice(1).concat(c);return{packageSpec:i,binName:l,extraArgs:f}}let u=o[0];if(!u)return null;let d=o.slice(1).concat(c);return{packageSpec:u,extraArgs:d}}function Cg(t){if(t[0]!=="exec")return null;let e=t.slice(1),n=e.indexOf("--");if(n<0)return null;let r=e.slice(0,n),o=e.slice(n+1),i;for(let c=0;c<r.length;c++){let u=r[c];if(u===void 0)return null;if(!(u==="-y"||u==="--yes")){if(u==="--package"){let d=r[c+1];if(!d||d.startsWith("-"))return null;i||(i=d),c++;continue}if(u.startsWith("--package=")){let d=u.slice(10);if(!d)return null;i||(i=d);continue}if(u.startsWith("-"))return null}}let s=o[0];if(!i||!s)return null;let a=o.slice(1);return{packageSpec:i,binName:s,extraArgs:a}}function _c(t,e){let n=kg();if(!n)return null;let r=jc(t);if(!r)return null;let{packageName:o,exactVersion:i}=r,s=Pg(n,o,i);if(!s)return null;let a=Kt(s,"package.json");if(!Jt(a))return null;let c=null;try{c=JSON.parse(Hi(a,"utf-8"))}catch{return null}let u=c?.bin;if(!u)return null;let d=Tg(o,e),l,f;if(typeof u=="string")l=Ag(o),f=u;else{for(let b of d)if(u[b]){l=b,f=u[b];break}if(!f){let b=Object.entries(u)[0];b&&(l=b[0],f=b[1])}}if(!f)return null;let p=Rg(s),g=l?Kt(p,".bin",l):null,y=g&&Jt(g)?Ig(g):"";if(!y&&(y=vg(s,f),!Jt(y)))return null;let w=Eg(y);return{resolvedBin:y,resolvedAt:Date.now(),...c?.version!==void 0?{packageVersion:c.version}:{},isJs:w}}var xg=3e4;async function Mg(t,e){D(e);try{await new Promise((n,r)=>{let o=Nc("npm",["exec","--yes","--package",t,"--","node","-e","1"],{stdio:"ignore"}),i=setTimeout(()=>{o.kill(),r(new Error("timeout"))},xg),s=()=>{o.kill(),r(e?.reason instanceof Error?e.reason:new Error("MCP request aborted"))};e?.addEventListener("abort",s,{once:!0}),i.unref(),o.on("close",()=>{clearTimeout(i),e?.removeEventListener("abort",s),n()}),o.on("error",a=>{clearTimeout(i),e?.removeEventListener("abort",s),r(a)})})}catch{e?.aborted&&D(e)}D(e)}function Tg(t,e){let n=[];if(e&&n.push(e),t.startsWith("@")){let r=t.split("/")[1]??"",o=t.split("/")[0]?.replace("@","")??"";r&&n.push(r),o&&r&&n.push(`${o}-${r}`)}else n.push(t);return[...new Set(n.filter(Boolean))]}function jc(t){let e=t.trim();if(!e)return null;let n,r;if(e.startsWith("@")){let i=e.indexOf("/");if(i<0)return null;let s=e.lastIndexOf("@");s>i?(n=e.slice(0,s),r=e.slice(s+1)):n=e}else{let i=e.indexOf("@");i>=0?(n=e.slice(0,i),r=e.slice(i+1)):n=e}if(!n)return null;let o=r?.replace(/^=/,"").replace(/^v/i,"");return{packageName:n,...o&&wg.test(o)?{exactVersion:o}:{}}}function Ag(t){return t.startsWith("@")?t.split("/")[1]??t.replace("@","").replace("/","-"):t}function Pg(t,e,n){let r=Kt(t,"_npx");if(!Jt(r))return null;let o=e.startsWith("@")?e.split("/"):[e],i=cg(r,{withFileTypes:!0}).filter(s=>s.isDirectory()).map(s=>{let a=Kt(r,s.name),c=_g(a);return{name:s.name,mtime:c}}).sort((s,a)=>a.mtime-s.mtime);for(let s of i){let a=Kt(r,s.name,"node_modules",...o),c=Kt(a,"package.json");if(Jt(c)){if(n)try{if(JSON.parse(Hi(c,"utf-8")).version!==n)continue}catch{continue}return a}}return null}function Rg(t){let e=t.split(Ic),n=e.lastIndexOf("node_modules");return n>=0?e.slice(0,n+1).join(Ic):Kt(t,"..")}function Eg(t){let e=yg(t).toLowerCase();if(e===".js"||e===".mjs"||e===".cjs")return!0;try{let n=fg(t,"r");try{let r=Buffer.alloc(256);pg(n,r,0,256,0);let o=r.toString("utf-8").split(`
|
|
11
11
|
`)[0]??"";return o.startsWith("#!")&&o.includes("node")}finally{gg(n)}}catch{return!1}}var Mt;function kg(){if(Mt!==void 0)return Mt;if(process.env.NPM_CONFIG_CACHE)return Mt=process.env.NPM_CONFIG_CACHE,Mt;try{let t=Nc.sync("npm",["config","get","cache"],{encoding:"utf-8"});if(t.status===0)return Mt=String(t.stdout).trim()||null,Mt}catch{return Mt=null,null}return Mt=null,null}function Fi(){return Qe("mcp-npx-cache.json")}function zi(t){if(!Jt(t))return null;try{return JSON.parse(Hi(t,"utf-8"))}catch{return null}}function mo(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)?t:null}function Bc(){return Object.create(null)}function Og(t){let e=mo(t);return!e||typeof e.resolvedBin!="string"||typeof e.resolvedAt!="number"||!Number.isFinite(e.resolvedAt)||typeof e.isJs!="boolean"||e.packageVersion!==void 0&&typeof e.packageVersion!="string"?null:{resolvedBin:e.resolvedBin,resolvedAt:e.resolvedAt,...e.packageVersion!==void 0?{packageVersion:e.packageVersion}:{},isJs:e.isJs}}function Hc(t){let e=mo(t);if(!e||e.version!==Bi)return null;let n=mo(e.entries);if(!n)return null;let r=Bc();for(let[o,i]of Object.entries(n)){let s=Og(i);s&&(r[o]=s)}return{version:Bi,entries:r}}function Fc(){let t=Fi();if(mo(zi(t))?.version!==1)return!1;try{mg(t)}catch{try{Dc(t,"","utf-8")}catch{}}return!0}Fc();function $g(){return Fc()?null:Hc(zi(Fi()))}function Uc(t,e){try{let n=Fi(),r=hg(n);dg(r,{recursive:!0});let o=Hc(zi(n)),i=Bc();o&&Object.assign(i,o.entries);let s={version:Bi,entries:i};s.entries[t]=e;let a=`${n}.${process.pid}.tmp`;Dc(a,JSON.stringify(s,null,2),"utf-8"),lg(a,n)}catch{}}function Ig(t){try{return ag(t)}catch{return""}}function _g(t){try{return ug(t).mtimeMs}catch{return 0}}import{Ajv as Ug}from"ajv";import Dg from"ajv/dist/2020.js";import Ng from"ajv-formats";import{AjvJsonSchemaValidator as zc}from"@modelcontextprotocol/client/validators/ajv";var qc=Ng,Lg=new Set(["http://json-schema.org/draft-07/schema","https://json-schema.org/draft-07/schema"]),jg=new Set(["https://json-schema.org/draft/2020-12/schema"]);function Bg(t){return!("$schema"in t)||typeof t.$schema!="string"?{status:"unstamped"}:{status:"stamped",uri:t.$schema.endsWith("#")?t.$schema.slice(0,-1):t.$schema}}function Vc(){let t,e;return{getValidator(n){let r=Bg(n);if(r.status==="unstamped"||jg.has(r.uri))return e??=(()=>{let o=Dg,i=new o({strict:!1,allErrors:!0});return qc(i),new zc(i)})(),e.getValidator(n);if(!Lg.has(r.uri))throw new Error(`Unsupported JSON Schema dialect: ${r.uri}`);return t??=(()=>{let o=new Ug({strict:!1,validateFormats:!0,validateSchema:!1,allErrors:!0});return qc(o),new zc(o)})(),t.getValidator(n)}}}Rn();import{UnauthorizedError as mu}from"@modelcontextprotocol/client";tt();Tn();import{spawnSync as zg}from"child_process";import{createHash as Zc}from"crypto";import{createRequire as qg}from"module";import{readFileSync as Vg,existsSync as eu,rmSync as Jc}from"fs";import{dirname as Kg,join as Yi}from"path";import{fileURLToPath as Jg}from"url";var Wg=qg(import.meta.url),tu="pi-mcp-adapter.oauth",yo="PI_MCP_ADAPTER_TEST_AUTH_STORE",vo=1e3,Wc=1280,Gg="PI_MCP_ADAPTER_DISABLE_KEYRING_RECOVERY",Yg="PI_MCP_ADAPTER_KEYRING_RECOVERY_KEYCTL",Xg="PI_MCP_ADAPTER_KEYRING_RECOVERY_NODE",Qg="PI_MCP_ADAPTER_KEYRING_RECOVERY_HELPER",Zg="PI_MCP_ADAPTER_TEST_LINUX_KEYRING_RECOVERY",em="PI_MCP_ADAPTER_DISABLE_AUTH_CACHE",tm=1e4,nu="__piMcpAdapterOAuthChunked",At=class extends Error{constructor(n,r,o){super(n,{cause:o});this.operation=r;this.name="OAuthCredentialStoreError"}operation;code="OAUTH_CREDENTIAL_STORE_UNAVAILABLE"};function ru(t,e){let n=new Set,r=t;for(;(typeof r=="object"&&r!==null||typeof r=="function")&&!n.has(r);){n.add(r);let o=r;if([o.name,o.message,o.code].some(i=>typeof i=="string"&&e.test(i)))return!0;r=o.cause}return!1}function nm(t){return process.platform==="linux"&&ru(t,/key\s*(?:has been\s*)?revoked|keyrevoked/i)?"OAuth credential store unavailable: the Linux session keyring may be revoked. Start Pi from a fresh login/keyring session and retry.":"OAuth credential store unavailable. Configure or unlock the OS credential store and retry."}var Gc,En=new Map,wo=0,Wt=new Map;function ou(){return process.env[em]!=="1"}function Ji(t){return t===void 0?void 0:structuredClone(t)}var rm={read(t){return wo++,En.get(t)},write(t,e){En.set(t,e)},remove(t){En.delete(t)}},om={read(t){return Vi(t).getPassword()??void 0},write(t,e){Vi(t).setPassword(e)},remove(t){Vi(t).deleteCredential()}},im={read(t){return wo++,En.get(t)},write(t,e){if(e.length>Wc)throw new Error(`Value of 'password encoded as UTF-16' is longer than the platform limit of ${Wc*2} chars`);En.set(t,e)},remove(t){En.delete(t)}},sm={read(){throw wo++,new Error("simulated secure credential store unavailable")},write(){throw new Error("simulated secure credential store unavailable")},remove(){throw new Error("simulated secure credential store unavailable")}};function qi(){return new Error("Couldn't access platform storage: KeyRevoked",{cause:new Error("KeyRevoked")})}var am={read(){throw wo++,qi()},write(){throw qi()},remove(){throw qi()}};function Xi(){return process.env[yo]==="memory"?rm:process.env[yo]==="sizelimited"?im:process.env[yo]==="unavailable"?sm:process.env[yo]==="keyrevoked"?am:om}function Vi(t){try{return Gc??=cm(),new Gc(tu,t)}catch(e){throw new Error("OAuth secure credential storage is unavailable. Configure the OS credential store and retry authentication.",{cause:e})}}function cm(t=Wg,e=process.platform,n=process.arch){try{return t("@napi-rs/keyring").Entry}catch(r){try{return um(t,e,n).Entry}catch(o){throw new Error(`Failed to load @napi-rs/keyring; absolute-path native binding fallback also failed: ${fm(o)}`,{cause:r})}}}function um(t,e,n){let r=lm(e,n);if(r.length===0)throw new Error(`Unsupported @napi-rs/keyring native binding target: ${e}-${n}`);let o;for(let i of r)try{let s=t.resolve(`${i.packageName}/package.json`);return t(Yi(Kg(s),i.bindingFile))}catch(s){o=s}throw o instanceof Error?o:new Error(String(o))}function lm(t,e){return dm(t,e).map(n=>({packageName:`@napi-rs/keyring-${n}`,bindingFile:`keyring.${n}.node`}))}function dm(t,e){if(t==="darwin"){if(e==="arm64")return["darwin-arm64"];if(e==="x64")return["darwin-x64"]}if(t==="win32"){if(e==="arm64")return["win32-arm64-msvc"];if(e==="x64")return["win32-x64-msvc"];if(e==="ia32")return["win32-ia32-msvc"]}if(t==="linux"){if(e==="arm64")return["linux-arm64-gnu","linux-arm64-musl"];if(e==="arm")return["linux-arm-gnueabihf"];if(e==="riscv64")return["linux-riscv64-gnu"];if(e==="x64")return["linux-x64-gnu","linux-x64-musl"]}return t==="freebsd"&&e==="x64"?["freebsd-x64"]:[]}function fm(t){return t instanceof Error?t.message:String(t)}function pm(){return process.env[Gg]==="1"?!1:process.platform==="linux"||process.env[Zg]==="1"}function Qi(t){return pm()&&ru(t,/key\s*(?:has been\s*)?revoked|keyrevoked/i)}function Ki(t,e,n){let r=process.env[Yg]?.trim()||"keyctl",o=process.env[Xg]?.trim()||"node",i=process.env[Qg]?.trim()||Jg(new URL("./mcp-keyring-helper.cjs",import.meta.url)),s=JSON.stringify({operation:t,service:tu,account:e,payload:n}),a=zg(r,["session","-",o,i],{input:`${s}
|
|
12
12
|
`,encoding:"utf8",maxBuffer:1024*1024,timeout:tm,windowsHide:!0});if(a.error)throw new Error(`Linux keyring recovery helper could not start: ${a.error.message}`,{cause:a.error});if(a.status!==0)throw new Error(`Linux keyring recovery helper failed with exit code ${a.status??"unknown"}`);let c;try{c=JSON.parse(a.stdout.trim())}catch(d){throw new Error("Linux keyring recovery helper returned invalid JSON",{cause:d})}if(typeof c!="object"||c===null||typeof c.ok!="boolean")throw new Error("Linux keyring recovery helper returned an invalid response");let u=c;if(u.ok===!1)throw new Error(u.error||"Linux keyring recovery helper failed");if(t==="read"&&u.found===!0&&typeof u.value!="string")throw new Error("Linux keyring recovery helper returned an invalid read response");return u}var Zi={read(t){let e=Ki("read",t);return e.ok&&e.found===!0?e.value:void 0},write(t,e){Ki("write",t,e)},remove(t){Ki("remove",t)}};function bo(t,e=process.cwd()){let n=Rc(t,e);return n?{baseDir:n}:{}}function Co(t={}){let e=process.env.MCP_OAUTH_DIR?.trim();return e||(t.baseDir??Qe("mcp-oauth"))}function iu(t,e){if(typeof t!="string")throw new Error(`Invalid MCP server name: ${JSON.stringify(t)}`);let n=xo(t);return Yi(Co(e),n)}function xo(t){if(typeof t!="string")throw new Error(`Invalid MCP server name: ${JSON.stringify(t)}`);return`sha256-${Zc("sha256").update(t,"utf8").digest("hex")}`}function su(t,e){return Yi(iu(t,e),"tokens.json")}function au(t,e,n){try{return JSON.parse(e)}catch(r){throw new Error(`Failed to parse OAuth credentials for ${t} from ${n}`,{cause:r})}}function es(t,e,n){let r=au(t,e,n),o=cu(r);if(!o)throw new Error(`Failed to parse OAuth credentials for ${t} from ${n}: invalid credential shape`);return o}function cu(t){let e=ts(t);if(!e)return;let n=Tt(e.codeVerifier),r=Tt(e.oauthState),o=Tt(e.serverUrl);if(n===null||r===null||o===null)return;let i=e.tokens===void 0?void 0:gm(e.tokens),s=e.clientInfo===void 0?void 0:mm(e.clientInfo);if(e.tokens!==void 0&&!i||e.clientInfo!==void 0&&!s)return;let a={};return i&&(a.tokens=i),s&&(a.clientInfo=s),n!==void 0&&(a.codeVerifier=n),r!==void 0&&(a.oauthState=r),o!==void 0&&(a.serverUrl=o),a}function gm(t){let e=ts(t);if(!e||typeof e.accessToken!="string")return;let n=Tt(e.refreshToken),r=Tt(e.scope),o=Tt(e.issuer),i=Wi(e.expiresAt);if(n===null||r===null||o===null||i===null)return;let s={accessToken:e.accessToken};return n!==void 0&&(s.refreshToken=n),i!==void 0&&(s.expiresAt=i),r!==void 0&&(s.scope=r),o!==void 0&&(s.issuer=o),s}function mm(t){let e=ts(t);if(!e||typeof e.clientId!="string")return;let n=Tt(e.clientSecret),r=Tt(e.issuer),o=Wi(e.clientIdIssuedAt),i=Wi(e.clientSecretExpiresAt),s=hm(e.configPreRegistered);if(n===null||r===null||o===null||i===null||s===null)return;let a={clientId:e.clientId},c=ym(e.redirectUris);return n!==void 0&&(a.clientSecret=n),o!==void 0&&(a.clientIdIssuedAt=o),i!==void 0&&(a.clientSecretExpiresAt=i),c!==void 0&&(a.redirectUris=c),r!==void 0&&(a.issuer=r),s!==void 0&&(a.configPreRegistered=s),a}function ts(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)?t:void 0}function Tt(t){if(t!==void 0)return typeof t=="string"?t:null}function Wi(t){if(t!==void 0)return typeof t=="number"?t:null}function hm(t){if(t!==void 0)return typeof t=="boolean"?t:null}function ym(t){return Array.isArray(t)&&t.every(e=>typeof e=="string")?t:void 0}function vm(t){if(typeof t!="object"||t===null)return!1;let e=t;return e[nu]===1&&typeof e.chunkCount=="number"&&Number.isInteger(e.chunkCount)&&e.chunkCount>0&&typeof e.chunkDigest=="string"&&/^[a-f0-9]{16}$/.test(e.chunkDigest)}function uu(t,e,n){return`${t}.chunk.${e.chunkDigest}.${n}`}function lu(t,e){return Array.from({length:e.chunkCount},(n,r)=>uu(t,e,r))}function ns(t,e,n){let r=au(t,e,n);return vm(r)?r:void 0}function Sm(t,e,n){try{let r=t.read(n);return r===void 0?void 0:ns(e,r,"OS secure credential store")}catch{return}}function du(t,e,n){for(let r of lu(e,n))t.remove(r)}function Yc(t,e,n){if(n)try{du(t,e,n)}catch{}}function wm(t){return{[nu]:1,chunkCount:Math.ceil(t.length/vo),chunkDigest:Zc("sha256").update(t,"utf8").digest("hex").slice(0,16)}}function bm(t,e,n,r){let o=lu(n,r).map(i=>{try{let s=t.read(i);if(s===void 0)throw new Error(`Missing OAuth credential chunk ${i} for ${e}`);return s}catch(s){throw new At(`Failed to read OAuth credentials for ${e} from the OS secure credential store`,"read",s)}});return es(e,o.join(""),"OS secure credential store chunks")}function Cm(t,e){let n=su(t,e);if(!eu(n))return;let r=Vg(n,"utf-8");return es(t,r,n)}function So(t,e){let n=su(t,e);if(!eu(n))return;try{Jc(n,{force:!0})}catch(o){throw new Error(`Failed to remove legacy plaintext OAuth credentials for ${t} at ${n}`,{cause:o})}let r=iu(t,e);try{Jc(r,{recursive:!0})}catch{}}function Gi(t,e,n){let r=xo(e),o=JSON.stringify(n),i=Sm(t,e,r),s=o.length>vo?wm(o):void 0;try{if(s){for(let a=0;a<s.chunkCount;a++){let c=o.slice(a*vo,(a+1)*vo);t.write(uu(r,s,a),c)}t.write(r,JSON.stringify(s))}else t.write(r,o);i?.chunkDigest!==s?.chunkDigest&&Yc(t,r,i)}catch(a){throw Yc(t,r,s),new At(`Failed to write OAuth credentials for ${e} to the OS secure credential store`,"write",a)}xm(e,o)}function xm(t,e){if(!ou())return;let n=cu(JSON.parse(e));if(!n){Wt.delete(t);return}Wt.set(t,Ji(n))}function Mm(t,e){try{Gi(Xi(),t,e)}catch(n){if(!Qi(n))throw n;Gi(Zi,t,e)}}function Xc(t,e,n,r={}){let o=xo(e),i;try{i=t.read(o)}catch(a){throw new At(`Failed to read OAuth credentials for ${e} from the OS secure credential store`,"read",a)}if(i!==void 0){let a=ns(e,i,"OS secure credential store"),c=a?bm(t,e,o,a):es(e,i,"OS secure credential store");return So(e,n),c}let s=Cm(e,n);if(s)return r.migrateLegacy===!1||(Gi(t,e,s),So(e,n)),s}function fu(t,e,n={}){let r=n.migrateLegacy!==!1&&ou();if(r&&Wt.has(t))return Ji(Wt.get(t));let o;try{o=Xc(Xi(),t,e,n)}catch(i){if(!Qi(i))throw i;o=Xc(Zi,t,e,n)}return r&&Wt.set(t,Ji(o)),o}function Pt(t,e){return fu(t,e)}function kn(t,e,n){let r=Pt(t,n);if(r&&r.serverUrl&&r.serverUrl===e)return r}function pu(t,e,n){try{let r=fu(t,n,{migrateLegacy:!1});return!r?.serverUrl||r.serverUrl!==e?{status:"absent"}:{status:"present",entry:r}}catch(r){if(!(r instanceof At))throw r;return{status:"unavailable",message:nm(r)}}}function On(t,e,n,r){n&&(e.serverUrl=n),Mm(t,e),So(t,r)}function Qc(t,e){let n=xo(e);try{let r=t.read(n),o=r===void 0?void 0:ns(e,r,"OS secure credential store");o&&du(t,n,o),t.remove(n)}catch(r){throw new At(`Failed to remove OAuth credentials for ${e} from the OS secure credential store`,"remove",r)}}function Tm(t,e){try{Qc(Xi(),t)}catch(n){if(!Qi(n))throw n;Qc(Zi,t)}Wt.delete(t),So(t,e)}function at(t){Wt.delete(t)}function rs(t,e,n,r){let o=Pt(t,r)??{};n&&o.serverUrl!==n&&(delete o.clientInfo,delete o.codeVerifier,delete o.oauthState),o.tokens=e,On(t,o,n,r)}function mr(t,e,n,r){let o=Pt(t,r)??{};n&&o.serverUrl!==n&&(delete o.tokens,delete o.codeVerifier,delete o.oauthState),o.clientInfo=e,On(t,o,n,r)}function $n(t,e){let n=Pt(t,e);n&&(delete n.codeVerifier,On(t,n,void 0,e))}function os(t,e){return Pt(t,e)?.oauthState}function Rt(t,e){let n=Pt(t,e);n&&(delete n.oauthState,On(t,n,void 0,e))}function Mo(t,e){Tm(t,e)}function To(t,e){let n=Pt(t,e);n&&(delete n.clientInfo,On(t,n,void 0,e))}function gu(t,e){let n=Pt(t,e);n&&(delete n.tokens,On(t,n,void 0,e))}be();tt();import{OAuthMetadataSchema as Am,OpenIdProviderDiscoveryMetadataSchema as Pm}from"@modelcontextprotocol/core";function hu(){let t=Lt();return t==="pi"?"Pi Coding Agent":t}function Rm(){let t=ja();return t||(Lt()==="pi"?"https://github.com/nicobailon/pi-mcp-adapter":void 0)}function Ao(t,e){return t===e||t.endsWith("/")&&t.slice(0,-1)===e||e.endsWith("/")&&e.slice(0,-1)===t}function Em(t){let e={access_token:t.accessToken,token_type:"Bearer"};return t.refreshToken!==void 0&&(e.refresh_token=t.refreshToken),t.expiresAt!==void 0&&(e.expires_in=Math.max(0,Math.floor(t.expiresAt-Date.now()/1e3))),t.scope!==void 0&&(e.scope=t.scope),t.issuer!==void 0&&(e.issuer=t.issuer),e}var km=19876,Po="/callback",is=km;if(process.env.MCP_OAUTH_CALLBACK_PORT){let t=Number.parseInt(process.env.MCP_OAUTH_CALLBACK_PORT,10);Number.isInteger(t)&&t>0&&t<=65535&&(is=t)}var yu=is,vu=Po;function ss(){return is}function Ro(){return yu}function Eo(t){yu=t}function hr(){return vu}function ko(t){vu=t.startsWith("/")?t:`/${t}`}var Om=new Set(["client_id","code_challenge","code_challenge_method","redirect_uri","resource","response_type","scope","state"]);function $m(t,e){if(!e)return t;let n=new URL(t.toString());for(let[r,o]of Object.entries(e)){if(Om.has(r)||n.searchParams.has(r))throw new Error(`OAuth authorizationParams.${r} cannot override an authorization flow parameter`);n.searchParams.set(r,o)}return n}function Im(t){let e=new URL(t),n=e.pathname.replace(/\/+$/,"")||"/",r="/.well-known/oauth-authorization-server";if(n===r||n.startsWith(`${r}/`)){let i=n.slice(r.length)||"/";return new URL(i,e.origin).toString()}let o="/.well-known/openid-configuration";if(n===o||n.startsWith(`${o}/`)){let i=n.slice(o.length)||"/";return new URL(i,e.origin).toString()}if(n.endsWith(o)){let i=n.slice(0,-o.length)||"/";return new URL(i,e.origin).toString()}}function _m(t,e,n){let r;try{r=new URL(e)}catch(i){throw new Error("OAuth authorization-server metadata issuer must be an absolute URL",{cause:i})}if(r.protocol!=="http:"&&r.protocol!=="https:")throw new Error("OAuth authorization-server metadata issuer must use http:// or https://");let o=Im(t);if(!n){if(o!==void 0&&!Ao(o,e))throw new Error(`OAuth authorization-server metadata issuer does not match authServerMetadataUrl: expected ${o}`);if(o===void 0&&!Ao(new URL(t).origin,e))throw new Error(`OAuth authorization-server metadata issuer does not match authServerMetadataUrl origin: expected ${new URL(t).origin}`)}}async function Um(t,e,n,r){let o=await fetch(t,{headers:{accept:"application/json"},...r!==void 0?{signal:r}:{}});if(!o.ok)throw await o.text().catch(()=>{}),new Error(`OAuth authServerMetadataUrl request failed with HTTP ${o.status}`);let i=await o.json(),s=Am.safeParse(i),a=s.success?s.data:Pm.parse(i);_m(t,a.issuer,n);let c=new URL(e);return c.hash="",{authorizationServerUrl:a.issuer,authorizationServerMetadata:a,resourceMetadata:{resource:c.toString()}}}var Gt=class{constructor(e,n,r,o,i={},s,a){this.serverName=e;this.serverUrl=n;this.config=r;this.callbacks=o;this.storageOptions=i;this.runtimeSignal=s;this.flowState=a,this.redirectUrlSnapshot=r.grantType==="client_credentials"?void 0:r.redirectUri??`http://localhost:${Ro()}${hr()}`}serverName;serverUrl;config;callbacks;storageOptions;runtimeSignal;redirectUrlSnapshot;active=!0;flowClientInfo;flowCodeVerifier;flowDiscoveryState;flowIssuerMismatch=!1;flowState;invalidatedAccessToken;invalidatedClientId;lastObservedClientId;lastSavedAccessToken;pendingAuthAccessToken;get usesClientCredentials(){return this.config.grantType==="client_credentials"}get discoveredIssuer(){return this.flowDiscoveryState?.authorizationServerMetadata?.issuer??this.flowDiscoveryState?.authorizationServerUrl}deactivate(){this.active=!1,this.invalidatedAccessToken=void 0,this.invalidatedClientId=void 0,this.lastObservedClientId=void 0,this.lastSavedAccessToken=void 0,this.pendingAuthAccessToken=void 0}assertStoredIssuerBindings(e,n){if(this.flowIssuerMismatch)throw new Error(`OAuth authorization server issuer changed for ${this.serverName}; clear credentials before authenticating again`);if(!e||!n)return;if([e.clientInfo?.issuer,e.tokens?.issuer].filter(o=>o!==void 0).some(o=>!Ao(o,n)))throw this.flowIssuerMismatch=!0,new Error(`OAuth authorization server issuer changed for ${this.serverName}; clear credentials before authenticating again`)}throwIfInactive(){if(!this.active)throw new Error("OAuth flow is no longer active");this.runtimeSignal?.throwIfAborted()}get redirectUrl(){return this.redirectUrlSnapshot}get clientUri(){return this.config.clientUri??Rm()}get clientMetadata(){if(this.usesClientCredentials)return{client_name:this.config.clientName??hu(),...this.clientUri!==void 0?{client_uri:this.clientUri}:{},...this.config.logoUri!==void 0?{logo_uri:this.config.logoUri}:{},redirect_uris:[],grant_types:["client_credentials"],token_endpoint_auth_method:this.config.clientSecret?"client_secret_post":"none"};let e=this.redirectUrl;if(!e)throw new Error("redirectUrl is required for authorization_code flow");return{redirect_uris:[e],client_name:this.config.clientName??hu(),...this.clientUri!==void 0?{client_uri:this.clientUri}:{},...this.config.logoUri!==void 0?{logo_uri:this.config.logoUri}:{},grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:this.config.clientSecret?"client_secret_post":"none",...this.config.scope!==void 0?{scope:this.config.scope}:{}}}async clientInformation(){this.invalidatedClientId!==void 0&&at(this.serverName);let e=this.discoveredIssuer,n=await kn(this.serverName,this.serverUrl,this.storageOptions);if(this.assertStoredIssuerBindings(n,e),this.config.clientId){let o=n?.clientInfo?.clientId===this.config.clientId?n.clientInfo:void 0;e&&(o?.issuer!==e||o.configPreRegistered!==!0)&&mr(this.serverName,{clientId:this.config.clientId,issuer:e,configPreRegistered:!0},this.serverUrl,this.storageOptions);let i=this.config.clientSecret?.startsWith("!")?cr(this.config.clientSecret,`MCP server "${this.serverName}" OAuth clientSecret`):this.config.clientSecret;return{client_id:this.config.clientId,client_secret:i,...e!==void 0?{issuer:e}:{}}}let r=this.flowClientInfo??n?.clientInfo;if(r?.clientId!==this.invalidatedClientId&&r)return this.invalidatedClientId=void 0,r.configPreRegistered===!0||r.clientSecret===void 0&&r.clientIdIssuedAt===void 0&&r.clientSecretExpiresAt===void 0&&r.redirectUris===void 0||r.clientSecretExpiresAt&&r.clientSecretExpiresAt<Date.now()/1e3||e&&r.issuer&&!Ao(r.issuer,e)?void 0:(e&&r.issuer===void 0&&(r.issuer=e,this.flowClientInfo=r,mr(this.serverName,r,this.serverUrl,this.storageOptions)),this.lastObservedClientId=r.clientId,{client_id:r.clientId,client_secret:r.clientSecret,...r.clientIdIssuedAt!==void 0?{client_id_issued_at:r.clientIdIssuedAt}:{},...r.clientSecretExpiresAt!==void 0?{client_secret_expires_at:r.clientSecretExpiresAt}:{},...r.redirectUris!==void 0?{redirect_uris:r.redirectUris}:{},...r.issuer!==void 0?{issuer:r.issuer}:{}})}async saveClientInformation(e){this.throwIfInactive();let n=this.discoveredIssuer??e.issuer;if(this.config.clientId&&e.client_id===this.config.clientId){mr(this.serverName,{clientId:e.client_id,...n!==void 0?{issuer:n}:{},configPreRegistered:!0},this.serverUrl,this.storageOptions);return}let r=("redirect_uris"in e?e.redirect_uris:void 0)??(this.redirectUrl?[this.redirectUrl]:void 0),o={clientId:e.client_id,...e.client_secret!==void 0?{clientSecret:e.client_secret}:{},...e.client_id_issued_at!==void 0?{clientIdIssuedAt:e.client_id_issued_at}:{},...e.client_secret_expires_at!==void 0?{clientSecretExpiresAt:e.client_secret_expires_at}:{},...r!==void 0?{redirectUris:r}:{},...n!==void 0?{issuer:n}:{}};this.flowClientInfo=o,this.invalidatedClientId=void 0,this.lastObservedClientId=o.clientId,mr(this.serverName,o,this.serverUrl,this.storageOptions)}async tokens(e){this.invalidatedAccessToken!==void 0&&at(this.serverName);let n=await kn(this.serverName,this.serverUrl,this.storageOptions);if(!n?.tokens||n.tokens.accessToken===this.invalidatedAccessToken)return;this.invalidatedAccessToken=void 0;let r=this.discoveredIssuer;return this.assertStoredIssuerBindings(n,r),r&&n.tokens.issuer===void 0&&(n.tokens.issuer=r,rs(this.serverName,n.tokens,this.serverUrl,this.storageOptions)),e!==void 0&&(this.pendingAuthAccessToken=n.tokens.accessToken),Em(n.tokens)}async saveTokens(e){let n=this.discoveredIssuer??e.issuer,r={accessToken:e.access_token,...e.refresh_token!==void 0?{refreshToken:e.refresh_token}:{},...e.expires_in!==void 0?{expiresAt:Date.now()/1e3+e.expires_in}:{},...e.scope!==void 0?{scope:e.scope}:{},...n!==void 0?{issuer:n}:{}};this.throwIfInactive(),rs(this.serverName,r,this.serverUrl,this.storageOptions),this.invalidatedAccessToken=void 0,this.lastSavedAccessToken=r.accessToken,this.flowDiscoveryState=void 0}async redirectToAuthorization(e){if(this.usesClientCredentials)throw new Error("redirectToAuthorization is not used for client_credentials flow");if(this.throwIfInactive(),!this.flowState)throw new mu(`Re-authentication required for MCP server: ${this.serverName}`);await this.callbacks.onRedirect($m(e,this.config.authorizationParams))}async saveCodeVerifier(e){this.throwIfInactive(),this.flowCodeVerifier=e}async codeVerifier(){if(this.usesClientCredentials)throw new Error("codeVerifier is not used for client_credentials flow");if(this.throwIfInactive(),!this.flowCodeVerifier)throw new Error(`No code verifier saved for MCP server: ${this.serverName}`);return this.flowCodeVerifier}async saveDiscoveryState(e){this.throwIfInactive(),this.flowDiscoveryState=structuredClone(e)}async discoveryState(){return this.throwIfInactive(),!this.flowDiscoveryState&&this.config.authServerMetadataUrl!==void 0&&(this.flowDiscoveryState=await Um(this.config.authServerMetadataUrl,this.serverUrl,this.config.skipIssuerMetadataValidation===!0,this.runtimeSignal)),this.flowDiscoveryState?structuredClone(this.flowDiscoveryState):void 0}async saveState(e){this.throwIfInactive(),this.flowState=e}async state(){if(this.usesClientCredentials)throw new Error("state is not used for client_credentials flow");if(this.throwIfInactive(),!this.flowState)throw new mu(`Re-authentication required for MCP server: ${this.serverName}`);return this.flowState}async invalidateCredentials(e){switch(this.throwIfInactive(),e){case"all":this.flowClientInfo=void 0,this.flowCodeVerifier=void 0,this.flowDiscoveryState=void 0,this.flowIssuerMismatch=!1,this.flowState=void 0,this.invalidatedAccessToken=void 0,this.invalidatedClientId=void 0,this.lastObservedClientId=void 0,this.lastSavedAccessToken=void 0,this.pendingAuthAccessToken=void 0,Mo(this.serverName,this.storageOptions);break;case"client":this.invalidatedClientId=this.lastObservedClientId,this.lastObservedClientId=void 0,this.flowClientInfo=void 0,at(this.serverName);break;case"tokens":this.invalidatedAccessToken=this.pendingAuthAccessToken??this.lastSavedAccessToken,this.lastSavedAccessToken=void 0,this.pendingAuthAccessToken=void 0,at(this.serverName);break;case"verifier":$n(this.serverName,this.storageOptions);break;case"discovery":this.flowDiscoveryState=void 0;break}}addClientAuthentication=async(e,n,r,o)=>{this.throwIfInactive(),n.get("grant_type")==="authorization_code"&&!n.has("scope")&&this.config.scope&&n.set("scope",this.config.scope);let i=await this.clientInformation();if(this.throwIfInactive(),!i)return;let s=o?.token_endpoint_auth_methods_supported??[],a=i.client_secret!==void 0,c;if(s.length===0?c=a?"client_secret_post":"none":a&&s.includes("client_secret_basic")?c="client_secret_basic":a&&s.includes("client_secret_post")?c="client_secret_post":s.includes("none")?c="none":c=a?"client_secret_post":"none",c==="client_secret_basic"){if(!i.client_secret)throw new Error("client_secret_basic authentication requires a client_secret");e.set("Authorization",`Basic ${Buffer.from(`${i.client_id}:${i.client_secret}`).toString("base64")}`);return}n.has("client_id")||n.set("client_id",i.client_id),c==="client_secret_post"&&i.client_secret&&!n.has("client_secret")&&n.set("client_secret",i.client_secret)};prepareTokenRequest(e){if(!this.usesClientCredentials)return;let n=new URLSearchParams({grant_type:"client_credentials"}),r=e??this.config.scope;return r&&n.set("scope",r),n}};import{auth as fs,extractWWWAuthenticateParams as qm,LATEST_PROTOCOL_VERSION as Vm,UnauthorizedError as ps}from"@modelcontextprotocol/client";import Km from"open";tt();import{createServer as Dm}from"http";var Nm=`
|
|
13
13
|
:root { color-scheme: light dark; }
|
|
@@ -83,7 +83,7 @@ var Cf=Object.defineProperty;var je=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&
|
|
|
83
83
|
${t.autoClose?` <script>setTimeout(() => window.close(), 2000);</script>
|
|
84
84
|
`:""}</body>
|
|
85
85
|
</html>`}function $o(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function jm(){let t=$o(Lt());return as({title:`${t} \u2014 Authorization Successful`,heading:"Authorization Successful",body:`You can close this window and return to <span class="app">${t}</span>.`,icon:Su,tone:"ok",autoClose:!0})}function Bm(){let t=$o(Lt());return as({title:`${t} \u2014 Authorization Received`,heading:"Authorization Received",body:`Copy the full callback URL from your browser address bar and paste it back into <span class="app">${t}</span> with auth-complete.`,icon:Su,tone:"ok"})}function yr(t){let e=$o(Lt());return as({title:`${e} \u2014 Authorization Failed`,heading:"Authorization Failed",body:`Something went wrong during authorization. You can close this window and try again from <span class="app">${e}</span>.`,icon:Lm,tone:"bad",extra:`<code>${$o(t)}</code>`})}var Yt,Et,kt,_n,In=0,Je=new Map,Ze=new Set,Hm=300*1e3,cs="localhost",Oo=cs;function Fm(t,e){let n=new URL(t.url||"/",`http://${t.headers.host}`);if(n.pathname!==hr()){e.writeHead(404,{"Content-Type":"text/plain"}),e.end("Not found");return}let r=n.searchParams.get("code"),o=n.searchParams.get("iss"),i=n.searchParams.get("state"),s=n.searchParams.get("error"),a=n.searchParams.get("error_description");if(!i){let d="Missing required state parameter - potential CSRF attack";e.writeHead(400,{"Content-Type":"text/html"}),e.end(yr(d));return}let c=Je.get(i),u=Ze.has(i);if(s){if(!c&&!u){let l="Invalid or expired state parameter - potential CSRF attack";e.writeHead(400,{"Content-Type":"text/html"}),e.end(yr(l));return}let d=a||s;e.writeHead(200,{"Content-Type":"text/html"}),e.end(yr(d)),c&&(Ze.delete(i),clearTimeout(c.timeout),Je.delete(i),setTimeout(()=>c.reject(new Error(d)),0));return}if(!c&&!u){let d="Invalid or expired state parameter - potential CSRF attack";e.writeHead(400,{"Content-Type":"text/html"}),e.end(yr(d));return}if(!r){e.writeHead(400,{"Content-Type":"text/html"}),e.end(yr("No authorization code provided"));return}if(!c){e.writeHead(200,{"Content-Type":"text/html"}),e.end(Bm());return}clearTimeout(c.timeout),Je.delete(i),c.resolve({code:r,...o!==null?{iss:o}:{}}),e.writeHead(200,{"Content-Type":"text/html"}),e.end(jm())}async function wu(t={}){let e=In;if(kt){if(!_n)throw new Error("OAuth callback server stopped");if(await _n,e!==In)throw new Error("OAuth callback server stopped")}for(;Et;)if(await Et,e!==In)throw new Error("OAuth callback server stopped");if(e!==In)throw new Error("OAuth callback server stopped");let n=zm(t);Et=n;try{await n}finally{Et===n&&(Et=void 0)}}async function zm(t={}){let e=t.port??ss(),n=t.strictPort===!0,r=t.callbackHost??cs,o=t.callbackPath??Po,i=o.startsWith("/")?o:`/${o}`;if(t.reserveState&&!t.oauthState)throw new Error("OAuth callback reservation requires an oauthState");let s,a=Yt,c=!!(a&&n&&Ro()!==e),u=!!(a&&Oo!==r),d=!!(a&&hr()!==i);if(a){if(!c&&!u){if(d){if(Je.size>0||Ze.size>0)throw new Error(`OAuth callback server is using path ${hr()}, but callback path ${i} is required and cannot be switched while authorizations are pending`);ko(i)}t.reserveState&&t.oauthState&&(Ze.add(t.oauthState),s=t.oauthState);return}if(Je.size>0||Ze.size>0)throw new Error(`OAuth callback server is running on ${Oo}:${Ro()}, but strict callback endpoint ${r}:${e} is required and cannot be switched while authorizations are pending`)}let l=Dm(Fm),f=n?e:0;try{if(await new Promise((p,g)=>{l.once("error",y=>{g(y)}),l.listen(f,r,()=>{p()})}),n)Eo(e);else{let p=l.address();if(!p||typeof p=="string"||typeof p.port!="number")throw new Error("OAuth callback server did not report an assigned port");Eo(p.port)}a&&(c||u)&&await new Promise(p=>{a.close(()=>p())}),Oo=r,ko(i),Yt=l,t.reserveState&&t.oauthState&&(Ze.add(t.oauthState),s=t.oauthState),Yt.unref()}catch(p){s&&Ze.delete(s);let g=p;throw await new Promise(y=>{l.close(()=>y())}),n&&g.code==="EADDRINUSE"?new Error(`OAuth callback port ${e} is already in use. Pre-registered OAuth clients require an exact redirect URI; set MCP_OAUTH_CALLBACK_PORT to your registered port or free port ${e}`,{cause:p}):p}}function us(t){Ze.delete(t)}function bu(t){return Ze.delete(t),new Promise((e,n)=>{let r=setTimeout(()=>{Je.has(t)&&(Je.delete(t),n(new Error("OAuth callback timeout - authorization took too long")))},Hm);Je.set(t,{resolve:e,reject:n,timeout:r})})}function Un(t){Ze.delete(t);let e=Je.get(t);e&&(clearTimeout(e.timeout),Je.delete(t),e.reject(new Error("Authorization cancelled")))}function ls(){if(kt)return _n=void 0,In+=1,kt;In+=1;let e=(async()=>{for(;Et;)await Et.catch(()=>{});Yt&&(await new Promise(r=>{Yt.close(()=>{r()})}),Yt=void 0),Eo(ss()),Oo=cs,ko(Po);let n=Array.from(Je.entries());Je.clear(),Ze.clear(),setTimeout(()=>{for(let[,r]of n)clearTimeout(r.timeout),r.reject(new Error("OAuth callback server stopped"))},0)})().finally(()=>{kt===e&&(kt=void 0)});return kt=e,e}function ds(){if(kt)return kt;if(Et||!Yt||Je.size>0||Ze.size>0)return Promise.resolve();let t=ls().finally(()=>{_n===t&&(_n=void 0)});return _n=t,t}ue();be();be();function Dn(){let t=new AbortController,e=[],n,r=(o,i)=>{console.error(`MCP: ${i?"late ":""}runtime cleanup failed: ${_e(o)}`)};return{signal:t.signal,isActive:()=>!t.signal.aborted,addCleanup:o=>{if(t.signal.aborted){Promise.resolve().then(o).catch(i=>r(i,!0));return}e.push(o)},stop:(o="MCP extension runtime stopped")=>{if(n)return n;t.abort(new Error(o));let i=e.splice(0).reverse().map(s=>Promise.resolve().then(s));return n=Promise.allSettled(i).then(s=>{let a=s.flatMap(c=>c.status==="rejected"?[c.reason]:[]);if(a.length>0){let c=new AggregateError(a,"MCP runtime cleanup failed");throw console.error(`MCP: runtime cleanup failed: ${_e(c)}`),c}}),n},throwIfInactive:()=>t.signal.throwIfAborted()}}function te(...t){let e=t.filter(n=>n!==void 0);if(e.length!==0)return e.length===1?e[0]:AbortSignal.any(e)}function vr(t,e){let n=new WeakMap,r=o=>{if((typeof o!="object"||o===null)&&typeof o!="function")return o;let i=o,s=n.get(i);if(s)return s;let a=new Proxy(i,{get(c,u,d){if(!e.isActive())return;let l=Reflect.get(c,u,d);return typeof l=="function"?(...f)=>{if(e.isActive())return Reflect.apply(l,c,f)}:e.isActive()?r(l):void 0}});return n.set(i,a),a};return r(t)}function ie(t,e){return e?.aborted?!0:t instanceof Error&&(t.name==="AbortError"||t.message==="MCP extension runtime stopped")}function Cu(t,e){return{...t,...e.scope!==void 0?{scope:e.scope}:{},...e.skipIssuerMetadataValidation===!0?{skipIssuerMetadataValidation:!0}:{}}}var Mu=new WeakMap,Nn=new Set;function $t(t){let e=new AbortController,n={signal:te(t,e.signal)};return Mu.set(n,{controller:e,generation:0,pendingAuths:new Map,pendingAuthStates:new Map,pendingAuthCleanupTimers:new Map,pendingAuthentications:new Map}),Nn.add(n),n}var Xt=$t();Nn.delete(Xt);function Sr(t){return t?.runtime?(t.runtime.signal.throwIfAborted(),Nn.add(t.runtime),t.runtime):(Xt.signal.aborted&&(Xt=$t()),Nn.add(Xt),Xt)}function gt(t){let e=Mu.get(t);if(!e)throw new Error("Unknown OAuth runtime");return e}function Ot(t,e){return`${t}|${Co(e)}`}function Io(t,e,n){let r=gt(n??Xt);return e?r.pendingAuths.has(Ot(t,e)):Array.from(r.pendingAuths.values()).some(o=>o.serverName===t)}var Jm=300*1e3;function Wm(){return Array.from(crypto.getRandomValues(new Uint8Array(32))).map(t=>t.toString(16).padStart(2,"0")).join("")}function gs(t){if(t.oauth===!1)return{};let e={};if(t.oauth?.grantType!==void 0&&(e.grantType=t.oauth.grantType),t.oauth?.clientId!==void 0){if(typeof t.oauth.clientId!="string")throw new Error("OAuth clientId must be a string");e.clientId=le(t.oauth.clientId)}if(t.oauth?.clientSecret!==void 0){if(typeof t.oauth.clientSecret!="string")throw new Error("OAuth clientSecret must be a string");e.clientSecret=t.oauth.clientSecret.startsWith("!")?t.oauth.clientSecret:le(t.oauth.clientSecret)}if(t.oauth?.scope!==void 0){if(typeof t.oauth.scope!="string")throw new Error("OAuth scope must be a string");e.scope=le(t.oauth.scope)}if(t.oauth?.authorizationParams!==void 0){let n=t.oauth.authorizationParams;if(!n||typeof n!="object"||Array.isArray(n))throw new Error("OAuth authorizationParams must be an object");e.authorizationParams={};for(let[r,o]of Object.entries(n)){if(!r)throw new Error("OAuth authorizationParams keys must not be empty");if(typeof o!="string")throw new Error(`OAuth authorizationParams.${r} must be a string`);e.authorizationParams[r]=le(o)}}if(t.oauth?.redirectUri!==void 0){if(typeof t.oauth.redirectUri!="string")throw new Error("OAuth redirectUri must be a string");let n=le(t.oauth.redirectUri).trim();if(!n)throw new Error("OAuth redirectUri must not be empty");e.redirectUri=n}if(t.oauth?.clientName!==void 0){if(typeof t.oauth.clientName!="string")throw new Error("OAuth clientName must be a string");let n=le(t.oauth.clientName).trim();if(!n)throw new Error("OAuth clientName must not be empty");e.clientName=n}if(t.oauth?.clientUri!==void 0){if(typeof t.oauth.clientUri!="string")throw new Error("OAuth clientUri must be a string");let n=le(t.oauth.clientUri).trim();if(!n)throw new Error("OAuth clientUri must not be empty");e.clientUri=n}if(t.oauth?.logoUri!==void 0){if(typeof t.oauth.logoUri!="string")throw new Error("OAuth logoUri must be a string");let n=le(t.oauth.logoUri).trim();if(!n)throw new Error("OAuth logoUri must not be empty");let r;try{r=new URL(n)}catch{throw new Error("OAuth logoUri must be an absolute http(s) URL")}if(r.protocol!=="https:"&&r.protocol!=="http:")throw new Error("OAuth logoUri must be an absolute http(s) URL");e.logoUri=n}if(t.oauth?.authServerMetadataUrl!==void 0){if(typeof t.oauth.authServerMetadataUrl!="string")throw new Error("OAuth authServerMetadataUrl must be a string");let n=le(t.oauth.authServerMetadataUrl).trim();if(!n)throw new Error("OAuth authServerMetadataUrl must not be empty");let r;try{r=new URL(n)}catch{throw new Error("OAuth authServerMetadataUrl must be an absolute https:// URL")}if(r.protocol!=="https:")throw new Error("OAuth authServerMetadataUrl must be an absolute https:// URL");e.authServerMetadataUrl=n}if(t.oauth?.skipIssuerMetadataValidation!==void 0){if(typeof t.oauth.skipIssuerMetadataValidation!="boolean")throw new Error("OAuth skipIssuerMetadataValidation must be a boolean");e.skipIssuerMetadataValidation=t.oauth.skipIssuerMetadataValidation}return e}async function xu(t,e,n){let r=e?.headers?Object.fromEntries(Object.entries(e.headers).filter(([,c])=>!c.startsWith("!")||c.startsWith("!!"))):void 0,o=new Headers(yn(r));o.set("content-type","application/json");let i=new AbortController,s=te(n,i.signal),a=setTimeout(()=>i.abort(),5e3);try{o.set("accept","application/json, text/event-stream");let c=await fetch(new URL(t),{method:"POST",headers:o,body:JSON.stringify({jsonrpc:"2.0",id:0,method:"initialize",params:{protocolVersion:Vm,capabilities:{},clientInfo:{name:"pi-mcp-adapter",version:"2.11.0"}}}),...s?{signal:s}:{}}),{resourceMetadataUrl:u,scope:d}=qm(c);return await c.body?.cancel().catch(()=>{}),{...u?{resourceMetadataUrl:u}:{},...d?{scope:d}:{}}}catch{return n?.aborted&&D(n),{}}finally{clearTimeout(a)}}function Gm(t){let e;try{e=new URL(t)}catch(s){throw new Error(`Invalid OAuth redirectUri: ${t}`,{cause:s})}if(e.username||e.password)throw new Error("OAuth redirectUri must not include username or password");if(e.hash)throw new Error("OAuth redirectUri must not include a fragment");let n=e.hostname.toLowerCase(),r=n==="localhost"||n==="127.0.0.1"||n==="[::1]"||n==="::1";if(e.port){let s=Number.parseInt(e.port,10);if(!Number.isInteger(s)||s<=0||s>65535)throw new Error("OAuth redirectUri port must be a positive numeric port")}if(e.protocol==="https:"&&!r)return{mode:"manual"};if(e.protocol!=="http:"||!r)throw new Error("OAuth redirectUri must be an https:// URI or an http:// localhost or loopback URI");if(!e.port)throw new Error("OAuth localhost redirectUri must include an explicit numeric port");let o=Number.parseInt(e.port,10);if(!Number.isInteger(o)||o<=0||o>65535)throw new Error("OAuth localhost redirectUri must include an explicit numeric port");return{mode:"local",port:o,callbackHost:n==="[::1]"?"::1":n,callbackPath:e.pathname}}async function Ln(t,e,n,r={}){if(U(n))throw new Error(`MCP server "${t}" is disabled`);let o=Sr(r),i=gt(o),s=n?gs(n):{},a=r.authStorageOptions??{},c=te(o.signal,r.signal),u=i.generation;if(D(c),s.grantType==="client_credentials"){let w=await kn(t,e,a);w?.clientInfo&&!w.tokens&&!s.clientId&&(To(t,a),$n(t,a),await Rt(t,a));let b=new Gt(t,e,s,{onRedirect:async()=>{throw new Error("Browser redirect is not used for client_credentials flow")}},a,o.signal);try{let v=Cu(await xu(e,n,c),s);D(c);let m=await ve(fs(b,{serverUrl:e,...v}),c);if(D(c),m!=="AUTHORIZED")throw new ps("Failed to authorize");return{authorizationUrl:""}}finally{b.deactivate()}}let d=i.pendingAuths.get(Ot(t,a));if(d?.serverUrl===e)return{authorizationUrl:d.authorizationUrl};let l=s.redirectUri!==void 0?Gm(s.redirectUri):void 0,f=l?.mode==="manual",p=Wm();if(!f)try{await wu({strictPort:!!s.clientId||s.redirectUri!==void 0,oauthState:p,reserveState:!0,...l?.mode==="local"?{port:l.port,callbackHost:l.callbackHost,callbackPath:l.callbackPath}:{}}),D(c)}catch(w){us(p);try{await Tu(()=>Rt(t,a))}catch(b){throw new AggregateError([w,b],"OAuth startup cleanup failed")}throw w}let g,y=new Gt(t,e,s,{onRedirect:async w=>{g=w}},a,o.signal,p);try{let w=await kn(t,e,a);if(w?.clientInfo&&!s.clientId)if(!w.tokens)To(t,a),$n(t,a),await Rt(t,a);else{let m=w.clientInfo.redirectUris;(!Array.isArray(m)||!m.includes(y.redirectUrl??""))&&(To(t,a),gu(t,a),$n(t,a),await Rt(t,a))}D(c);let b=Cu(await xu(e,n,c),s);D(c);let v=await ve(fs(y,{serverUrl:e,...b}),c);if(D(c),v==="AUTHORIZED")return y.deactivate(),us(p),await Rt(t,a),await ds(),{authorizationUrl:""};if(!g)throw new ps("OAuth authorization URL was not provided");return await Ym(o,t,{serverName:t,authProvider:y,serverUrl:e,authorizationUrl:g.toString(),manualRedirect:f,...f?{manualCompletionController:new AbortController}:{},discovery:b,authStorageOptions:a},p,c,u),{authorizationUrl:g.toString()}}catch(w){y.deactivate();try{await wr(o,t,p,a)}catch(b){throw new AggregateError([w,b],"OAuth startup cleanup failed")}throw w}}async function Ym(t,e,n,r,o,i=gt(t).generation){let s=gt(t),a=Ot(e,n.authStorageOptions);if(await ms(t,e,void 0,n.authStorageOptions),D(o),i!==s.generation)throw new Error("OAuth runtime stopped");s.pendingAuths.set(a,n),s.pendingAuthStates.set(a,r);let c=setTimeout(()=>{wr(t,e,r,n.authStorageOptions,new Error("OAuth authorization timeout - authorization took too long")).catch(u=>{console.error(`MCP Auth: Timed-out flow cleanup failed: ${_e(u)}`)})},Jm);c.unref?.(),s.pendingAuthCleanupTimers.set(a,c)}async function ms(t,e,n,r={},o=new Error("Authorization cancelled")){let i=gt(t),s=Ot(e,r),a=i.pendingAuths.get(s),c=a?.authStorageOptions??r,u=i.pendingAuthStates.get(s);if(n&&u&&u!==n)return;let d=i.pendingAuthCleanupTimers.get(s);d&&(clearTimeout(d),i.pendingAuthCleanupTimers.delete(s)),a?.manualCompletionController?.abort(o),a?.authProvider.deactivate(),i.pendingAuths.delete(s),i.pendingAuthStates.delete(s);let l=u??n;l&&(Un(l),await os(e,c)===l&&await Rt(e,c))}async function wr(t,e,n,r={},o){await Tu(()=>ms(t,e,n,r,o))}async function Tu(t){let e;try{await t()}catch(n){e={error:n}}try{await ds()}catch(n){throw e?new AggregateError([e.error,n],"OAuth callback cleanup failed"):n}if(e)throw e.error}function hs(t){try{let e=new URL(t),n=new URLSearchParams(e.search);if(e.hash){let r=e.hash.startsWith("#")?e.hash.slice(1):e.hash,o=new URLSearchParams(r);for(let[i,s]of o)n.has(i)||n.set(i,s)}return n}catch{let e=t.includes("?")?t.slice(t.indexOf("?")+1):t,n=new URLSearchParams(e.startsWith("#")?e.slice(1):e);return n.has("code")||n.has("state")||n.has("error")?n:void 0}}function Au(t,e){let n=t.trim();if(!n)throw new Error("Authorization code or redirect URL is required");let r=hs(n);if(r){let o=r.get("error");if(o){let a=r.get("error_description");throw new Error(a?`${o}: ${a}`:o)}let i=r.get("state");if(e&&!i)throw new Error("OAuth state missing from redirect URL");if(e&&i!==e)throw new Error("OAuth state mismatch - potential CSRF attack");let s=r.get("code");if(s){let a=r.get("iss");return{code:s,...a!==null?{iss:a}:{}}}}if(/^[A-Za-z0-9._~+/=-]+$/.test(n))return{code:n};throw new Error("Could not find an OAuth authorization code in the provided input")}function Xm(t){return new Promise((e,n)=>{let r=()=>{n(t.reason instanceof Error?t.reason:new Error("Authorization cancelled"))};if(t.aborted){r();return}t.addEventListener("abort",r,{once:!0})})}async function Qm(t,e,n,r,o){if(!r)return{input:await ve(t,o),source:"callback"};let i=new AbortController;try{let s=await ve(Promise.race([t.then(a=>({input:a,source:"callback"})),r(e,i.signal).then(a=>({input:a,source:"manual"}))]),o);if(s.source==="callback")return s;if(!s.input?.trim())throw new Error("OAuth authentication cancelled");if(!hs(s.input.trim()))throw new Error("Paste the full OAuth callback URL, including its code and state parameters");return{input:Au(s.input,n),source:"manual"}}finally{i.abort()}}async function br(t,e,n={}){let r=Sr(n),o=gt(r),i=n.authStorageOptions??{},s=te(r.signal,n.signal);D(s);let a=Ot(t,i),c=o.pendingAuthStates.get(a),u=o.pendingAuths.get(a);if(D(s),u?.manualRedirect&&!hs(e.trim()))throw new Error("Paste the full OAuth callback URL, including its code and state parameters");let d=Au(e,c);return Pu(t,d,n)}async function Pu(t,e,n={}){let r=Sr(n),o=gt(r),{code:i,iss:s}=typeof e=="string"?{code:e,iss:void 0}:e,a=n.authStorageOptions??{},c=te(r.signal,n.signal);D(c);let u=Ot(t,a),d=o.pendingAuths.get(u),l=d?.authStorageOptions??a;if(!d)throw new Error(`No pending OAuth flow for server: ${t}`);let f=o.pendingAuthStates.get(u);D(c);let p=!1,g;try{let y=await d.authProvider.discoveryState(),w=y?.authorizationServerMetadata,b=w?.issuer??y?.authorizationServerUrl,v=w?.authorization_response_iss_parameter_supported===!0;if(b!==void 0&&s===void 0&&v)throw p=!0,new Error(`The authorization server for ${t} requires the RFC 9207 "iss" parameter. Paste the full redirect URL from the browser address bar (not just the authorization code).`);if(b!==void 0&&s!==void 0&&s!==b)throw new Error(`The OAuth authorization response issuer does not match the discovered issuer for ${t}.`);let m=await ve(fs(d.authProvider,{serverUrl:d.serverUrl,authorizationCode:i,...s!==void 0?{iss:s}:{},...d.discovery}),c);if(D(c),m!=="AUTHORIZED")throw new ps("Failed to authorize");return"authenticated"}catch(y){throw g=y,y}finally{if(!p)try{await wr(r,t,f,l)}catch(y){throw g!==void 0?new AggregateError([g,y],"OAuth completion cleanup failed"):y}}}async function mt(t,e,n,r={}){if(U(n))throw new Error(`MCP server "${t}" is disabled`);let o=Sr(r),i=gt(o),s=r.authStorageOptions??{},a=te(o.signal,r.signal);D(a);let c=`${t}|${e}|${Co(s)}`,u=i.pendingAuthentications.get(c);if(u)return u;let d=(async()=>{let{authorizationUrl:l}=await Ln(t,e,n,{...r,...a?{signal:a}:{},runtime:o});if(!l)return"authenticated";let f;try{if(f=i.pendingAuthStates.get(Ot(t,s)),D(a),!f)throw new Error("OAuth state not found - this should not happen");let p=i.pendingAuths.get(Ot(t,s));if(!p)throw new Error(`No pending OAuth flow for server: ${t}`);if(p.manualRedirect&&!r.onAuthorizationInput)throw new Error(`OAuth for ${t} uses a remote redirect URI. Complete it with auth-start/auth-complete or /mcp-auth.`);let g=p.manualRedirect?Xm(p.manualCompletionController.signal):bu(f);g.catch(()=>{}),r.onAuthorizationUrl?await ve(Promise.resolve(r.onAuthorizationUrl(l)),a):console.log(`MCP Auth: Open this URL to authenticate ${t}:
|
|
86
|
-
${l}`);try{await ve(Km(l),a)}catch(w){if(ie(w,a))throw w;console.warn(`MCP Auth: Failed to open browser for ${t}; waiting for manual callback`,{error:w})}let y=await Qm(g,l,f,r.onAuthorizationInput,a);return y.source==="manual"&&Un(f),D(a),await Pu(t,y.input,{...r,...a?{signal:a}:{},runtime:o})}catch(p){f&&Un(f);try{await wr(o,t,f,s)}catch(g){throw new AggregateError([p,g],"OAuth cancellation cleanup failed")}throw p}})();i.pendingAuthentications.set(c,d);try{return await d}finally{i.pendingAuthentications.get(c)===d&&i.pendingAuthentications.delete(c)}}async function Ru(t,e={}){let n=Sr(e),r=te(n.signal,e.signal);D(r);let o=e.authStorageOptions??{},i=await os(t,o);D(r),i&&Un(i),await wr(n,t,i,o),D(r),Mo(t,o),await Rt(t,o),D(r),console.log(`MCP Auth: Removed credentials for ${t}`)}function Ue(t){return!t.url||t.auth===!1||t.oauth===!1?!1:t.auth==="oauth"?!0:t.headers&&Object.keys(t.headers).length>0?!1:t.auth===void 0}async function jn(t=Xt){let e=gt(t);if(!e.controller.signal.aborted){e.generation+=1,e.controller.abort(new Error("OAuth runtime stopped"));for(let n of Array.from(e.pendingAuthStates.values()))Un(n);for(let n of Array.from(e.pendingAuths.values()))await ms(t,n.serverName,void 0,n.authStorageOptions);e.pendingAuthentications.clear(),Nn.delete(t),Nn.size===0&&await ls()}}import{createHash as Zm}from"node:crypto";import{createRequire as eh}from"node:module";import{dirname as th,join as nh}from"node:path";var rh=eh(import.meta.url),oh="pi-mcp-adapter.bearer",ys="PI_MCP_ADAPTER_TEST_AUTH_STORE";var Eu=1280,ku,Bn=new Map,Ss=0,Hn=class extends Error{code="BEARER_CREDENTIAL_STORE_UNAVAILABLE";operation;constructor(e,n,r){super(e,{cause:r}),this.name="BearerCredentialStoreError",this.operation=n}},ih={read(t){return Ss++,Bn.get(t)},write(t,e){Bn.set(t,e)},remove(t){Bn.delete(t)}},sh={read(t){return Ss++,Bn.get(t)},write(t,e){if(e.length>Eu)throw new Error(`Value of 'password encoded as UTF-16' is longer than the platform limit of ${Eu*2} chars`);Bn.set(t,e)},remove(t){Bn.delete(t)}},ah={read(){throw Ss++,new Error("simulated secure credential store unavailable")},write(){throw new Error("simulated secure credential store unavailable")},remove(){throw new Error("simulated secure credential store unavailable")}},ch={read(t){return vs(t).getPassword()??void 0},write(t,e){vs(t).setPassword(e)},remove(t){vs(t).deleteCredential()}};function ws(){return process.env[ys]==="memory"?ih:process.env[ys]==="sizelimited"?sh:process.env[ys]==="unavailable"?ah:ch}function vs(t){try{return ku??=uh(),new ku(oh,t)}catch(e){throw new Error("Bearer token secure credential storage is unavailable. Configure the OS credential store and retry.",{cause:e})}}function uh(t=rh,e=process.platform,n=process.arch){try{return t("@napi-rs/keyring").Entry}catch(r){try{return lh(t,e,n).Entry}catch(o){let i=o instanceof Error?o.message:String(o);throw new Error(`Failed to load @napi-rs/keyring; absolute-path native binding fallback also failed: ${i}`,{cause:r})}}}function lh(t,e,n){let r=dh(e,n).map(i=>({packageName:`@napi-rs/keyring-${i}`,bindingFile:`keyring.${i}.node`})),o;for(let i of r)try{let s=t.resolve(`${i.packageName}/package.json`);return t(nh(th(s),i.bindingFile))}catch(s){o=s}throw o instanceof Error?o:new Error(String(o))}function dh(t,e){if(t==="darwin"){if(e==="arm64")return["darwin-arm64"];if(e==="x64")return["darwin-x64"]}if(t==="win32"){if(e==="arm64")return["win32-arm64-msvc"];if(e==="x64")return["win32-x64-msvc"];if(e==="ia32")return["win32-ia32-msvc"]}if(t==="linux"){if(e==="arm64")return["linux-arm64-gnu","linux-arm64-musl"];if(e==="arm")return["linux-arm-gnueabihf"];if(e==="riscv64")return["linux-riscv64-gnu"];if(e==="x64")return["linux-x64-gnu","linux-x64-musl"]}return t==="freebsd"&&e==="x64"?["freebsd-x64"]:[]}function Ou(t){if(typeof t!="string")throw new Error(`Invalid MCP server name: ${JSON.stringify(t)}`);return`sha256-${Zm("sha256").update(t,"utf8").digest("hex")}`}function fh(t,e){let n=$u(t,e);if(typeof n!="object"||n===null||Array.isArray(n))throw new Error(`Stored bearer token record for ${t} has invalid shape`);let r=n;if(typeof r.token!="string"||typeof r.serverUrl!="string")throw new Error(`Stored bearer token record for ${t} has invalid shape`);return{token:r.token,serverUrl:r.serverUrl}}function $u(t,e){try{return JSON.parse(e)}catch{throw new Error(`Failed to parse stored bearer token record for ${t}`)}}function ph(t){if(typeof t!="object"||t===null)return!1;let e=t;return e.__piMcpAdapterBearerChunked===1&&typeof e.chunkCount=="number"&&Number.isInteger(e.chunkCount)&&e.chunkCount>0&&typeof e.chunkDigest=="string"&&/^[a-f0-9]{16}$/.test(e.chunkDigest)}function Iu(t,e){let n=$u(t,e);return ph(n)?n:void 0}function gh(t,e,n){return`${t}.chunk.${e.chunkDigest}.${n}`}function _u(t,e){return Array.from({length:e.chunkCount},(n,r)=>gh(t,e,r))}function mh(t,e,n){if(n)for(let r of _u(e,n))t.remove(r)}function Uu(t,e){let n=Ou(e),r;try{r=t.read(n)}catch(o){throw new Hn(`Failed to read bearer token for ${e} from the OS secure credential store`,"read",o)}if(r!==void 0)try{let o=Iu(e,r),i=o?_u(n,o).map(s=>{let a=t.read(s);if(a===void 0)throw new Error(`Missing bearer token chunk for ${e}`);return a}).join(""):r;return fh(e,i)}catch(o){throw new Hn(`Failed to read bearer token for ${e} from the OS secure credential store`,"read",o)}}function hh(t,e){let n=Ou(e);try{let r=t.read(n),o=r===void 0?void 0:Iu(e,r);mh(t,n,o),t.remove(n)}catch(r){throw new Hn(`Failed to remove bearer token for ${e} from the OS secure credential store`,"remove",r)}}function Du(t,e){let n=Uu(ws(),t);if(n)return n.serverUrl===e?n.token:void 0}function Nu(t){hh(ws(),t)}function Lu(t,e){try{let n=Uu(ws(),t);return n?n.serverUrl!==e?{status:"url-mismatch"}:{status:"present"}:{status:"missing"}}catch(n){if(!(n instanceof Hn))throw n;return{status:"unavailable",message:"Bearer token secure credential store unavailable. Configure or unlock the OS credential store and retry."}}}be();import{complete as yh}from"
|
|
86
|
+
${l}`);try{await ve(Km(l),a)}catch(w){if(ie(w,a))throw w;console.warn(`MCP Auth: Failed to open browser for ${t}; waiting for manual callback`,{error:w})}let y=await Qm(g,l,f,r.onAuthorizationInput,a);return y.source==="manual"&&Un(f),D(a),await Pu(t,y.input,{...r,...a?{signal:a}:{},runtime:o})}catch(p){f&&Un(f);try{await wr(o,t,f,s)}catch(g){throw new AggregateError([p,g],"OAuth cancellation cleanup failed")}throw p}})();i.pendingAuthentications.set(c,d);try{return await d}finally{i.pendingAuthentications.get(c)===d&&i.pendingAuthentications.delete(c)}}async function Ru(t,e={}){let n=Sr(e),r=te(n.signal,e.signal);D(r);let o=e.authStorageOptions??{},i=await os(t,o);D(r),i&&Un(i),await wr(n,t,i,o),D(r),Mo(t,o),await Rt(t,o),D(r),console.log(`MCP Auth: Removed credentials for ${t}`)}function Ue(t){return!t.url||t.auth===!1||t.oauth===!1?!1:t.auth==="oauth"?!0:t.headers&&Object.keys(t.headers).length>0?!1:t.auth===void 0}async function jn(t=Xt){let e=gt(t);if(!e.controller.signal.aborted){e.generation+=1,e.controller.abort(new Error("OAuth runtime stopped"));for(let n of Array.from(e.pendingAuthStates.values()))Un(n);for(let n of Array.from(e.pendingAuths.values()))await ms(t,n.serverName,void 0,n.authStorageOptions);e.pendingAuthentications.clear(),Nn.delete(t),Nn.size===0&&await ls()}}import{createHash as Zm}from"node:crypto";import{createRequire as eh}from"node:module";import{dirname as th,join as nh}from"node:path";var rh=eh(import.meta.url),oh="pi-mcp-adapter.bearer",ys="PI_MCP_ADAPTER_TEST_AUTH_STORE";var Eu=1280,ku,Bn=new Map,Ss=0,Hn=class extends Error{code="BEARER_CREDENTIAL_STORE_UNAVAILABLE";operation;constructor(e,n,r){super(e,{cause:r}),this.name="BearerCredentialStoreError",this.operation=n}},ih={read(t){return Ss++,Bn.get(t)},write(t,e){Bn.set(t,e)},remove(t){Bn.delete(t)}},sh={read(t){return Ss++,Bn.get(t)},write(t,e){if(e.length>Eu)throw new Error(`Value of 'password encoded as UTF-16' is longer than the platform limit of ${Eu*2} chars`);Bn.set(t,e)},remove(t){Bn.delete(t)}},ah={read(){throw Ss++,new Error("simulated secure credential store unavailable")},write(){throw new Error("simulated secure credential store unavailable")},remove(){throw new Error("simulated secure credential store unavailable")}},ch={read(t){return vs(t).getPassword()??void 0},write(t,e){vs(t).setPassword(e)},remove(t){vs(t).deleteCredential()}};function ws(){return process.env[ys]==="memory"?ih:process.env[ys]==="sizelimited"?sh:process.env[ys]==="unavailable"?ah:ch}function vs(t){try{return ku??=uh(),new ku(oh,t)}catch(e){throw new Error("Bearer token secure credential storage is unavailable. Configure the OS credential store and retry.",{cause:e})}}function uh(t=rh,e=process.platform,n=process.arch){try{return t("@napi-rs/keyring").Entry}catch(r){try{return lh(t,e,n).Entry}catch(o){let i=o instanceof Error?o.message:String(o);throw new Error(`Failed to load @napi-rs/keyring; absolute-path native binding fallback also failed: ${i}`,{cause:r})}}}function lh(t,e,n){let r=dh(e,n).map(i=>({packageName:`@napi-rs/keyring-${i}`,bindingFile:`keyring.${i}.node`})),o;for(let i of r)try{let s=t.resolve(`${i.packageName}/package.json`);return t(nh(th(s),i.bindingFile))}catch(s){o=s}throw o instanceof Error?o:new Error(String(o))}function dh(t,e){if(t==="darwin"){if(e==="arm64")return["darwin-arm64"];if(e==="x64")return["darwin-x64"]}if(t==="win32"){if(e==="arm64")return["win32-arm64-msvc"];if(e==="x64")return["win32-x64-msvc"];if(e==="ia32")return["win32-ia32-msvc"]}if(t==="linux"){if(e==="arm64")return["linux-arm64-gnu","linux-arm64-musl"];if(e==="arm")return["linux-arm-gnueabihf"];if(e==="riscv64")return["linux-riscv64-gnu"];if(e==="x64")return["linux-x64-gnu","linux-x64-musl"]}return t==="freebsd"&&e==="x64"?["freebsd-x64"]:[]}function Ou(t){if(typeof t!="string")throw new Error(`Invalid MCP server name: ${JSON.stringify(t)}`);return`sha256-${Zm("sha256").update(t,"utf8").digest("hex")}`}function fh(t,e){let n=$u(t,e);if(typeof n!="object"||n===null||Array.isArray(n))throw new Error(`Stored bearer token record for ${t} has invalid shape`);let r=n;if(typeof r.token!="string"||typeof r.serverUrl!="string")throw new Error(`Stored bearer token record for ${t} has invalid shape`);return{token:r.token,serverUrl:r.serverUrl}}function $u(t,e){try{return JSON.parse(e)}catch{throw new Error(`Failed to parse stored bearer token record for ${t}`)}}function ph(t){if(typeof t!="object"||t===null)return!1;let e=t;return e.__piMcpAdapterBearerChunked===1&&typeof e.chunkCount=="number"&&Number.isInteger(e.chunkCount)&&e.chunkCount>0&&typeof e.chunkDigest=="string"&&/^[a-f0-9]{16}$/.test(e.chunkDigest)}function Iu(t,e){let n=$u(t,e);return ph(n)?n:void 0}function gh(t,e,n){return`${t}.chunk.${e.chunkDigest}.${n}`}function _u(t,e){return Array.from({length:e.chunkCount},(n,r)=>gh(t,e,r))}function mh(t,e,n){if(n)for(let r of _u(e,n))t.remove(r)}function Uu(t,e){let n=Ou(e),r;try{r=t.read(n)}catch(o){throw new Hn(`Failed to read bearer token for ${e} from the OS secure credential store`,"read",o)}if(r!==void 0)try{let o=Iu(e,r),i=o?_u(n,o).map(s=>{let a=t.read(s);if(a===void 0)throw new Error(`Missing bearer token chunk for ${e}`);return a}).join(""):r;return fh(e,i)}catch(o){throw new Hn(`Failed to read bearer token for ${e} from the OS secure credential store`,"read",o)}}function hh(t,e){let n=Ou(e);try{let r=t.read(n),o=r===void 0?void 0:Iu(e,r);mh(t,n,o),t.remove(n)}catch(r){throw new Hn(`Failed to remove bearer token for ${e} from the OS secure credential store`,"remove",r)}}function Du(t,e){let n=Uu(ws(),t);if(n)return n.serverUrl===e?n.token:void 0}function Nu(t){hh(ws(),t)}function Lu(t,e){try{let n=Uu(ws(),t);return n?n.serverUrl!==e?{status:"url-mismatch"}:{status:"present"}:{status:"missing"}}catch(n){if(!(n instanceof Hn))throw n;return{status:"unavailable",message:"Bearer token secure credential store unavailable. Configure or unlock the OS credential store and retry."}}}be();import{complete as yh}from"./vendor/pi-ai-compat.js";function Bu(t,e){t.setRequestHandler("sampling/createMessage",n=>vh(e,n))}async function vh(t,e){let n=e.params,r=t.getSignal();if(D(r),"task"in n&&n.task)throw new Error("MCP sampling tasks are not supported");if(n.includeContext&&n.includeContext!=="none")throw new Error("MCP sampling context inclusion is not supported");if(n.tools?.length)throw new Error("MCP sampling tool use is not supported");if(n.toolChoice)throw new Error("MCP sampling tool choice is not supported");if(n.stopSequences?.length)throw new Error("MCP sampling stop sequences are not supported");let o=n.messages.map(xh),{model:i,apiKey:s,headers:a}=await Ch(t,n.modelPreferences);D(r),await ju(t,"Approve MCP sampling request",Sh(t.serverName,`${i.provider}/${i.id}`,n.systemPrompt,o)),D(r);let c=await yh(i,{...n.systemPrompt!==void 0?{systemPrompt:n.systemPrompt}:{},messages:o},{...s!==void 0?{apiKey:s}:{},...a!==void 0?{headers:a}:{},maxTokens:n.maxTokens,...n.temperature!==void 0?{temperature:n.temperature}:{},...n.metadata!==void 0?{metadata:n.metadata}:{},...r?{signal:r}:{}}),u=Ah(c);return D(r),await ju(t,"Return MCP sampling response",wh(t.serverName,u)),u}function Sh(t,e,n,r){let o=[`${t} wants to sample ${r.length} message${r.length===1?"":"s"} with ${e}.`];n&&o.push(`System: ${Ve(n,400)}`);for(let[i,s]of r.entries())o.push(`${i+1}. ${s.role}: ${Ve(bh(s),400)}`);return o.join(`
|
|
87
87
|
|
|
88
88
|
`)}function wh(t,e){let n=e.content.type==="text"?e.content.text:`[${e.content.type} content]`;return`${t} will receive this response from ${e.model}:
|
|
89
89
|
|
|
@@ -495,7 +495,7 @@ data: ${JSON.stringify(T)}
|
|
|
495
495
|
|
|
496
496
|
`),o.add(O),P(O,$.headers["last-event-id"]?String($.headers["last-event-id"]):null),$.on("close",()=>{o.delete(O)});return}if(T==="GET"&&F.pathname==="/health"){if(!Zo(F,e,O))return;re(O,200,{ok:!0,result:{healthy:!0}});return}if(T==="GET"&&F.pathname==="/ui-app"){if(!Zo(F,n,O,"resource"))return;v();let j=fd(t.resource.meta.csp);O.writeHead(200,{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store","Content-Security-Policy":j}),O.end(t.resource.html);return}if(T==="GET"&&F.pathname==="/app-bridge.bundle.js"){let j=Yv.join(import.meta.dirname,"app-bridge.bundle.js");try{let Q=await Gv.readFile(j,"utf-8");O.writeHead(200,{"Content-Type":"application/javascript","Cache-Control":"public, max-age=31536000"}),O.end(Q)}catch{re(O,500,{ok:!1,error:"Bundle not found"})}return}if(T!=="POST"){re(O,404,{ok:!1,error:"Not found"});return}let Oe=await nS($,O);if(!Oe||!aS(Oe,e,O))return;let fe=Oe.params??{};if(v(),F.pathname==="/proxy/tools/call"){t.consentManager.ensureApproved(t.serverName);let j=fe;if(!j||typeof j.name!="string"||!j.name.trim()){re(O,400,{ok:!1,error:"Invalid tools/call params"});return}let Q=t.manager.getConnection(t.serverName);if(!Q||Q.status!=="connected"){re(O,503,{ok:!1,error:`Server "${t.serverName}" is not connected`});return}if(U(t.config?.mcpServers[t.serverName])||U(Q.definition)){re(O,503,{ok:!1,error:`Server "${t.serverName}" is disabled`});return}let Se=(Array.isArray(Q.tools)?Q.tools:[]).find(I=>I.name===j.name);if(!Se){re(O,403,{ok:!1,error:`MCP tool "${j.name}" is not callable by apps`});return}let Xe=Zt(Se._meta);if(!Us(Xe)){re(O,403,{ok:!1,error:`MCP tool "${j.name}" is not callable by apps`});return}let dt;try{dt=Sn(j.arguments,`tool "${j.name}" arguments`)}catch(I){re(O,400,{ok:!1,error:I instanceof Error?I.message:String(I)});return}let Re={name:j.name,arguments:dt},St={name:j.name,originalName:j.name,description:Se?.description??"",...Se?.inputSchema!==void 0?{inputSchema:Se.inputSchema}:{},...Xe!==void 0?{uiVisibility:Xe}:{}},st=new Map(t.state?.toolMetadata),pn=t.config?.mcpServers[t.serverName]??t.state?.config.mcpServers[t.serverName];st.set(t.serverName,[...Q.tools.map(I=>({name:I.name,originalName:I.name,description:I.description??""})),...pn?.exposeResources!==!1?(Q.resources??[]).map(I=>{let q=`read_${Ce(I.name)}`;return{name:q,originalName:q,description:I.description??`Read resource: ${I.uri}`}}):[]]);let wt=t.state?await Qn(t.state,t.serverName,St,Re.arguments,t.state.owner?.signal,"iframe",st):t.config&&Xn(t.config,t.serverName,St,st)?{ok:!1,reason:"approval_required_headless"}:{ok:!0};if(wt.ok===!1){let I=wt.reason==="denied",q=I?`The user declined approval to run MCP tool "${j.name}" on server "${t.serverName}".`:`MCP tool "${j.name}" on server "${t.serverName}" is approval-gated and requires an interactive session.`;re(O,200,{ok:!0,result:{content:[{type:"text",text:q}],details:{error:I?"approval_denied":"approval_required",server:t.serverName,tool:j.name}}});return}try{t.manager.touch(t.serverName),t.manager.incrementInFlight(t.serverName);let I=t.config?await ct({manager:t.manager,config:t.config,...t.onNeedsAuth?{onNeedsAuth:t.onNeedsAuth}:{}},t.serverName,q=>q.client.callTool(Re,t.manager.getRequestOptions?.(t.serverName))):await Q.client.callTool(Re,t.manager.getRequestOptions?.(t.serverName));re(O,200,{ok:!0,result:I})}finally{t.manager.decrementInFlight(t.serverName),t.manager.touch(t.serverName)}return}if(F.pathname==="/proxy/ui/consent"){let j=!!fe.approved;t.consentManager.registerDecision(t.serverName,j),re(O,200,{ok:!0,result:{approved:j}});return}if(F.pathname==="/proxy/ui/generated-tool-call-intent"){let j=typeof fe.tool=="string"?fe.tool:void 0;j&&w(j)?r.debug("Ignored generated app-only tool call intent",{tool:j}):await b({type:"intent",intent:"call_tool",params:{...j!==void 0?{tool:j}:{},...fe.arguments!==void 0?{arguments:fe.arguments}:{},...fe.isError!==void 0?{isError:fe.isError}:{}}}),re(O,200,{ok:!0,result:{}});return}if(F.pathname==="/proxy/ui/message"){await b(fe),re(O,200,{ok:!0,result:{}});return}if(F.pathname==="/proxy/ui/context"){let j=fe.content,Q=fe.structuredContent;if(j!==void 0&&(!Array.isArray(j)||j.some(Xe=>!Xv.safeParse(Xe).success))||Q!==void 0&&(!Q||typeof Q!="object"||Array.isArray(Q))){re(O,400,{ok:!1,error:"Invalid update-model-context params"});return}let ne={...j!==void 0?{content:j}:{},...Q!==void 0?{structuredContent:Q}:{}},Se=Jr(ne);if(Se)for(p.contexts.push(Se);p.contexts.length>tS;)p.contexts.shift();r.debug("UI context update",{hasContent:!!ne.content,hasUpdate:!!Se}),await t.onContextUpdate?.(ne),re(O,200,{ok:!0,result:{}});return}if(F.pathname==="/proxy/ui/open-link"){let j=fe;if(!j?.url||typeof j.url!="string"){re(O,400,{ok:!1,error:"Invalid open-link params"});return}let Q={};try{new URL(j.url)}catch{Q={isError:!0}}re(O,200,{ok:!0,result:Q});return}if(F.pathname==="/proxy/ui/download-file"){re(O,200,{ok:!0,result:{isError:!0}});return}if(F.pathname==="/proxy/ui/request-display-mode"){let Q=fe?.mode,ne=g.availableDisplayModes??["inline"];Q&&ne.includes(Q)&&(c=Q),g.displayMode=c,M("host-context",{displayMode:c}),re(O,200,{ok:!0,result:{mode:c}});return}if(F.pathname==="/proxy/ui/heartbeat"){re(O,200,{ok:!0,result:{}});return}if(F.pathname==="/proxy/ui/complete"){let j=typeof fe.reason=="string"?fe.reason:"done";L(j),re(O,200,{ok:!0,result:{}}),setTimeout(()=>{try{H.close()}catch{}C()},20).unref();return}re(O,404,{ok:!1,error:"Not found"})}catch(T){if(T instanceof We){let Oe=`Server "${t.serverName}" requires OAuth authentication. Run mcp({ action: "auth-start", server: "${t.serverName}" }) to get a browser URL, or /mcp-auth ${t.serverName} in an interactive local session.`,fe=T.authMessage??(t.config?wn(t.config,t.serverName,Oe):Oe);re(O,401,{ok:!1,error:fe});return}let G=Ec(T,{server:t.serverName,tool:t.toolName}),F=/approval required|denied/i.test(G.message)?403:500;F===500&&r.error("Request handler error",T instanceof Error?T:void 0),re(O,F,{ok:!1,error:G.message})}});return t.initialResultPromise&&t.initialResultPromise.then($=>M("tool-result",$),$=>{let O=$ instanceof Error?$.message:String($);M("tool-cancelled",{reason:O})}),a=setInterval(()=>{if(!i&&!(Date.now()-s<=Zv)){L("stale");try{H.close()}catch{}C()}},eS),a.unref(),new Promise(($,O)=>{let T=oS(t.port),G=0,F=()=>{H.once("error",Oe),H.listen(T[G],"127.0.0.1",fe)},Oe=j=>{if(H.off("listening",fe),j.code==="EADDRINUSE"&&G<T.length-1){G+=1,F();return}r.error("Failed to start server",j);let Q=T[G];O(new gr(j.message,{...Q!==void 0?{port:Q}:{},cause:j}))},fe=()=>{H.off("error",Oe);let j=H.address();if(!j||typeof j=="string"){let ne=new gr("invalid address");r.error("Invalid server address",ne),O(ne);return}r.debug("Server started",{port:j.port}),iS(j.port);let Q={url:`http://localhost:${j.port}/?session=${e}`,port:j.port,sessionToken:e,serverName:t.serverName,toolName:t.toolName,close:ne=>{L(ne??"closed");try{H.close()}catch{}C()},sendToolInput:ne=>{M("tool-input",{arguments:ne})},sendToolResult:ne=>{M("tool-result",ne)},sendResultPatch:ne=>{M("result-patch",ne)},sendToolCancelled:ne=>{M("tool-cancelled",{reason:ne})},sendHostContext:ne=>{Object.assign(g,ne),M("host-context",ne)},getSessionMessages:()=>({...p}),getStreamSummary:()=>f?{...f,phases:[...f.phases]}:void 0};$(Q)};F()})}async function nS(t,e){try{let n=await rS(t);return!n||typeof n!="object"?(re(e,400,{ok:!1,error:"Invalid request body"}),null):n}catch(n){return re(e,400,{ok:!1,error:n instanceof Error?n.message:"Invalid body"}),null}}function rS(t){return new Promise((e,n)=>{let r=0,o=[];t.on("data",i=>{if(r+=i.length,r>Qv){t.destroy(),n(new Error("Request body too large"));return}o.push(i)}),t.on("end",()=>{try{e(JSON.parse(Buffer.concat(o).toString("utf-8")))}catch(i){n(i)}}),t.on("error",n)})}function oS(t){if(t!==void 0)return[t];let e=[],n=ca-Zn+1;for(let r=0;r<n;r+=1){let o=Zn+(gd-Zn+r)%n;e.push(o)}return e.push(0),e}function iS(t){t<Zn||t>ca||(gd=t>=ca?Zn:t+1)}function sS(t){return t==="localhost"||t==="127.0.0.1"||t==="[::1]"}function Zo(t,e,n,r="session"){return t.searchParams.get(r)!==e?(re(n,403,{ok:!1,error:"Invalid session"}),!1):!0}function aS(t,e,n){return t.token!==e?(re(n,403,{ok:!1,error:"Invalid session"}),!1):!0}function re(t,e,n){t.writeHead(e,{"Content-Type":"application/json; charset=utf-8","Cache-Control":"no-store"}),t.end(JSON.stringify(n))}function cS(t,e,n){t.writeHead(e,{"Content-Type":"text/plain; charset=utf-8","Cache-Control":"no-store"}),t.end(n)}import{existsSync as ua}from"node:fs";import{execFileSync as uS}from"node:child_process";import{join as la,dirname as hd}from"node:path";import{platform as lS}from"node:os";import{createRequire as dS}from"node:module";var _r=null,ei=null;function yd(){return _r!==null?_r:lS()!=="darwin"?(_r=!1,!1):(ei=fS(),_r=ei!==null,_r)}function fS(){if(process.env.GLIMPSE_BINARY&&ua(process.env.GLIMPSE_BINARY))return process.env.GLIMPSE_BINARY;try{let e=dS(import.meta.url).resolve("glimpseui"),n=la(hd(e),"glimpse");if(ua(n))return n}catch{}try{let t=uS("npm",["root","-g"],{encoding:"utf-8"}).trim(),e=la(t,"glimpseui","src","glimpse");if(ua(e))return e}catch{}return null}async function vd(t,e){let r=await import(ei?la(hd(ei),"glimpse.mjs"):"glimpseui"),o=!0,i=r.open(t,{width:e.width??900,height:e.height??700,title:e.title});return i.on("closed",()=>{o&&(o=!1,e.onClosed())}),{close:()=>{o&&(o=!1,i.close())}}}var sn=null;function ni(t){return t?t.windowOpen?{message:t.reused?"Updated the open UI.":"Interactive UI is open. I'll respond to your prompts and intents as you interact with it.",uiOpen:!0,uiViewer:t.viewer,uiUrl:t.url}:{message:`${t.reused?"Updated the suppressed MCP UI session.":"MCP UI window was suppressed."} Open manually: ${t.url}`,uiOpen:!1,uiViewer:t.viewer,uiUrl:t.url}:{message:"Interactive UI was unavailable; returning the tool result inline.",uiOpen:!1}}var hS=10;function an(t,e,n){if(!e)return t;let r=t.structuredContent&&typeof t.structuredContent=="object"&&!Array.isArray(t.structuredContent)?{...t.structuredContent}:{},o=r[or],i=o&&typeof o=="object"&&!Array.isArray(o)?{...o}:{frameType:"final",phase:"settled",status:t.isError?"error":"ok"};return r[or]={...i,streamId:e,sequence:n},{...t,structuredContent:r}}async function Sd(t,e,n){D(n);try{return await t.openBrowser(e),D(n),null}catch(r){if(ie(r,n))throw r;let o=r instanceof Error?r.message:String(r);return t.owner?.isActive()===!1?null:(t.ui?.notify(`MCP UI browser open failed: ${o}`,"warning"),o)}}function yS(){return!!(process.env.SSH_CONNECTION||process.env.SSH_TTY)}function vS(){return new Promise(t=>{pS("who",{encoding:"utf8",timeout:2e3},(e,n)=>{if(e){t(!1);return}t(/\(.+\)\s*$/m.test(n))})})}function SS(){return new Promise(t=>{let e=gS.connect({host:"127.0.0.1",port:24543}),n=r=>{e.destroy(),t(r)};e.setTimeout(300),e.once("connect",()=>n(!0)),e.once("timeout",()=>n(!1)),e.once("error",()=>n(!1))})}function wS(t){let e=[t.openError!==null?"Couldn't open MCP UI here. Open it from your own device:":t.openedOnHost?"MCP UI opened on this host. If you're controlling this session remotely, open it from your own device:":"This looks like a remote session - if no MCP UI appeared, open it from your own device:",` ${t.url}`];return t.openError!==null&&e.push(`Browser launch failed: ${t.openError}`),t.moshi&&e.push("Moshi: tap the preview button in the terminal title bar and pick this MCP UI server."),e.push(`SSH: run \`ssh -L ${t.port}:127.0.0.1:${t.port} <this-host>\` on your local machine, then open the URL above.`,"mosh can't forward ports - run that ssh command in a separate terminal."),e.join(`
|
|
497
497
|
`)}async function ri(t,e){let n=X.child({component:"UiSession",server:e.serverName,tool:e.toolName}),r=te(t.owner?.signal,e.signal)??new AbortController().signal;try{if(D(r),t.uiServer&&t.uiServer.serverName===e.serverName&&t.uiServer.toolName===e.toolName){let v=t.uiServer,m=e.streamMode,S=m?ti():void 0,R=m?ti():void 0,h=!0,M=0,P=()=>{R&&t.manager.removeUiStreamListener(R)};return v.sendToolInput(e.toolArgs),R&&t.manager.registerUiStreamListener(R,(C,E)=>{!h||t.uiServer!==v||C===e.serverName&&(M+=1,v.sendResultPatch(an(E.result,S,M)))}),{serverName:e.serverName,toolName:e.toolName,reused:!0,...S!==void 0?{streamId:S}:{},...R!==void 0?{streamToken:R}:{},...m!==void 0?{streamMode:m}:{},...R?{requestMeta:{[zr]:R}}:{},url:v.url,viewer:v.viewer??"browser",windowOpen:v.windowOpen??!0,isActive:()=>h&&t.uiServer===v,sendToolResult:C=>{!h||t.uiServer!==v||(M+=1,v.sendToolResult(an(C,S,M)))},sendResultPatch:C=>{!h||t.uiServer!==v||(M+=1,v.sendResultPatch(an(C,S,M)))},sendToolCancelled:C=>{!h||t.uiServer!==v||(M+=1,v.sendToolResult(an({isError:!0,content:[{type:"text",text:C}]},S,M)))},close:()=>{h=!1,P()}}}let o=await t.uiResourceHandler.readUiResource(e.serverName,e.uiResourceUri,{config:t.config,signal:r,onNeedsAuth:e.onNeedsAuth});D(r),t.uiServer&&(t.uiServer.close("replaced"),t.uiServer=null),sn&&(sn.close(),sn=null);let i=e.streamMode,s=i?ti():void 0,a=i?ti():void 0,c=i&&s?{[gi]:{mode:i,streamId:s,intermediateResultPatches:i==="stream-first",partialInput:!1}}:void 0,u=!0,d=0,l,f=()=>{a&&t.manager.removeUiStreamListener(a)};if(l=await md({serverName:e.serverName,toolName:e.toolName,toolArgs:i==="stream-first"?{}:e.toolArgs,resource:o,manager:t.manager,config:t.config,state:t,...e.onNeedsAuth?{onNeedsAuth:e.onNeedsAuth}:{},consentManager:t.consentManager,...c!==void 0?{hostContext:c}:{},onMessage:v=>{let m=Kr(v);if(m)t.sendMessage&&(t.sendMessage({customType:"mcp-ui-prompt",content:[{type:"text",text:`User sent prompt from ${e.serverName} UI: "${m}"`}],display:`\u{1F4AC} UI Prompt: ${m}`,details:{server:e.serverName,tool:e.toolName,prompt:m}},{triggerTurn:!0}),n.debug("Triggered agent turn for UI prompt",{prompt:m.slice(0,50)}));else if(v.type==="intent"||v.intent){let S=v.intent??"",R=v.params;if(S&&t.sendMessage){let h=R?` ${JSON.stringify(R)}`:"";t.sendMessage({customType:"mcp-ui-intent",content:[{type:"text",text:`User triggered intent from ${e.serverName} UI: ${S}${h}`}],display:`\u{1F3AF} UI Intent: ${S}`,details:{server:e.serverName,tool:e.toolName,intent:S,params:R}},{triggerTurn:!0}),n.debug("Triggered agent turn for UI intent",{intent:S})}}else if(v.type==="notify"||v.message){let S=v.message??"";S&&t.ui&&t.ui.notify(`[${e.serverName}] ${S}`,"info")}},onContextUpdate:v=>{let m=Jr(v);n.debug("Model context update from UI",{hasContent:!!v.content,hasStructured:!!v.structuredContent,hasUpdate:!!m}),m&&t.sendMessage&&t.sendMessage({customType:"mcp-ui-context",content:[{type:"text",text:`User submitted model context from ${e.serverName} UI:
|
|
498
|
-
${m.summary}`}],display:"UI Context submitted",details:{server:e.serverName,tool:e.toolName,context:m}},{triggerTurn:!0})},onComplete:v=>{if(u=!1,f(),t.uiServer===l){let m=l.getSessionMessages(),S=l.getStreamSummary();if(m.prompts.length>0||m.intents.length>0||m.notifications.length>0||m.contexts.length>0||!!S){for(t.completedUiSessions.push({serverName:l.serverName,toolName:l.toolName,completedAt:new Date,reason:v,messages:m,...S!==void 0?{stream:S}:{}});t.completedUiSessions.length>hS;)t.completedUiSessions.shift();n.debug("Session completed",{reason:v,prompts:m.prompts.length,intents:m.intents.length,notifications:m.notifications.length,contexts:m.contexts.length,streamFrames:S?.frames??0})}t.uiServer=null,sn&&(sn.close(),sn=null)}}}),t.owner?.isActive()===!1||r.aborted)throw l.close("runtime_owner_stopped"),D(r),new Error("MCP UI session became stale before registration");a&&t.manager.registerUiStreamListener(a,(v,m)=>{!u||t.uiServer!==l||v===e.serverName&&(d+=1,l.sendResultPatch(an(m.result,s,d)))}),t.uiServer=l;let p=process.env.MCP_UI_VIEWER?.toLowerCase(),g=p==="none"||p==="off"||p==="disabled",y="browser",w=!0,b=yS();if(g)y="suppressed",w=!1,t.ui?.notify(`MCP UI window suppressed (MCP_UI_VIEWER=${p}). Open manually: ${l.url}`,"info"),n.info("Suppressing MCP UI window (MCP_UI_VIEWER="+p+")",{url:l.url});else{let v=b||await vS(),m=async(h,M=!1)=>{t.ui?.notify(wS({url:l.url,port:l.port,moshi:await SS(),openError:h,openedOnHost:M}),h===null?"info":"warning")},S=!b&&yd();if(!b&&(p==="glimpse"||p!=="browser"&&S))try{let h=`<!DOCTYPE html><html><head><meta charset="utf-8"><style>body{margin:0;padding:0;width:100vw;height:100vh;overflow:hidden}iframe{width:100%;height:100%;border:none}</style></head><body><iframe src="${l.url}"></iframe></body></html>`,M=await vd(h,{title:`MCP \xB7 ${e.serverName} \xB7 ${e.toolName}`,width:1e3,height:800,onClosed:()=>{u&&l.close("glimpse-closed")}});if(t.owner?.isActive()===!1||r.aborted)throw M.close(),D(r),new Error("MCP Glimpse window became stale before registration");sn=M,y="glimpse",v&&await m(null,!0)}catch(h){n.debug("Glimpse unavailable, using browser",{error:h instanceof Error?h.message:String(h)});let M=await Sd(t,l.url,r);(M!==null||v)&&await m(M),y="browser"}else{let h=await Sd(t,l.url,r);(h!==null||v)&&await m(h)}}return D(r),l.viewer=y,l.windowOpen=w,{serverName:e.serverName,toolName:e.toolName,reused:!1,...s!==void 0?{streamId:s}:{},...a!==void 0?{streamToken:a}:{},...i!==void 0?{streamMode:i}:{},...a?{requestMeta:{[zr]:a}}:{},url:l.url,viewer:y,windowOpen:w,isActive:()=>u&&t.uiServer===l,sendToolResult:v=>{!u||t.uiServer!==l||(d+=1,l.sendToolResult(an(v,s,d)))},sendResultPatch:v=>{!u||t.uiServer!==l||(d+=1,l.sendResultPatch(an(v,s,d)))},sendToolCancelled:v=>{!u||t.uiServer!==l||l.sendToolCancelled(v)},close:v=>{u=!1,f(),l.close(v)}}}catch(o){if(o instanceof mS||ie(o,r))throw o;let i=o instanceof Error?o.message:String(o);return n.error("Failed to start UI session",o instanceof Error?o:void 0),t.ui?.notify(`MCP UI unavailable for ${e.toolName} (${e.serverName}): ${i}`,"warning"),null}}ue();en();It();be();import{Check as CS,Errors as xS}from"typebox/value";var wd=new Set(["read","bash","edit","write","grep","find","ls","mcp"]),MS=75;function xd(t,e){if(!t||typeof t!="object"||Array.isArray(t))return e;let n=t;if(n.type!=="object")return e;let r=e&&typeof e=="object"&&!Array.isArray(e)?e:null,o=n.properties,i;if(r&&o&&typeof o=="object"&&!Array.isArray(o))for(let[a,c]of Object.entries(o)){if(!Object.hasOwn(r,a)||typeof r[a]!="string"||!c||typeof c!="object"||Array.isArray(c))continue;let u=c.type;if(!(u!=="object"&&u!=="array"))try{let d=JSON.parse(r[a]);(u==="array"?Array.isArray(d):d!==null&&typeof d=="object"&&!Array.isArray(d))&&(i??={...r},i[a]=d)}catch{}}let s=i??e;if(!CS(t,s)){let a=xS(t,s),c=a.slice(0,8).map(u=>({instancePath:u.instancePath||"/",keyword:u.keyword,message:u.message}));throw new TypeError(`MCP direct tool arguments do not match the advertised input schema: ${JSON.stringify({issues:c,total:a.length,truncated:a.length>c.length})}`)}return s}function oi(t,e,n=`MCP server "${e}" requires OAuth authentication. Run mcp({ action: "auth-start", server: "${e}" }) to get a browser URL, or /mcp-auth ${e} in an interactive local session.`){return wn(t.config,e,n)}function bd(t,e,n){return t.config.settings?.authRequiredMessage?`OAuth authentication failed for "${e}": ${n}. ${oi(t,e)}`:`OAuth authentication failed for "${e}": ${n}. Run mcp({ action: "auth-start", server: "${e}" }) to get a browser URL, or /mcp-auth ${e} in an interactive local session.`}async function Cd(t,e,n){if(t.config.settings?.autoAuth!==!0)return{status:"skipped"};let r=t.config.mcpServers[e];if(!r||U(r)||!Ue(r))return{status:"skipped"};let o;try{o=He(r)}catch(s){let a=s instanceof Error?s.message:String(s);return{status:"failed",message:bd(t,e,a)}}if(!o)return{status:"skipped"};let i=r.oauth?r.oauth.grantType??"authorization_code":"authorization_code";if(!t.ui&&i!=="client_credentials")return{status:"failed",message:oi(t,e,`MCP server "${e}" requires OAuth authentication. Run mcp({ action: "auth-start", server: "${e}" }) to get a browser URL, or /mcp-auth ${e} in an interactive local session.`)};try{return t.authStorageOptions?await mt(e,o,r,n?{authStorageOptions:t.authStorageOptions,signal:n,runtime:t.oauthRuntime}:{authStorageOptions:t.authStorageOptions,runtime:t.oauthRuntime}):await mt(e,o,r,{...n?{signal:n}:{},runtime:t.oauthRuntime}),{status:"success"}}catch(s){if(ie(s,n))throw s;let a=s instanceof Error?s.message:String(s);return{status:"failed",message:bd(t,e,a)}}}function Md(t,e,n,r,o=new Set,i){let s=[];if(!e)return s;let a=new Set,c=r?tn(r):null,u=t.settings?.directTools;for(let[l,f]of Object.entries(t.mcpServers)){if(U(f))continue;let p=e.servers[l];if(!p||!$e(p,f))continue;let g=!1;if(c?c.servers.has(l)?g=!0:c.tools.has(l)&&(g=[...c.tools.get(l)]):f.directTools!==void 0?g=f.directTools:u&&(g=u),!g)continue;let y=pe(f,n),b=Array.isArray(f.includeTools)&&f.includeTools.length>0||Array.isArray(f.excludeTools)&&f.excludeTools.length>0?(()=>{let v=new Set;for(let[m,S]of Object.entries(t.mcpServers)){let R=e.servers[m];if(!R||!$e(R,S)||U(S))continue;let h=pe(S,n);for(let M of R.tools??[])if(ke(M.uiVisibility))for(let P of ce(M.name,m,h,!1))v.add(P);if(S.exposeResources!==!1)for(let M of R.resources??[]){let P=`read_${Ce(M.name)}`;for(let C of ce(P,m,h,!1))v.add(C)}}return mn(v)})():void 0;for(let v of p.tools??[]){if(!ke(v.uiVisibility)||g!==!0&&!g.includes(v.name)||!Ee(v.name,l,y,f.includeTools,f.excludeTools,b))continue;let m=se(v.name,l,y);if(wd.has(m)){console.warn(`MCP: skipping direct tool "${m}" (collides with builtin)`);continue}if(a.has(m)){console.warn(`MCP: skipping duplicate direct tool "${m}" from "${l}"`);continue}a.add(m),s.push({serverName:l,originalName:v.name,prefixedName:m,description:v.description??"",...v.inputSchema!==void 0?{inputSchema:v.inputSchema}:{},...v.uiResourceUri!==void 0?{uiResourceUri:v.uiResourceUri}:{},...v.uiStreamMode!==void 0?{uiStreamMode:v.uiStreamMode}:{}})}if(f.exposeResources!==!1)for(let v of p.resources??[]){let m=`read_${Ce(v.name)}`;if(g!==!0&&!g.includes(m)||!Ee(m,l,y,f.includeTools,f.excludeTools,b))continue;let S=se(m,l,y);if(wd.has(S)){console.warn(`MCP: skipping direct resource tool "${S}" (collides with builtin)`);continue}if(a.has(S)){console.warn(`MCP: skipping duplicate direct resource tool "${S}" from "${l}"`);continue}a.add(S),s.push({serverName:l,originalName:m,prefixedName:S,description:v.description??`Read resource: ${v.uri}`,resourceUri:v.uri})}}for(let l of s)i?.add(l.prefixedName);let d=o.size===0?s:s.filter(l=>!o.has(l.serverName));return t.settings?.warnOnLargeDirectTools!==!1&&d.length>=MS&&console.warn(`MCP: ${d.length} direct tools resolved. Each direct tool adds prompt context; README guidance recommends targeted sets of 5-20 tools and using the proxy or an explicit string[] when 75+ direct tools would be registered. Set settings.warnOnLargeDirectTools to false to hide this advisory.`),d}function Td(t){let e=`MCP gateway \u2014 server status, tool search/describe, auth, and single MCP tool calls. When one request needs several MCP calls with logic between them, use mcpScript. Non-MCP Pi tools should be called directly, not through mcp.
|
|
498
|
+
${m.summary}`}],display:"UI Context submitted",details:{server:e.serverName,tool:e.toolName,context:m}},{triggerTurn:!0})},onComplete:v=>{if(u=!1,f(),t.uiServer===l){let m=l.getSessionMessages(),S=l.getStreamSummary();if(m.prompts.length>0||m.intents.length>0||m.notifications.length>0||m.contexts.length>0||!!S){for(t.completedUiSessions.push({serverName:l.serverName,toolName:l.toolName,completedAt:new Date,reason:v,messages:m,...S!==void 0?{stream:S}:{}});t.completedUiSessions.length>hS;)t.completedUiSessions.shift();n.debug("Session completed",{reason:v,prompts:m.prompts.length,intents:m.intents.length,notifications:m.notifications.length,contexts:m.contexts.length,streamFrames:S?.frames??0})}t.uiServer=null,sn&&(sn.close(),sn=null)}}}),t.owner?.isActive()===!1||r.aborted)throw l.close("runtime_owner_stopped"),D(r),new Error("MCP UI session became stale before registration");a&&t.manager.registerUiStreamListener(a,(v,m)=>{!u||t.uiServer!==l||v===e.serverName&&(d+=1,l.sendResultPatch(an(m.result,s,d)))}),t.uiServer=l;let p=process.env.MCP_UI_VIEWER?.toLowerCase(),g=p==="none"||p==="off"||p==="disabled",y="browser",w=!0,b=yS();if(g)y="suppressed",w=!1,t.ui?.notify(`MCP UI window suppressed (MCP_UI_VIEWER=${p}). Open manually: ${l.url}`,"info"),n.info("Suppressing MCP UI window (MCP_UI_VIEWER="+p+")",{url:l.url});else{let v=b||await vS(),m=async(h,M=!1)=>{t.ui?.notify(wS({url:l.url,port:l.port,moshi:await SS(),openError:h,openedOnHost:M}),h===null?"info":"warning")},S=!b&&yd();if(!b&&(p==="glimpse"||p!=="browser"&&S))try{let h=`<!DOCTYPE html><html><head><meta charset="utf-8"><style>body{margin:0;padding:0;width:100vw;height:100vh;overflow:hidden}iframe{width:100%;height:100%;border:none}</style></head><body><iframe src="${l.url}"></iframe></body></html>`,M=await vd(h,{title:`MCP \xB7 ${e.serverName} \xB7 ${e.toolName}`,width:1e3,height:800,onClosed:()=>{u&&l.close("glimpse-closed")}});if(t.owner?.isActive()===!1||r.aborted)throw M.close(),D(r),new Error("MCP Glimpse window became stale before registration");sn=M,y="glimpse",v&&await m(null,!0)}catch(h){n.debug("Glimpse unavailable, using browser",{error:h instanceof Error?h.message:String(h)});let M=await Sd(t,l.url,r);(M!==null||v)&&await m(M),y="browser"}else{let h=await Sd(t,l.url,r);(h!==null||v)&&await m(h)}}return D(r),l.viewer=y,l.windowOpen=w,{serverName:e.serverName,toolName:e.toolName,reused:!1,...s!==void 0?{streamId:s}:{},...a!==void 0?{streamToken:a}:{},...i!==void 0?{streamMode:i}:{},...a?{requestMeta:{[zr]:a}}:{},url:l.url,viewer:y,windowOpen:w,isActive:()=>u&&t.uiServer===l,sendToolResult:v=>{!u||t.uiServer!==l||(d+=1,l.sendToolResult(an(v,s,d)))},sendResultPatch:v=>{!u||t.uiServer!==l||(d+=1,l.sendResultPatch(an(v,s,d)))},sendToolCancelled:v=>{!u||t.uiServer!==l||l.sendToolCancelled(v)},close:v=>{u=!1,f(),l.close(v)}}}catch(o){if(o instanceof mS||ie(o,r))throw o;let i=o instanceof Error?o.message:String(o);return n.error("Failed to start UI session",o instanceof Error?o:void 0),t.ui?.notify(`MCP UI unavailable for ${e.toolName} (${e.serverName}): ${i}`,"warning"),null}}ue();en();It();be();import{Check as CS,Errors as xS}from"./vendor/typebox/value.js";var wd=new Set(["read","bash","edit","write","grep","find","ls","mcp"]),MS=75;function xd(t,e){if(!t||typeof t!="object"||Array.isArray(t))return e;let n=t;if(n.type!=="object")return e;let r=e&&typeof e=="object"&&!Array.isArray(e)?e:null,o=n.properties,i;if(r&&o&&typeof o=="object"&&!Array.isArray(o))for(let[a,c]of Object.entries(o)){if(!Object.hasOwn(r,a)||typeof r[a]!="string"||!c||typeof c!="object"||Array.isArray(c))continue;let u=c.type;if(!(u!=="object"&&u!=="array"))try{let d=JSON.parse(r[a]);(u==="array"?Array.isArray(d):d!==null&&typeof d=="object"&&!Array.isArray(d))&&(i??={...r},i[a]=d)}catch{}}let s=i??e;if(!CS(t,s)){let a=xS(t,s),c=a.slice(0,8).map(u=>({instancePath:u.instancePath||"/",keyword:u.keyword,message:u.message}));throw new TypeError(`MCP direct tool arguments do not match the advertised input schema: ${JSON.stringify({issues:c,total:a.length,truncated:a.length>c.length})}`)}return s}function oi(t,e,n=`MCP server "${e}" requires OAuth authentication. Run mcp({ action: "auth-start", server: "${e}" }) to get a browser URL, or /mcp-auth ${e} in an interactive local session.`){return wn(t.config,e,n)}function bd(t,e,n){return t.config.settings?.authRequiredMessage?`OAuth authentication failed for "${e}": ${n}. ${oi(t,e)}`:`OAuth authentication failed for "${e}": ${n}. Run mcp({ action: "auth-start", server: "${e}" }) to get a browser URL, or /mcp-auth ${e} in an interactive local session.`}async function Cd(t,e,n){if(t.config.settings?.autoAuth!==!0)return{status:"skipped"};let r=t.config.mcpServers[e];if(!r||U(r)||!Ue(r))return{status:"skipped"};let o;try{o=He(r)}catch(s){let a=s instanceof Error?s.message:String(s);return{status:"failed",message:bd(t,e,a)}}if(!o)return{status:"skipped"};let i=r.oauth?r.oauth.grantType??"authorization_code":"authorization_code";if(!t.ui&&i!=="client_credentials")return{status:"failed",message:oi(t,e,`MCP server "${e}" requires OAuth authentication. Run mcp({ action: "auth-start", server: "${e}" }) to get a browser URL, or /mcp-auth ${e} in an interactive local session.`)};try{return t.authStorageOptions?await mt(e,o,r,n?{authStorageOptions:t.authStorageOptions,signal:n,runtime:t.oauthRuntime}:{authStorageOptions:t.authStorageOptions,runtime:t.oauthRuntime}):await mt(e,o,r,{...n?{signal:n}:{},runtime:t.oauthRuntime}),{status:"success"}}catch(s){if(ie(s,n))throw s;let a=s instanceof Error?s.message:String(s);return{status:"failed",message:bd(t,e,a)}}}function Md(t,e,n,r,o=new Set,i){let s=[];if(!e)return s;let a=new Set,c=r?tn(r):null,u=t.settings?.directTools;for(let[l,f]of Object.entries(t.mcpServers)){if(U(f))continue;let p=e.servers[l];if(!p||!$e(p,f))continue;let g=!1;if(c?c.servers.has(l)?g=!0:c.tools.has(l)&&(g=[...c.tools.get(l)]):f.directTools!==void 0?g=f.directTools:u&&(g=u),!g)continue;let y=pe(f,n),b=Array.isArray(f.includeTools)&&f.includeTools.length>0||Array.isArray(f.excludeTools)&&f.excludeTools.length>0?(()=>{let v=new Set;for(let[m,S]of Object.entries(t.mcpServers)){let R=e.servers[m];if(!R||!$e(R,S)||U(S))continue;let h=pe(S,n);for(let M of R.tools??[])if(ke(M.uiVisibility))for(let P of ce(M.name,m,h,!1))v.add(P);if(S.exposeResources!==!1)for(let M of R.resources??[]){let P=`read_${Ce(M.name)}`;for(let C of ce(P,m,h,!1))v.add(C)}}return mn(v)})():void 0;for(let v of p.tools??[]){if(!ke(v.uiVisibility)||g!==!0&&!g.includes(v.name)||!Ee(v.name,l,y,f.includeTools,f.excludeTools,b))continue;let m=se(v.name,l,y);if(wd.has(m)){console.warn(`MCP: skipping direct tool "${m}" (collides with builtin)`);continue}if(a.has(m)){console.warn(`MCP: skipping duplicate direct tool "${m}" from "${l}"`);continue}a.add(m),s.push({serverName:l,originalName:v.name,prefixedName:m,description:v.description??"",...v.inputSchema!==void 0?{inputSchema:v.inputSchema}:{},...v.uiResourceUri!==void 0?{uiResourceUri:v.uiResourceUri}:{},...v.uiStreamMode!==void 0?{uiStreamMode:v.uiStreamMode}:{}})}if(f.exposeResources!==!1)for(let v of p.resources??[]){let m=`read_${Ce(v.name)}`;if(g!==!0&&!g.includes(m)||!Ee(m,l,y,f.includeTools,f.excludeTools,b))continue;let S=se(m,l,y);if(wd.has(S)){console.warn(`MCP: skipping direct resource tool "${S}" (collides with builtin)`);continue}if(a.has(S)){console.warn(`MCP: skipping duplicate direct resource tool "${S}" from "${l}"`);continue}a.add(S),s.push({serverName:l,originalName:m,prefixedName:S,description:v.description??`Read resource: ${v.uri}`,resourceUri:v.uri})}}for(let l of s)i?.add(l.prefixedName);let d=o.size===0?s:s.filter(l=>!o.has(l.serverName));return t.settings?.warnOnLargeDirectTools!==!1&&d.length>=MS&&console.warn(`MCP: ${d.length} direct tools resolved. Each direct tool adds prompt context; README guidance recommends targeted sets of 5-20 tools and using the proxy or an explicit string[] when 75+ direct tools would be registered. Set settings.warnOnLargeDirectTools to false to hide this advisory.`),d}function Td(t){let e=`MCP gateway \u2014 server status, tool search/describe, auth, and single MCP tool calls. When one request needs several MCP calls with logic between them, use mcpScript. Non-MCP Pi tools should be called directly, not through mcp.
|
|
499
499
|
`,n=Object.keys(t.mcpServers).filter(o=>!U(t.mcpServers[o]));n.length>0&&(e+=`
|
|
500
500
|
Servers: ${n.join(", ")}
|
|
501
501
|
`);let r=Object.entries(t.mcpServers).filter(([,o])=>U(o)).map(([o])=>o);return r.length>0&&(e+=`
|
|
@@ -599,4 +599,4 @@ ${i}`,0,0)}text;expanded;maxCollapsedLines;preTruncated;fullText;footerText;coll
|
|
|
599
599
|
`):[`[image: ${t.mimeType}]`]}function iw(t,e,n){if(t.length===0)return{lines:["(empty result)"],truncated:!1};let r=[],o=n,i=!1,s=a=>{if(r.length===0){let c=Math.min(a.length,o);if(a.slice(0,c).trim()==="")return a.length>=o?(i=!0,o=0,!1):(o-=a.length+1,!0)}return r.length>=e||o<=0?(i=!0,!1):a.length>o?(r.push(a.slice(0,o)),i=!0,o=0,!1):(r.push(a),o-=a.length+1,!0)};for(let a of t){if(a.type!=="text"){if(!s(`[image: ${a.mimeType}]`))break;continue}let c=0;for(;c<=a.text.length;){let u=a.text.indexOf(`
|
|
600
600
|
`,c),d=u===-1?a.text.slice(c):a.text.slice(c,u);if(!s(d)||u===-1)break;c=u+1}if(i)break}return r.length===0&&r.push(i?"(leading blank output omitted)":""),i&&r.length>=e&&r.push("\u2026"),{lines:r,truncated:i}}function Kd(t){if(t?.mode!=="call")return null;let e=typeof t.server=="string"?t.server:typeof t.hintServer=="string"?t.hintServer:null;return e?typeof t.tool=="string"?`MCP ${e}/${t.tool}`:typeof t.resourceUri=="string"?`MCP ${e} resource ${t.resourceUri}`:typeof t.requestedTool=="string"?`MCP ${e}/${t.requestedTool}`:null:null}function Jd(t,e,n=Gd,r=XS){if(!e)return iw(t.content,n,r);let o=t.content.flatMap(ow);return{lines:o.length>0?o:["(empty result)"],truncated:!1}}function sw(t,e,n,r,o=fn()){let i=n??Wd;if(e.isPartial)return new jr(i.fg("warning","Running MCP tool..."),0,0);let s=!!t.details.error,a=e.expanded||r?.isError===!0||s;if(!a&&o.resultRendering==="compact"){let l=Jd(t,!1,o.collapsedResultLines),f=r?.state?.compactTitle??Kd(t.details)??"",p=r?.state?.compactInputPreview??"";return new ya(f,p,l,i)}let c=Jd(t,a,o.collapsedResultLines),u=Kd(t.details),d=[...u?[i.fg("muted",u)]:[],...c.lines.map(l=>i.fg("toolOutput",l))].join(`
|
|
601
601
|
`);return new va(d,a,o.collapsedResultLines+(u?1:0),i.fg("muted","\u2026"),i.fg("muted","(Ctrl+O to expand)"),c.truncated)}function di(t){return(e,n,r,o)=>sw(e,n,r,o,t)}function nf(t){if(t&&typeof t=="object"&&"error"in t){let e=t.error;if(e==="tool_error"||e==="call_failed")return{isError:!0}}}import{formatWithOptions as aw}from"node:util";import{Worker as cw}from"node:worker_threads";var rf=3e4,fi=class extends Error{constructor(e){super(`mcpScript timed out after ${e}ms`),this.name="McpScriptTimeoutError"}};function cf(t,e=new WeakSet){if(t===void 0||typeof t=="bigint"||typeof t=="function"||typeof t=="symbol")return!0;if(typeof t!="object"||t===null)return!1;if(e.has(t)||t instanceof Map||t instanceof Set||t instanceof WeakMap||t instanceof WeakSet)return!0;e.add(t);try{return Object.values(t).some(n=>cf(n,e))}finally{e.delete(t)}}function uw(t){if(typeof t=="string")return t;try{if(!cf(t)){let e=JSON.stringify(t,null,2);if(e!==void 0)return e}return aw({colors:!1,depth:6},t)}catch{return"[unserializable value]"}}function of(t){if(typeof t=="object"&&t!==null){let e=t;if(e.type==="text"&&typeof e.text=="string")return{type:"text",text:e.text};if(e.type==="image"&&typeof e.data=="string"&&typeof e.mimeType=="string")return{type:"image",data:e.data,mimeType:e.mimeType}}return{type:"text",text:uw(t)}}function sf(t){return t.filter(e=>e.type==="text").map(e=>e.text).join(`
|
|
602
|
-
`)}function af(t){return t instanceof Error?t:new Error(String(t??"MCP request aborted"))}function lw(t){if(typeof t!="object"||t===null)return null;let e=t;return e.type==="emit"&&"block"in e?{type:"emit",block:e.block}:e.type==="call"&&typeof e.id=="number"&&typeof e.path=="string"?"args"in e?{type:"call",id:e.id,path:e.path,args:e.args}:{type:"call",id:e.id,path:e.path}:(e.type==="search"||e.type==="describe")&&typeof e.id=="number"?"input"in e?{type:e.type,id:e.id,input:e.input}:{type:e.type,id:e.id}:e.type==="done"?"returnBlock"in e?{type:"done",returnBlock:e.returnBlock}:{type:"done"}:e.type==="error"&&typeof e.message=="string"?{type:"error",message:e.message}:null}async function uf(t,e,n=rf,r,o){let i=Number.isFinite(n)&&n>0?Math.floor(n):rf,s=[],a=te(t.owner?.signal,o),c=new AbortController,u=te(a,c.signal),d=[],l=()=>d.map(({startedAt:h,...M})=>({...M,durationMs:"error"in M&&M.error==="incomplete"?Math.max(0,Date.now()-h):M.durationMs})),f,p=async(h,M)=>{let P=Date.now(),C=d.push({operation:"call",path:h,ok:!1,error:"incomplete",durationMs:0,startedAt:P})-1,E=await tr(t,h,M,void 0,r,u,"script"),L=E.details;if(L.error!==void 0){let H=String(L.error),$=Array.isArray(L.suggestions)?L.suggestions.filter(T=>typeof T=="string"):[],O=H==="tool_not_found"?`Tool "${h}" not found. Use await tools.search({ query: "..." }) inside mcpScript.${$.length>0?` Did you mean: ${$.join(", ")}`:""}`:typeof L.message=="string"?L.message:sf(E.content);return d[C]={operation:"call",path:h,ok:!1,error:H,durationMs:Date.now()-P,startedAt:P},{ok:!1,error:{code:H,message:O}}}return d[C]={operation:"call",path:h,ok:!0,durationMs:Date.now()-P,startedAt:P},{ok:!0,data:L.mcpResult!==void 0?L.mcpResult:sf(E.content)}},g=h=>{let M=Date.now(),P=typeof h?.query=="string"?h.query:"",C;try{if(P.trim()==="")return{items:[],total:0,hasMore:!1,nextOffset:null};let E=typeof h?.server=="string"?h.server:void 0,L=typeof h?.limit=="number"?h.limit:12,H=typeof h?.offset=="number"?h.offset:0,$=ii(Nr(t,P,E),H,L);return{...$,items:$.items.map(({server:O,tool:T,score:G})=>({path:T.name,name:T.originalName,server:O,...T.description?{description:T.description}:{},score:G}))}}catch(E){throw C=E,E}finally{d.push(C===void 0?{operation:"search",query:P,ok:!0,durationMs:Date.now()-M,startedAt:M}:{operation:"search",query:P,ok:!1,error:C instanceof Error?C.message:String(C),durationMs:Date.now()-M,startedAt:M})}},y=h=>{let M=Date.now(),P=typeof h?.path=="string"?h.path:"",C;try{for(let[L,H]of t.toolMetadata){if(Te(t,L))continue;let $=Ar(H,P);if(!$)continue;let O=$.inputSchema?Dr($.inputSchema)??rt($.inputSchema):null;return{path:$.name,name:$.originalName,server:L,...$.description?{description:$.description}:{},...O?{inputTypeScript:O}:{}}}let E=P?un(t,P,5):[];return C="tool_not_found",{path:P,error:{code:"tool_not_found",message:`Tool not found: ${P}`,suggestions:E}}}catch(E){throw C=E,E}finally{d.push(C===void 0?{operation:"describe",path:P,ok:!0,durationMs:Date.now()-M,startedAt:M}:{operation:"describe",path:P,ok:!1,error:C instanceof Error?C.message:String(C),durationMs:Date.now()-M,startedAt:M})}},w,b,v=()=>{},m,S;try{if(a?.aborted)throw af(a.reason);w=new cw(new URL("./mcp-script-worker.mjs",import.meta.url),{workerData:{code:e},env:{},trackUnmanagedFds:!1});let h=w,M=new Promise((L,H)=>{let $=!1;h.on("message",O=>{let T=lw(O);if(!(!T||$)){if(T.type==="emit"){s.push(of(T.block));return}if(T.type==="done"){$=!0,"returnBlock"in T&&s.push(of(T.returnBlock)),L();return}if(T.type==="error"){$=!0,H(new Error(T.message));return}(async()=>{let G;T.type==="call"?G=await p(T.path,T.args):T.type==="search"?G=g(T.input):G=y(T.input);let F={type:"result",id:T.id,envelope:G};h.postMessage(F)})().catch(H)}}),h.once("error",H),h.once("exit",O=>{!$&&O!==0&&H(new Error(`mcpScript worker exited with code ${O}`))})}),P=new fi(i),C=new Promise((L,H)=>{b=setTimeout(()=>{f=l(),c.abort(P),h.terminate(),H(P)},i)}),E=a?new Promise((L,H)=>{let $=()=>{f=l(),h.terminate(),H(af(a.reason))};a.addEventListener("abort",$,{once:!0}),v=()=>a.removeEventListener("abort",$)}):new Promise(()=>{});await Promise.race([M,C,E])}catch(h){h instanceof fi?(m="timeout",S=`mcpScript timed out after ${i}ms`):a?.aborted?(m="aborted",S=h instanceof Error?h.message:String(h)):(m="script_error",S=h instanceof Error?h.message:String(h)),s.push({type:"text",text:S})}finally{clearTimeout(b),v(),f??=l(),c.abort(new Error("mcpScript finished")),await w?.terminate()}let R=await Le(s.length>0?[...s]:[{type:"text",text:"(no output)"}],Yn(t.config.settings));return{content:R.content,details:{mode:"script",...m?{error:m,message:S}:{},timeoutMs:i,...f.length>0?{calls:f}:{},...Ne(R)}}}ue();nt();import{Type as pi}from"typebox";en();It();nt();ue();var dw=new Set(["read","bash","edit","write","grep","find","ls","mcp"]),lf="_mcpns_";function fw(t){let e=t.replace(/-/g,"_");if(e===""||/^[A-Za-z0-9_]+$/.test(e)&&!e.startsWith(lf))return e;let n=Array.from(e,r=>r.codePointAt(0).toString(16)).join("_");return`${lf}${n}`}function Ut(t){return`mcp__${fw(t)}`}function df(t){if(!t.startsWith("mcp:"))return{raw:t};let e=t.slice(4).trim();if(!e)return{raw:t};let n=e.indexOf("/");if(n===-1)return{raw:t,server:e};let r=e.slice(0,n).trim(),o=e.slice(n+1).trim();return{raw:t,...r?{server:r}:{},...o?{tool:o}:{}}}function wa(t,e,n,r){if(r){if(r.servers.has(n))return!0;let o=r.tools.get(n);return o?[...o]:!1}return e.directTools!==void 0?e.directTools:t.settings?.directTools===!0}function ba(t,e,n,r){return r?r.servers.has(n):t?.directTools!==void 0?t.directTools===!0||Array.isArray(t.directTools)&&t.directTools.length>0:e?.directTools===!0}function Ca(t,e){return t.tools.length>0||e.exposeResources!==!1&&(t.resources?.length??0)>0}function xa(t,e,n,r,o,i){let s=t.mcpServers[i];if(!s||U(s)||ba(s,t.settings,i,n))return!1;let a=Ut(i);if(r.has(a)||o.has(a))return!1;let c=Ma(s,e,i);return!!c&&Ca(c,s)}function Ma(t,e,n){let r=e?.servers[n];if(!(!t||!r||!$e(r,t)))return r}function ff(t,e){let n=[];if(!e)return n;for(let[r,o]of Object.entries(t.mcpServers)){if(U(o))continue;let i=Ma(o,e,r);i&&n.push({serverName:r,definition:o,entry:i,prefix:pe(o,t.settings?.toolPrefix)})}return n}function pw(t,e,n,r){let o=new Map;if(!e)return new Set;for(let i of Object.keys(t.mcpServers)){if(!xa(t,e,n,new Set,r,i))continue;let s=Ut(i);o.set(s,(o.get(s)??0)+1)}return new Set([...o].filter(([,i])=>i>1).map(([i])=>i))}function gw(t,e,n,r){let o=new Map;for(let{serverName:i,definition:s,entry:a,prefix:c}of ff(t,e)){let u=wa(t,s,i,n);for(let{name:d,originalName:l}of Ta(a,i,s,c,u,r))o.has(d)||o.set(d,{serverName:i,originalName:l})}return o}function mw(t,e){if(e)return Tr(t.mcpServers,e,t.settings?.toolPrefix??"server")}function hw(t,e,n,r,o){if(Ee(t,e,r,n.includeTools,n.excludeTools,o))return se(t,e,r)}function Ta(t,e,n,r,o,i,s){if(!o)return[];let a=[],c=u=>{if(o!==!0&&!o.includes(u))return;let d=hw(u,e,n,r,i);d&&(dw.has(d)||s!==void 0&&u!==s&&d!==s||a.push({name:d,originalName:u}))};for(let u of t.tools)ke(u.uiVisibility)&&c(u.name);if(n.exposeResources!==!1)for(let u of t.resources??[])c(`read_${Ce(u.name)}`);return a}function pf(t,e,n){return t.filter(({name:r,originalName:o})=>{let i=n.get(r);return i?.serverName===e&&i.originalName===o}).map(({name:r})=>r)}function gf(t,e,n,r,o,i){if(i===void 0)return!0;let s=a=>Ee(a,e,r,n.includeTools,n.excludeTools,o)?i===se(a,e,r):!1;return t.tools.some(a=>ke(a.uiVisibility)&&s(a.name))?!0:n.exposeResources===!1?!1:(t.resources??[]).some(a=>{let c=`read_${Ce(a.name)}`;return s(c)})}function Br(t,e,n){e.has(n)||(e.add(n),t.push(n))}function yw(t,e,n,r,o,i,s,a,c,u,d){let l=t.server,f=e.mcpServers[l];if(!f||U(f)){d.push(`MCP reference "${t.raw}" refers to disabled or unknown server "${l}"`);return}let p=Ma(f,n,l);if(!p){d.push(`MCP reference "${t.raw}" cannot be resolved: no valid cached metadata for server "${l}"`);return}let g=pe(f,e.settings?.toolPrefix),y=wa(e,f,l,r),w=pf(Ta(p,l,f,g,y,a,t.tool),l,s);if(w.length>0){for(let b of w)Br(c,u,b);return}if(xa(e,n,r,o,i,l)){if(gf(p,l,f,g,a,t.tool)){Br(c,u,Ut(l));return}d.push(`MCP reference "${t.raw}" refers to unknown or hidden tool "${t.tool}" on server "${l}"`);return}d.push(`MCP reference "${t.raw}" resolves to no registered tool`)}function vw(t,e,n,r,o,i,s,a,c,u,d,l){let f=!1;for(let{serverName:p,definition:g,entry:y,prefix:w}of ff(n,r)){let b=wa(n,g,p,o),v=pf(Ta(y,p,g,w,b,c,e),p,a);for(let m of v)Br(u,d,m),f=!0;xa(n,r,o,i,s,p)&&gf(y,p,g,w,c,e)&&(Br(u,d,Ut(p)),f=!0)}f||l.push(`MCP reference "${t}" does not match a configured server or cached tool`)}function Sw(t,e,n,r){let o=[],i=[],s=new Set;if(!e)return{names:t.filter(f=>!f.startsWith("mcp:")),diagnostics:t.filter(f=>f.startsWith("mcp:")).map(f=>`MCP reference "${f}" cannot be resolved: no MCP config`)};let a=r?tn(r):null,c=mw(e,n),u=gw(e,n,a,c),d=new Set(u.keys()),l=pw(e,n,a,d);for(let f of t){if(!f.startsWith("mcp:")){Br(o,s,f);continue}let p=df(f);if(!p.server){i.push(`MCP reference "${f}" is empty after the "mcp:" prefix`);continue}e.mcpServers[p.server]?yw(p,e,n,a,l,d,u,c,o,s,i):p.tool===void 0?vw(f,p.server,e,n,a,l,d,u,c,o,s,i):i.push(`MCP reference "${f}" refers to unknown server "${p.server}"`)}return{names:o,diagnostics:i}}function ww(t,e,n,r,o){let i=t.mcpServers[o];if(!i||U(i)||ba(i,t.settings,o,n))return null;let s=e.servers?.[o];if(!s||!$e(s,i)||!Ca(s,i))return null;let a=Ut(o);return r.has(a)?null:{serverName:o,toolName:a,description:`Namespace-proxy for MCP server "${o}". Forwards \`{tool, args}\` through the adapter's executeCall, so it inherits the same auth / lifecycle / output-guard rules as the \`mcp\` proxy.`}}function bw(t){let e=new Map;for(let n of t){let r=e.get(n.toolName)??[];r.push(n),e.set(n.toolName,r)}return t.filter(n=>{let r=e.get(n.toolName);return r.length===1?!0:(r[0]===n&&console.warn(`MCP: skipping namespace proxy "${n.toolName}" because servers ${r.map(({serverName:o})=>`"${o}"`).sort().join(", ")} normalize to the same name`),!1)})}function Cw(t,e,n,r,o){return!t||!e?[]:bw(Object.keys(t.mcpServers).map(i=>ww(t,e,n,r,i)).filter(i=>i!==null)).filter(i=>!o.has(i.serverName))}function xw(t,e,n,r){return async(o,i,s)=>{if(typeof i.tool!="string"||i.tool.length===0)return{content:[{type:"text",text:`mcp__${n} requires a \`tool\` parameter naming the underlying MCP tool.`}],details:{error:"missing_tool",server:n}};let a=t();if(!a){let c=e();if(c)try{a=await c}catch(u){let d=u instanceof Error?u.message:String(u);return{content:[{type:"text",text:`MCP initialization failed for ${n}: ${d}`}],details:{error:"init_failed",server:n,message:d}}}}return a?tr(a,i.tool,i.args??{},n,r,s,"proxy"):{content:[{type:"text",text:`MCP not initialized for ${n}.`}],details:{error:"not_initialized",server:n}}}}var Mw=pi.Object({tool:pi.String({description:"Underlying MCP tool name to call on this server."}),args:pi.Optional(pi.Object({},{additionalProperties:!0,description:"Arguments for the underlying tool. The exact shape depends on the tool being called; use mcp({ describe: 'server/tool' }) to inspect."}))});function Tw(t,e){let n=li(t);return(r,o,i)=>n({...r.tool!==void 0?{tool:r.tool}:{},...r.args!==void 0?{args:r.args}:{},server:e},o,i)}function Aw(t,e,n,r,o){t.pi.registerTool({name:e.toolName,label:`MCP: ${e.serverName}`,description:e.description,promptSnippet:`MCP namespace proxy for ${e.serverName}`,parameters:Mw,renderShell:r,renderCall:Tw(n,e.serverName),renderResult:o,execute:xw(t.getState,t.getInitPromise,e.serverName,t.getPiTools)})}function Pw(t,e){if(e.length!==0)try{return t.getActiveTools?.()}catch(n){if(n instanceof Error&&n.message.includes("Action methods cannot be called during extension loading"))return;throw n}}function Rw(t,e){let n=t.activeDirectNames??new Set,r=[...t.existingNamespaceNames].filter(u=>!e.has(u)&&!n.has(u)),o=[],i=t.pi.unregisterTool;for(let u of r)i?.(u)&&o.push(u);let s=Pw(t.pi,r);if(!s)return o;let a=new Set(r),c=s.filter(u=>!a.has(u));if(c.length===s.length)return o;t.pi.setActiveTools(c);for(let u of r)o.includes(u)||o.push(u);return o}function mf(t){let e=Cw(t.config,t.cache,t.envOverride,t.existingDirectNames,t.unavailableServers??new Set),n=new Set(e.map(a=>a.toolName)),r={specs:e,added:[],updated:[],deactivated:[]},o=t.renderOptions??fn(),i=t.renderShell??(o.resultRendering==="compact"?"self":"default"),s=t.renderResult??di(o);for(let a of e)Aw(t,a,o,i,s),(t.existingNamespaceNames.has(a.toolName)?r.updated:r.added).push(a.toolName);return r.deactivated.push(...Rw(t,n)),r}ue();var Hr=3e4,Ew=1e3,Ra=Symbol("init-wait-timed-out"),hf="pi-mcp-adapter:runtime-register:v1",yf=1,vf="pi-mcp-adapter:runtime-snapshot:v1",Sf=1,wf=new WeakMap,bf=new WeakMap;async function Aa(t,e){let n;try{return await Promise.race([t,new Promise(r=>{n=setTimeout(()=>r(Ra),e),n.unref?.()})])}finally{clearTimeout(n)}}function Pa(t){let e=oe.Number;return typeof e=="function"?oe.Optional(e(t)):{type:"number",...t}}function kw(t){return t?.split(",").map(e=>e.trim()).filter(Boolean)}function Ow(t,e){return t==="__none__"?{servers:new Set,tools:new Map}:e?tn(e):null}function $w(t,e){let n=e.config!==void 0?Vt(e.config):void 0,r=n!==void 0,o=null,i=null,s=null,a=null,c=0,u=null;function d(x){let k=Ve(_e(x),Ew);return u=k,k}function l(){u=null}function f(x,k=u){let A="Fix the MCP server configuration or startup failure, then call mcp(...) again to retry initialization.";return k?`${x}: ${k}. ${A}`:`${x}. ${A}`}function p(x,k){if(!k.signal.aborted)return ie(x);let A=k.signal.reason;return A instanceof Error&&A.message==="MCP initialization failed"&&x!==A?ie(x):!0}function g(x){let k=++c,A=Dn(),_=$t(A.signal);s=A,a=_,o=null,me(x,A,_,k,"stale_gateway_retry_initialization")}async function y(x,k){if(!x){zs(t.events);return}zs(x.statusEvents),x.uiServer&&(x.uiServer.close(k),x.uiServer=null);let A;try{Pl(x)}catch(_){A=_}try{x.owner?await x.owner.stop(k):await x.lifecycle.gracefulShutdown()}catch(_){if(A)console.error(`MCP: graceful shutdown failed after metadata flush error: ${_e(_)}`);else throw _}if(A)throw A}let w=r?void 0:e.configPath??cc(),b=r?Vt(n):io(w),v=ze(),m=process.env.MCP_DIRECT_TOOLS,S=kw(m),R=Ow(m,S),h=new Map,M=new Set,P=new Set,C=fn(b.settings),E=C.resultRendering==="compact"?"self":"default",L=di(C),H=!1,$=null,O=!1,T=new Map;function G(x,k,A){let _=A.lifecycle??"lazy",z=_==="eager"||_==="lazy-keep-alive",V=A.idleTimeout??(z?0:void 0);x.lifecycle.registerServer(k,A,V!==void 0?{idleTimeout:V}:void 0),_==="keep-alive"&&x.lifecycle.markKeepAlive(k,A)}let F=x=>typeof oe.Unsafe=="function"?oe.Unsafe(x):x;function Oe(x){return JSON.stringify({serverName:x.serverName,originalName:x.originalName,prefixedName:x.prefixedName,description:x.description,inputSchema:x.inputSchema,resourceUri:x.resourceUri,uiResourceUri:x.uiResourceUri,uiStreamMode:x.uiStreamMode})}function fe(x,k){t.registerTool({name:x.prefixedName,label:`MCP: ${x.originalName}`,description:x.description||"(no description)",promptSnippet:Ve(x.description,100)||`MCP tool from ${x.serverName}`,parameters:F(lc(x.inputSchema)),...k.settings?.strictDirectToolArguments===!0?{prepareArguments:A=>xd(x.inputSchema,A)}:{},execute:Ad(()=>o,()=>i,x),renderShell:E,renderCall:ef(x.prefixedName,C),renderResult:L})}function j(){let x=o;return x?new Set(Object.keys(x.config.mcpServers).filter(k=>Te(x,k))):new Set}function Q(x,k,A){if(m==="__none__")return[];let _=x.settings?.toolPrefix??"server";return Md(x,k,_,S,j(),A)}function ne(){try{return t.getActiveTools?.()}catch(x){if(x instanceof Error&&x.message.includes("Action methods cannot be called during extension loading"))return;throw x}}function Se(x){if(x.length===0)return[];let k=t.unregisterTool,A=x.filter(B=>k?.(B)===!0),_=x.filter(B=>!A.includes(B)),z=new Set(x),V=ne();if(!V||V.length===0){for(let B of _)P.add(B);return A}let N=V.filter(B=>!z.has(B));if(N.length!==V.length){for(let B of _)P.add(B);t.setActiveTools(N)}return A}function Xe(x,k){let A=new Set,_=Q(x,k,A),z=new Set(_.map(Y=>Y.prefixedName)),V=[],N=[],B=[];for(let Y of _){let ft=Oe(Y),Z=h.get(Y.prefixedName);if(Z!==ft){if(fe(Y,x),h.set(Y.prefixedName,ft),P.delete(Y.prefixedName)){let W=ne();W&&!W.includes(Y.prefixedName)&&t.setActiveTools([...W,Y.prefixedName])}(Z?N:V).push(Y.prefixedName)}}for(let Y of[...h.keys()])z.has(Y)||(h.delete(Y),B.push(Y));return Se(B),{specs:_,reservedDirectNames:A,activeDirectNames:z,added:V,updated:N,deactivated:B}}function dt(x){if(o)for(let[k,A]of x){let _=o.config.mcpServers[k];_&&(o.config.mcpServers[k]={..._,directTools:A})}}function Re(x){let k=o?.config??b,A=ze(),_=Xe(k,A);et(k,A,_.specs),St(k,A,_.reservedDirectNames,_.activeDirectNames),_.added.length+_.updated.length+_.deactivated.length>0&&x?.hasUI&&x.ui.notify(`MCP: direct tools refreshed (+${_.added.length}, ~${_.updated.length}, -${_.deactivated.length})`,"info")}function St(x,k,A=new Set(h.keys()),_=new Set(h.keys())){let z=mf({config:x,cache:k,envOverride:R,existingDirectNames:A,activeDirectNames:_,existingNamespaceNames:M,unavailableServers:j(),pi:t,getState:()=>o,getInitPromise:()=>i,getPiTools:()=>t.getAllTools(),renderOptions:C,renderShell:E,renderResult:L});for(let V of z.added)M.add(V);for(let V of z.deactivated)M.delete(V)}let st=new Set;function pn(x){for(let k of x){if(st.has(k.commandName)){X.debug(`MCP: prompt "${k.originalName}" on ${k.serverName} skipped; /${k.commandName} is already registered`);continue}st.add(k.commandName),t.registerCommand(k.commandName,kd(t,()=>o,k))}}function wt(){pn([...o?.promptMetadata?.values()??[]].flat())}pn(Ed(b));let I=(x,k)=>{if(typeof x!="string"||x.trim()==="")throw new Error("MCP server name must be a non-empty string");if(typeof k!="object"||k===null||Array.isArray(k))throw new Error(`MCP server definition for "${x}" must be an object`);let A=o?.config??b;if(T.has(x)||Object.hasOwn(A.mcpServers,x))throw new Error(`MCP server "${x}" is already registered`);let _=structuredClone(k),z={...structuredClone(_),directTools:!1};T.set(x,{definition:_,entry:z});let V=o;V&&(V.config.mcpServers[x]=z,G(V,x,z),Re(),ge(V));let N=!1;return{dispose:async()=>{if(N)return;N=!0,T.delete(x);let B=o;!B||B.config.mcpServers[x]!==z||(delete B.config.mcpServers[x],B.lifecycle.unregisterServer(x),await B.manager.close(x),Re(),ge(B))}}},q=x=>{if(typeof x!="string"||x.trim()==="")throw new Error("MCP runtime server name must be a non-empty string");let k=T.get(x);if(!k)throw new Error(`MCP runtime server "${x}" is not registered or has been disposed`);let A=o;if(!A)throw new Error(`MCP runtime server "${x}" is unavailable because the adapter has no active state`);let _=A.config.mcpServers[x];if(Object.hasOwn(A.config.mcpServers,x)&&_!==k.entry)throw new Error(`MCP runtime server "${x}" is shadowed by a configured server`);if(_!==k.entry)throw new Error(`MCP runtime server "${x}" is unavailable in the active adapter state`);return{name:x,definition:structuredClone(k.definition),runtime:!0,persisted:!1}};wf.set(t,I),bf.set(t,q),t.events.on(hf,x=>{if(typeof x!="object"||x===null||Array.isArray(x))return;let k=x;if(k.result===void 0){if(k.version!==yf){k.result={ok:!1,error:new Error(`Unsupported MCP runtime registration version: ${String(k.version)}`)};return}try{k.result={ok:!0,registration:I(k.name,k.definition)}}catch(A){k.result={ok:!1,error:A instanceof Error?A:new Error(String(A))}}}}),t.events.on(vf,x=>{if(typeof x!="object"||x===null||Array.isArray(x))return;let k=x;if(k.result===void 0){if(k.version!==Sf){k.result={ok:!1,error:new Error(`Unsupported MCP runtime snapshot version: ${String(k.version)}`)};return}try{k.result={ok:!0,snapshot:q(k.name)}}catch(A){k.result={ok:!1,error:A instanceof Error?A:new Error(String(A))}}}});let ee=()=>t.getAllTools();t.registerFlag("mcp-config",{description:"Path to MCP config file",type:"string"});function me(x,k,A,_,z){k.addCleanup(()=>Ql(k.signal));let V=Al(t,x,k,{...r||e.configPath!==void 0?{...w!==void 0?{configPath:w}:{},...n!==void 0?{config:n}:{}}:{},oauthRuntime:A});return i=V,V.then(async N=>{if(!k.isActive()||_!==c||i!==V){try{await y(N,z)}catch(B){console.error(`MCP: failed to clean stale initialization state: ${_e(B)}`)}return}o=N,l();for(let[B,{entry:Y}]of T){if(Object.hasOwn(N.config.mcpServers,B)){console.error(`MCP: runtime-registered server "${B}" now collides with a configured server; keeping the configured server`);continue}N.config.mcpServers[B]=Y,G(N,B,Y)}N.onToolMetadataUpdated=(B,Y)=>{if(!(o!==N||!k.isActive())){if(wt(),O){X.debug(`MCP: metadata update for ${B} (${Y}) skipped \u2014 directTools frozen`);return}Re(x)}},wt(),Re(x),N.statusEvents=t.events,ge(N),i=null,b.settings?.freezeDirectTools===!0&&(O=!0,X.info(`MCP: direct tools frozen after initial sync \u2014 reconnects won't rebuild the system prompt; use mcp({ connect: "server" }) to rediscover`))}).catch(async N=>{if(!k.isActive()||_!==c||i!==V&&i!==null)return;let B=d(N);if(console.error(`MCP initialization failed: ${B}`),i=null,!o)try{await Promise.all([k.stop("MCP initialization failed"),jn(A)])}catch(Y){console.error(`MCP: failed to clean rejected initialization: ${_e(Y)}`)}})}function Ie(){Object.values(b.mcpServers).some(k=>k.disabled===!0?!1:k.lifecycle==="eager"||k.lifecycle==="keep-alive")&&setImmediate(()=>{if(c!==0||o||i)return;let k=++c,A=Dn(),_=$t(A.signal);s=A,a=_,me({mode:"print",hasUI:!1,cwd:process.cwd(),model:void 0,modelRegistry:void 0,signal:void 0},A,_,k,"stale_load_time_initialization")})}t.on("session_start",async(x,k)=>{let A=++c,_=o,z=s,V=a,N=Dn(),B=$t(N.signal);s=N,a=B,o=null,i=null,l();let Y=z?.stop("MCP extension session restarted")??Promise.resolve();try{await Promise.all([Y,y(_,"session_restart"),V?jn(V):Promise.resolve()])}catch(Z){console.error(`MCP: failed to shut down previous session state: ${_e(Z)}`)}if(A!==c||!N.isActive())return;let ft=me(k,N,B,A,"stale_session_start");m!==void 0&&m!=="__none__"&&Fn(b,ze(),S).length>0&&await ft}),t.on("input",async()=>{let x=s;if(!x?.isActive())return;if(!o&&i)try{await Aa(i,Hr)}catch{return}let k=o;if(!(!k||!x.isActive()))try{await k.lifecycle.ensureConverged(x.signal)}catch(A){ie(A,x.signal)||X.debug(`MCP: keep-alive convergence failed before input: ${_e(A)}`)}}),t.on("session_shutdown",async()=>{++c;let x=o,k=s,A=a;s=null,a=null,o=null,i=null,l();let _=k?.stop("MCP extension session shutdown")??Promise.resolve();try{await Promise.all([_,y(x,"session_shutdown"),A?jn(A):Promise.resolve()])}catch(z){console.error(`MCP: session shutdown cleanup failed: ${_e(z)}`)}}),t.on("tool_result",x=>nf(x.details));let J=x=>t.registerCommand(x,{description:"Show MCP server status",getArgumentCompletions:k=>{let A=k.trimStart(),_=A.match(/^(\S+)\s+(.*)$/);if(!_){let B=[{value:"reconnect",label:"reconnect \u2014 Reconnect servers"},{value:"tools",label:"tools \u2014 List all tools"},{value:"prompts",label:"prompts \u2014 List all MCP prompts"},{value:"setup",label:"setup \u2014 Configure MCP servers"},{value:"logout",label:"logout \u2014 Clear server credentials"},{value:"token",label:"token \u2014 Manage stored bearer tokens"},{value:"disable",label:"disable \u2014 Disable a server"},{value:"enable",label:"enable \u2014 Enable a server"},{value:"status",label:"status \u2014 Show server status"}].filter(({value:Y})=>Y.startsWith(A));return B.length>0?B:null}let[,z,V]=_;if(z!=="reconnect"&&z!=="logout"&&z!=="disable"&&z!=="enable"&&z!=="token"||V===void 0||!o)return null;if(z==="token"){let B=V.trimStart().match(/^(set|remove|status)\s+(.*)$/);if(!B){let W=["set","remove","status"].filter(he=>he.startsWith(V.trimStart())).map(he=>({value:`token ${he} `,label:`${he} \u2014 Bearer token ${he}`}));return W.length>0?W:null}let Y=B[1]??"",ft=B[2]??"",Z=Object.keys(o.config.mcpServers).filter(W=>W.startsWith(ft.trimStart())).map(W=>({value:`token ${Y} ${W}`,label:W}));return Z.length>0?Z:null}let N=Object.keys(o.config.mcpServers).filter(B=>B.startsWith(V.trimStart())).map(B=>({value:`${z} ${B}`,label:B}));return N.length>0?N:null},handler:async(k,A)=>{let _=s,z=typeof A.reload=="function"?A.reload.bind(A):async()=>{},V=A.hasUI,N={hasUI:V,ui:V?_?vr(A.ui,_):A.ui:void 0,cwd:A.cwd,mode:A.mode,signal:_?.signal??A.signal};if(!o&&i)try{let W=await i;_?.throwIfInactive(),o=W}catch(W){let he=W instanceof Error?W.message:String(W);N.hasUI&&N.ui?.notify(`MCP initialization failed: ${he}`,"error");return}if(!o){N.hasUI&&N.ui?.notify("MCP not initialized","error");return}let B=k?.trim()?.split(/\s+/)??[],Y=B[0]??"",ft=B[1],Z=B.slice(1).join(" ");switch(Y){case"reconnect":_?.throwIfInactive(),await Bl(o,N,ft),O&&Re(N);break;case"tools":await jl(o,N);break;case"prompts":await Ll(o,N);break;case"setup":{if(_?.throwIfInactive(),r){N.ui?.notify("MCP setup is unavailable when config is supplied by createMcpAdapter().","info");break}if((await ea(o,t,N,w,"setup"))?.configChanged){_?.throwIfInactive(),await z();return}break}case"logout":{let W=Z;if(!W){N.hasUI&&N.ui?.notify("Usage: /mcp logout <server>","error");return}_?.throwIfInactive(),await Hl(W,o,N);break}case"token":{let W=B[1],he=B.slice(2).join(" ");if(W!=="set"&&W!=="remove"&&W!=="status"){N.hasUI&&N.ui?.notify("Usage: /mcp token set|remove|status <server>","error");return}if(!he){N.hasUI&&N.ui?.notify("Usage: /mcp token set|remove|status <server>","error");return}_?.throwIfInactive(),await Fl(W,he,o,N);break}case"disable":case"enable":{let W=Z;if(r){N.ui?.notify(`/mcp ${Y} is unavailable when config is supplied by createMcpAdapter().`,"info");break}if(!W){N.ui?.notify(`Usage: /mcp ${Y} <server>`,"error");break}if(!o.config.mcpServers[W]){N.ui?.notify(`Server "${W}" not found in effective config`,"error");break}_?.throwIfInactive();let he=bc(w,N.cwd,W,Y==="disable");he.changed?N.ui?.notify(`${Y==="disable"?"Disabled":"Enabled"} server "${W}" in ${he.path} \u2014 run /reload to apply`,"info"):N.ui?.notify(`Server "${W}" is already ${Y==="disable"?"disabled":"enabled"}`,"info");break}default:if(N.hasUI){if(_?.throwIfInactive(),r){N.ui?.notify("MCP status is shown from the in-memory SDK config; configuration discovery is unavailable.","info"),await Pr(o,N);break}if((await ql(o,t,N,w,he=>{dt(he),Re(N)}))?.configChanged){_?.throwIfInactive(),await z();return}}else await Pr(o,N);break}}});J("mcp"),J("pi-mcp"),t.registerCommand("mcp-auth",{description:"Authenticate with an MCP server (OAuth)",handler:async(x,k)=>{let A=s,_=k.hasUI,z={hasUI:_,ui:_?A?vr(k.ui,A):k.ui:void 0,cwd:k.cwd,mode:k.mode,signal:A?.signal??k.signal},V=x?.trim();if(!V&&!z.hasUI)return;if(!o&&i)try{let B=await i;A?.throwIfInactive(),o=B}catch(B){let Y=B instanceof Error?B.message:String(B);z.hasUI&&z.ui?.notify(`MCP initialization failed: ${Y}`,"error");return}if(!o){z.hasUI&&z.ui?.notify("MCP not initialized","error");return}if(!V){if(r){z.ui?.notify("Use /mcp-auth <server> to authenticate a server from the in-memory SDK config.","info");return}await Vl(o,t,z,w);return}(await Zs(V,o.config,z,z.signal,o.oauthRuntime)).ok&&(A?.throwIfInactive(),await Wo(o,z,V))}}),b.settings?.scriptMode!==!1&&t.registerTool({name:"mcpScript",label:"MCP Script",description:"Run trusted JavaScript that makes multiple MCP tool calls in one request \u2014 loop, filter, chain, or fan out between calls. For a single MCP call, search, describe, status check, or auth action, use the mcp tool instead. Discover with await tools.search({ query }) \u2014 resolves to { items: [{ path, name, server, description? }], total, hasMore, nextOffset }, not an { ok, data } envelope. Inspect with await tools.describe({ path }) \u2014 resolves to the tool descriptor with inputTypeScript, or { path, error: { code, message, suggestions } }. Then call tools.call(path, args) \u2014 resolves to { ok: true, data } or { ok: false, error: { code, message } } \u2014 or use direct flat calls when the name is already known; use emit(value) for user-visible output. Load the mcp-scripting skill for the full workflow guide.",promptSnippet:"Batch multiple MCP tool calls in one JavaScript request (loop, filter, chain)",parameters:oe.Object({code:oe.String({description:"Trusted JavaScript MCP script. Use tools.<prefixedToolName>(args) and emit(value)."}),timeoutMs:Pa({minimum:1,description:"Execution timeout in milliseconds (default: 30000)"})}),renderCall:tf(C),renderResult:L,async execute(x,k,A){let _=s;if(!o&&i)try{let z=await Aa(i,Hr);if(z===Ra)return{content:[{type:"text",text:"MCP initialization is still in progress. Try again shortly."}],details:{mode:"script",error:"init_timeout",timeoutMs:Hr}};_?.throwIfInactive(),o=z}catch(z){if(_&&p(z,_))throw z;let V=z instanceof Error?z.message:String(z);return{content:[{type:"text",text:`MCP initialization failed: ${V}`}],details:{mode:"script",error:"init_failed",message:V}}}return o?(_?.throwIfInactive(),uf(o,k.code,k.timeoutMs,ee,A)):{content:[{type:"text",text:u?f("MCP is not initialized after an earlier initialization failure"):"MCP not initialized"}],details:{mode:"script",error:"not_initialized",...u?{message:u}:{}}}}});function we(x){t.registerTool({name:"mcp",label:"MCP",description:x,promptSnippet:"MCP gateway \u2014 status, search, describe, auth, and single MCP tool calls",renderShell:E,renderCall:li(C),parameters:oe.Object({tool:oe.Optional(oe.String({description:"Tool name to call (e.g., 'xcodebuild_list_sims')"})),args:oe.Optional(oe.Union([oe.String({description:`Arguments as a JSON string (e.g., '{"key": "value"}')`}),oe.Object({},{additionalProperties:!0,description:'Arguments as a JSON object (e.g., { "key": "value" })'})],{description:"Tool arguments as a JSON object, or as a JSON string encoding one"})),connect:oe.Optional(oe.String({description:"Server name to connect (lazy connect + metadata refresh)"})),describe:oe.Optional(oe.String({description:"Tool name to describe (shows parameters)"})),instructions:oe.Optional(oe.String({description:"Server name to show that server's usage instructions"})),search:oe.Optional(oe.String({description:"Search tools by name/description"})),regex:oe.Optional(oe.Boolean({description:"Treat search as regex (default: substring match)"})),includeSchemas:oe.Optional(oe.Boolean({description:"Include parameter schemas in search results (default: true)"})),limit:Pa({minimum:1,description:"Maximum search results to return (default: 12)"}),offset:Pa({minimum:0,description:"Search result offset (default: 0)"}),server:oe.Optional(oe.String({description:"Filter to specific server (also disambiguates tool calls)"})),action:oe.Optional(oe.String({description:"Action: 'ui-messages', 'auth-start', or 'auth-complete'"}))}),renderResult:L,async execute(k,A,_,z,V){let N=s,Y=(Z=>{if(Z===void 0||Z==="")return;let W;if(typeof Z=="string")try{W=JSON.parse(Z)}catch(he){throw he instanceof SyntaxError?new Error(`Invalid args JSON: ${he.message}`,{cause:he}):he}else W=Z;if(typeof W!="object"||W===null||Array.isArray(W)){let he=Array.isArray(W)?"array":W===null?"null":typeof W;throw new Error(`Invalid args: expected a JSON object, got ${he}`)}return W})(A.args);if(!(Z=>Z.tool!==void 0||Z.connect!==void 0||Z.describe!==void 0||Z.instructions!==void 0||Z.search!==void 0||Z.server!==void 0||Z.action!==void 0)(A)&&A.args!==void 0)throw new Error('Gateway params were nested inside `args`; pass them top-level (for example, mcp({ search: "..." }) or mcp({ tool: "...", args: {} })).');if(!o&&!i&&u&&(g(V),N=s),!o&&i)try{let Z=await Aa(i,Hr);if(Z===Ra)return{content:[{type:"text",text:"MCP initialization is still in progress. Try again shortly."}],details:{error:"init_timeout",timeoutMs:Hr}};N?.throwIfInactive(),o=Z}catch(Z){if(N&&p(Z,N))throw Z;let W=d(Z);return{content:[{type:"text",text:f("MCP initialization failed",W)}],details:{error:"init_failed",message:W}}}if(!o)return{content:[{type:"text",text:u?f("MCP is not initialized after an earlier initialization failure"):"MCP not initialized"}],details:{error:"not_initialized",...u?{message:u}:{}}};if(N?.throwIfInactive(),A.action==="ui-messages")return jd(o);if(A.action==="auth-start")return A.server?_?ga(o,A.server,_):ga(o,A.server):{content:[{type:"text",text:'auth-start requires `server`. Example: mcp({ action: "auth-start", server: "linear-server" })'}],details:{mode:"auth-start",error:"missing_server"}};if(A.action==="auth-complete"){if(!A.server)return{content:[{type:"text",text:"auth-complete requires `server`."}],details:{mode:"auth-complete",error:"missing_server"}};let Z=Y?.redirectUrl??Y?.code??Y?.input;return typeof Z!="string"||Z.trim().length===0?{content:[{type:"text",text:"auth-complete requires args with `redirectUrl`, `code`, or `input`."}],details:{mode:"auth-complete",error:"missing_input"}}:_?ma(o,A.server,Z,_):ma(o,A.server,Z)}if(A.tool)return tr(o,A.tool,Y,A.server,ee,_);if(A.connect){let Z=await qd(o,A.connect,_);return Re(V),Z}return A.describe?Hd(o,A.describe):A.instructions?zd(o,A.instructions):A.search!==void 0?Fd(o,A.search,A.regex,A.server,A.includeSchemas,A.limit,A.offset):A.server?ha(o,A.server):Bd(o)}}),H=!0,$=x}function et(x,k,A){let _=Fn(x,k,m===void 0||m==="__none__"?void 0:S);if(x.settings?.disableProxyTool!==!0||A.length===0||_.length>0){let V=Td(x);if(!H||$!==V){we(V);return}let N=ne();N&&!N.includes("mcp")&&t.setActiveTools([...N,"mcp"]);return}H&&Se(["mcp"]).includes("mcp")&&(H=!1,$=null)}let Dt=Xe(b,v);et(b,v,Dt.specs),St(b,v,Dt.reservedDirectNames,Dt.activeDirectNames),Ie()}function Iw(t={}){let e=t.config!==void 0?Vt(t.config):void 0;return function(r){$w(r,{...t.configPath!==void 0?{configPath:t.configPath}:{},...e!==void 0?{config:Vt(e)}:{}})}}function RP(t){let{pi:e,name:n,definition:r}=t,o=wf.get(e);if(o)return o(n,r);let i={version:yf,name:n,definition:r};if(e.events.emit(hf,i),!i.result)throw new Error("pi-mcp-adapter is not installed for this Pi instance");if(!i.result.ok)throw i.result.error;return i.result.registration}function EP(t){let{pi:e,name:n}=t,r=bf.get(e);if(r)return r(n);let o={version:Sf,name:n};if(e.events.emit(vf,o),!o.result)throw new Error("pi-mcp-adapter is not installed for this Pi instance");if(!o.result.ok)throw o.result.error;return o.result.snapshot}var kP=Iw();export{hf as MCP_RUNTIME_REGISTER_EVENT,yf as MCP_RUNTIME_REGISTER_VERSION,vf as MCP_RUNTIME_SNAPSHOT_EVENT,Sf as MCP_RUNTIME_SNAPSHOT_VERSION,ir as MCP_STATUS_EVENT,sr as MCP_STATUS_SNAPSHOT_VERSION,Si as MCP_TOOL_APPROVAL_REQUEST_EVENT,Iw as createMcpAdapter,kP as default,EP as getRuntimeMcpServerSnapshot,Ut as namespaceProxyName,df as parseMcpReference,RP as registerMcpServer,Sw as resolveMcpToolReferences};
|
|
602
|
+
`)}function af(t){return t instanceof Error?t:new Error(String(t??"MCP request aborted"))}function lw(t){if(typeof t!="object"||t===null)return null;let e=t;return e.type==="emit"&&"block"in e?{type:"emit",block:e.block}:e.type==="call"&&typeof e.id=="number"&&typeof e.path=="string"?"args"in e?{type:"call",id:e.id,path:e.path,args:e.args}:{type:"call",id:e.id,path:e.path}:(e.type==="search"||e.type==="describe")&&typeof e.id=="number"?"input"in e?{type:e.type,id:e.id,input:e.input}:{type:e.type,id:e.id}:e.type==="done"?"returnBlock"in e?{type:"done",returnBlock:e.returnBlock}:{type:"done"}:e.type==="error"&&typeof e.message=="string"?{type:"error",message:e.message}:null}async function uf(t,e,n=rf,r,o){let i=Number.isFinite(n)&&n>0?Math.floor(n):rf,s=[],a=te(t.owner?.signal,o),c=new AbortController,u=te(a,c.signal),d=[],l=()=>d.map(({startedAt:h,...M})=>({...M,durationMs:"error"in M&&M.error==="incomplete"?Math.max(0,Date.now()-h):M.durationMs})),f,p=async(h,M)=>{let P=Date.now(),C=d.push({operation:"call",path:h,ok:!1,error:"incomplete",durationMs:0,startedAt:P})-1,E=await tr(t,h,M,void 0,r,u,"script"),L=E.details;if(L.error!==void 0){let H=String(L.error),$=Array.isArray(L.suggestions)?L.suggestions.filter(T=>typeof T=="string"):[],O=H==="tool_not_found"?`Tool "${h}" not found. Use await tools.search({ query: "..." }) inside mcpScript.${$.length>0?` Did you mean: ${$.join(", ")}`:""}`:typeof L.message=="string"?L.message:sf(E.content);return d[C]={operation:"call",path:h,ok:!1,error:H,durationMs:Date.now()-P,startedAt:P},{ok:!1,error:{code:H,message:O}}}return d[C]={operation:"call",path:h,ok:!0,durationMs:Date.now()-P,startedAt:P},{ok:!0,data:L.mcpResult!==void 0?L.mcpResult:sf(E.content)}},g=h=>{let M=Date.now(),P=typeof h?.query=="string"?h.query:"",C;try{if(P.trim()==="")return{items:[],total:0,hasMore:!1,nextOffset:null};let E=typeof h?.server=="string"?h.server:void 0,L=typeof h?.limit=="number"?h.limit:12,H=typeof h?.offset=="number"?h.offset:0,$=ii(Nr(t,P,E),H,L);return{...$,items:$.items.map(({server:O,tool:T,score:G})=>({path:T.name,name:T.originalName,server:O,...T.description?{description:T.description}:{},score:G}))}}catch(E){throw C=E,E}finally{d.push(C===void 0?{operation:"search",query:P,ok:!0,durationMs:Date.now()-M,startedAt:M}:{operation:"search",query:P,ok:!1,error:C instanceof Error?C.message:String(C),durationMs:Date.now()-M,startedAt:M})}},y=h=>{let M=Date.now(),P=typeof h?.path=="string"?h.path:"",C;try{for(let[L,H]of t.toolMetadata){if(Te(t,L))continue;let $=Ar(H,P);if(!$)continue;let O=$.inputSchema?Dr($.inputSchema)??rt($.inputSchema):null;return{path:$.name,name:$.originalName,server:L,...$.description?{description:$.description}:{},...O?{inputTypeScript:O}:{}}}let E=P?un(t,P,5):[];return C="tool_not_found",{path:P,error:{code:"tool_not_found",message:`Tool not found: ${P}`,suggestions:E}}}catch(E){throw C=E,E}finally{d.push(C===void 0?{operation:"describe",path:P,ok:!0,durationMs:Date.now()-M,startedAt:M}:{operation:"describe",path:P,ok:!1,error:C instanceof Error?C.message:String(C),durationMs:Date.now()-M,startedAt:M})}},w,b,v=()=>{},m,S;try{if(a?.aborted)throw af(a.reason);w=new cw(new URL("./mcp-script-worker.mjs",import.meta.url),{workerData:{code:e},env:{},trackUnmanagedFds:!1});let h=w,M=new Promise((L,H)=>{let $=!1;h.on("message",O=>{let T=lw(O);if(!(!T||$)){if(T.type==="emit"){s.push(of(T.block));return}if(T.type==="done"){$=!0,"returnBlock"in T&&s.push(of(T.returnBlock)),L();return}if(T.type==="error"){$=!0,H(new Error(T.message));return}(async()=>{let G;T.type==="call"?G=await p(T.path,T.args):T.type==="search"?G=g(T.input):G=y(T.input);let F={type:"result",id:T.id,envelope:G};h.postMessage(F)})().catch(H)}}),h.once("error",H),h.once("exit",O=>{!$&&O!==0&&H(new Error(`mcpScript worker exited with code ${O}`))})}),P=new fi(i),C=new Promise((L,H)=>{b=setTimeout(()=>{f=l(),c.abort(P),h.terminate(),H(P)},i)}),E=a?new Promise((L,H)=>{let $=()=>{f=l(),h.terminate(),H(af(a.reason))};a.addEventListener("abort",$,{once:!0}),v=()=>a.removeEventListener("abort",$)}):new Promise(()=>{});await Promise.race([M,C,E])}catch(h){h instanceof fi?(m="timeout",S=`mcpScript timed out after ${i}ms`):a?.aborted?(m="aborted",S=h instanceof Error?h.message:String(h)):(m="script_error",S=h instanceof Error?h.message:String(h)),s.push({type:"text",text:S})}finally{clearTimeout(b),v(),f??=l(),c.abort(new Error("mcpScript finished")),await w?.terminate()}let R=await Le(s.length>0?[...s]:[{type:"text",text:"(no output)"}],Yn(t.config.settings));return{content:R.content,details:{mode:"script",...m?{error:m,message:S}:{},timeoutMs:i,...f.length>0?{calls:f}:{},...Ne(R)}}}ue();nt();import{Type as pi}from"./vendor/typebox/index.js";en();It();nt();ue();var dw=new Set(["read","bash","edit","write","grep","find","ls","mcp"]),lf="_mcpns_";function fw(t){let e=t.replace(/-/g,"_");if(e===""||/^[A-Za-z0-9_]+$/.test(e)&&!e.startsWith(lf))return e;let n=Array.from(e,r=>r.codePointAt(0).toString(16)).join("_");return`${lf}${n}`}function Ut(t){return`mcp__${fw(t)}`}function df(t){if(!t.startsWith("mcp:"))return{raw:t};let e=t.slice(4).trim();if(!e)return{raw:t};let n=e.indexOf("/");if(n===-1)return{raw:t,server:e};let r=e.slice(0,n).trim(),o=e.slice(n+1).trim();return{raw:t,...r?{server:r}:{},...o?{tool:o}:{}}}function wa(t,e,n,r){if(r){if(r.servers.has(n))return!0;let o=r.tools.get(n);return o?[...o]:!1}return e.directTools!==void 0?e.directTools:t.settings?.directTools===!0}function ba(t,e,n,r){return r?r.servers.has(n):t?.directTools!==void 0?t.directTools===!0||Array.isArray(t.directTools)&&t.directTools.length>0:e?.directTools===!0}function Ca(t,e){return t.tools.length>0||e.exposeResources!==!1&&(t.resources?.length??0)>0}function xa(t,e,n,r,o,i){let s=t.mcpServers[i];if(!s||U(s)||ba(s,t.settings,i,n))return!1;let a=Ut(i);if(r.has(a)||o.has(a))return!1;let c=Ma(s,e,i);return!!c&&Ca(c,s)}function Ma(t,e,n){let r=e?.servers[n];if(!(!t||!r||!$e(r,t)))return r}function ff(t,e){let n=[];if(!e)return n;for(let[r,o]of Object.entries(t.mcpServers)){if(U(o))continue;let i=Ma(o,e,r);i&&n.push({serverName:r,definition:o,entry:i,prefix:pe(o,t.settings?.toolPrefix)})}return n}function pw(t,e,n,r){let o=new Map;if(!e)return new Set;for(let i of Object.keys(t.mcpServers)){if(!xa(t,e,n,new Set,r,i))continue;let s=Ut(i);o.set(s,(o.get(s)??0)+1)}return new Set([...o].filter(([,i])=>i>1).map(([i])=>i))}function gw(t,e,n,r){let o=new Map;for(let{serverName:i,definition:s,entry:a,prefix:c}of ff(t,e)){let u=wa(t,s,i,n);for(let{name:d,originalName:l}of Ta(a,i,s,c,u,r))o.has(d)||o.set(d,{serverName:i,originalName:l})}return o}function mw(t,e){if(e)return Tr(t.mcpServers,e,t.settings?.toolPrefix??"server")}function hw(t,e,n,r,o){if(Ee(t,e,r,n.includeTools,n.excludeTools,o))return se(t,e,r)}function Ta(t,e,n,r,o,i,s){if(!o)return[];let a=[],c=u=>{if(o!==!0&&!o.includes(u))return;let d=hw(u,e,n,r,i);d&&(dw.has(d)||s!==void 0&&u!==s&&d!==s||a.push({name:d,originalName:u}))};for(let u of t.tools)ke(u.uiVisibility)&&c(u.name);if(n.exposeResources!==!1)for(let u of t.resources??[])c(`read_${Ce(u.name)}`);return a}function pf(t,e,n){return t.filter(({name:r,originalName:o})=>{let i=n.get(r);return i?.serverName===e&&i.originalName===o}).map(({name:r})=>r)}function gf(t,e,n,r,o,i){if(i===void 0)return!0;let s=a=>Ee(a,e,r,n.includeTools,n.excludeTools,o)?i===se(a,e,r):!1;return t.tools.some(a=>ke(a.uiVisibility)&&s(a.name))?!0:n.exposeResources===!1?!1:(t.resources??[]).some(a=>{let c=`read_${Ce(a.name)}`;return s(c)})}function Br(t,e,n){e.has(n)||(e.add(n),t.push(n))}function yw(t,e,n,r,o,i,s,a,c,u,d){let l=t.server,f=e.mcpServers[l];if(!f||U(f)){d.push(`MCP reference "${t.raw}" refers to disabled or unknown server "${l}"`);return}let p=Ma(f,n,l);if(!p){d.push(`MCP reference "${t.raw}" cannot be resolved: no valid cached metadata for server "${l}"`);return}let g=pe(f,e.settings?.toolPrefix),y=wa(e,f,l,r),w=pf(Ta(p,l,f,g,y,a,t.tool),l,s);if(w.length>0){for(let b of w)Br(c,u,b);return}if(xa(e,n,r,o,i,l)){if(gf(p,l,f,g,a,t.tool)){Br(c,u,Ut(l));return}d.push(`MCP reference "${t.raw}" refers to unknown or hidden tool "${t.tool}" on server "${l}"`);return}d.push(`MCP reference "${t.raw}" resolves to no registered tool`)}function vw(t,e,n,r,o,i,s,a,c,u,d,l){let f=!1;for(let{serverName:p,definition:g,entry:y,prefix:w}of ff(n,r)){let b=wa(n,g,p,o),v=pf(Ta(y,p,g,w,b,c,e),p,a);for(let m of v)Br(u,d,m),f=!0;xa(n,r,o,i,s,p)&&gf(y,p,g,w,c,e)&&(Br(u,d,Ut(p)),f=!0)}f||l.push(`MCP reference "${t}" does not match a configured server or cached tool`)}function Sw(t,e,n,r){let o=[],i=[],s=new Set;if(!e)return{names:t.filter(f=>!f.startsWith("mcp:")),diagnostics:t.filter(f=>f.startsWith("mcp:")).map(f=>`MCP reference "${f}" cannot be resolved: no MCP config`)};let a=r?tn(r):null,c=mw(e,n),u=gw(e,n,a,c),d=new Set(u.keys()),l=pw(e,n,a,d);for(let f of t){if(!f.startsWith("mcp:")){Br(o,s,f);continue}let p=df(f);if(!p.server){i.push(`MCP reference "${f}" is empty after the "mcp:" prefix`);continue}e.mcpServers[p.server]?yw(p,e,n,a,l,d,u,c,o,s,i):p.tool===void 0?vw(f,p.server,e,n,a,l,d,u,c,o,s,i):i.push(`MCP reference "${f}" refers to unknown server "${p.server}"`)}return{names:o,diagnostics:i}}function ww(t,e,n,r,o){let i=t.mcpServers[o];if(!i||U(i)||ba(i,t.settings,o,n))return null;let s=e.servers?.[o];if(!s||!$e(s,i)||!Ca(s,i))return null;let a=Ut(o);return r.has(a)?null:{serverName:o,toolName:a,description:`Namespace-proxy for MCP server "${o}". Forwards \`{tool, args}\` through the adapter's executeCall, so it inherits the same auth / lifecycle / output-guard rules as the \`mcp\` proxy.`}}function bw(t){let e=new Map;for(let n of t){let r=e.get(n.toolName)??[];r.push(n),e.set(n.toolName,r)}return t.filter(n=>{let r=e.get(n.toolName);return r.length===1?!0:(r[0]===n&&console.warn(`MCP: skipping namespace proxy "${n.toolName}" because servers ${r.map(({serverName:o})=>`"${o}"`).sort().join(", ")} normalize to the same name`),!1)})}function Cw(t,e,n,r,o){return!t||!e?[]:bw(Object.keys(t.mcpServers).map(i=>ww(t,e,n,r,i)).filter(i=>i!==null)).filter(i=>!o.has(i.serverName))}function xw(t,e,n,r){return async(o,i,s)=>{if(typeof i.tool!="string"||i.tool.length===0)return{content:[{type:"text",text:`mcp__${n} requires a \`tool\` parameter naming the underlying MCP tool.`}],details:{error:"missing_tool",server:n}};let a=t();if(!a){let c=e();if(c)try{a=await c}catch(u){let d=u instanceof Error?u.message:String(u);return{content:[{type:"text",text:`MCP initialization failed for ${n}: ${d}`}],details:{error:"init_failed",server:n,message:d}}}}return a?tr(a,i.tool,i.args??{},n,r,s,"proxy"):{content:[{type:"text",text:`MCP not initialized for ${n}.`}],details:{error:"not_initialized",server:n}}}}var Mw=pi.Object({tool:pi.String({description:"Underlying MCP tool name to call on this server."}),args:pi.Optional(pi.Object({},{additionalProperties:!0,description:"Arguments for the underlying tool. The exact shape depends on the tool being called; use mcp({ describe: 'server/tool' }) to inspect."}))});function Tw(t,e){let n=li(t);return(r,o,i)=>n({...r.tool!==void 0?{tool:r.tool}:{},...r.args!==void 0?{args:r.args}:{},server:e},o,i)}function Aw(t,e,n,r,o){t.pi.registerTool({name:e.toolName,label:`MCP: ${e.serverName}`,description:e.description,promptSnippet:`MCP namespace proxy for ${e.serverName}`,parameters:Mw,renderShell:r,renderCall:Tw(n,e.serverName),renderResult:o,execute:xw(t.getState,t.getInitPromise,e.serverName,t.getPiTools)})}function Pw(t,e){if(e.length!==0)try{return t.getActiveTools?.()}catch(n){if(n instanceof Error&&n.message.includes("Action methods cannot be called during extension loading"))return;throw n}}function Rw(t,e){let n=t.activeDirectNames??new Set,r=[...t.existingNamespaceNames].filter(u=>!e.has(u)&&!n.has(u)),o=[],i=t.pi.unregisterTool;for(let u of r)i?.(u)&&o.push(u);let s=Pw(t.pi,r);if(!s)return o;let a=new Set(r),c=s.filter(u=>!a.has(u));if(c.length===s.length)return o;t.pi.setActiveTools(c);for(let u of r)o.includes(u)||o.push(u);return o}function mf(t){let e=Cw(t.config,t.cache,t.envOverride,t.existingDirectNames,t.unavailableServers??new Set),n=new Set(e.map(a=>a.toolName)),r={specs:e,added:[],updated:[],deactivated:[]},o=t.renderOptions??fn(),i=t.renderShell??(o.resultRendering==="compact"?"self":"default"),s=t.renderResult??di(o);for(let a of e)Aw(t,a,o,i,s),(t.existingNamespaceNames.has(a.toolName)?r.updated:r.added).push(a.toolName);return r.deactivated.push(...Rw(t,n)),r}ue();var Hr=3e4,Ew=1e3,Ra=Symbol("init-wait-timed-out"),hf="pi-mcp-adapter:runtime-register:v1",yf=1,vf="pi-mcp-adapter:runtime-snapshot:v1",Sf=1,wf=new WeakMap,bf=new WeakMap;async function Aa(t,e){let n;try{return await Promise.race([t,new Promise(r=>{n=setTimeout(()=>r(Ra),e),n.unref?.()})])}finally{clearTimeout(n)}}function Pa(t){let e=oe.Number;return typeof e=="function"?oe.Optional(e(t)):{type:"number",...t}}function kw(t){return t?.split(",").map(e=>e.trim()).filter(Boolean)}function Ow(t,e){return t==="__none__"?{servers:new Set,tools:new Map}:e?tn(e):null}function $w(t,e){let n=e.config!==void 0?Vt(e.config):void 0,r=n!==void 0,o=null,i=null,s=null,a=null,c=0,u=null;function d(x){let k=Ve(_e(x),Ew);return u=k,k}function l(){u=null}function f(x,k=u){let A="Fix the MCP server configuration or startup failure, then call mcp(...) again to retry initialization.";return k?`${x}: ${k}. ${A}`:`${x}. ${A}`}function p(x,k){if(!k.signal.aborted)return ie(x);let A=k.signal.reason;return A instanceof Error&&A.message==="MCP initialization failed"&&x!==A?ie(x):!0}function g(x){let k=++c,A=Dn(),_=$t(A.signal);s=A,a=_,o=null,me(x,A,_,k,"stale_gateway_retry_initialization")}async function y(x,k){if(!x){zs(t.events);return}zs(x.statusEvents),x.uiServer&&(x.uiServer.close(k),x.uiServer=null);let A;try{Pl(x)}catch(_){A=_}try{x.owner?await x.owner.stop(k):await x.lifecycle.gracefulShutdown()}catch(_){if(A)console.error(`MCP: graceful shutdown failed after metadata flush error: ${_e(_)}`);else throw _}if(A)throw A}let w=r?void 0:e.configPath??cc(),b=r?Vt(n):io(w),v=ze(),m=process.env.MCP_DIRECT_TOOLS,S=kw(m),R=Ow(m,S),h=new Map,M=new Set,P=new Set,C=fn(b.settings),E=C.resultRendering==="compact"?"self":"default",L=di(C),H=!1,$=null,O=!1,T=new Map;function G(x,k,A){let _=A.lifecycle??"lazy",z=_==="eager"||_==="lazy-keep-alive",V=A.idleTimeout??(z?0:void 0);x.lifecycle.registerServer(k,A,V!==void 0?{idleTimeout:V}:void 0),_==="keep-alive"&&x.lifecycle.markKeepAlive(k,A)}let F=x=>typeof oe.Unsafe=="function"?oe.Unsafe(x):x;function Oe(x){return JSON.stringify({serverName:x.serverName,originalName:x.originalName,prefixedName:x.prefixedName,description:x.description,inputSchema:x.inputSchema,resourceUri:x.resourceUri,uiResourceUri:x.uiResourceUri,uiStreamMode:x.uiStreamMode})}function fe(x,k){t.registerTool({name:x.prefixedName,label:`MCP: ${x.originalName}`,description:x.description||"(no description)",promptSnippet:Ve(x.description,100)||`MCP tool from ${x.serverName}`,parameters:F(lc(x.inputSchema)),...k.settings?.strictDirectToolArguments===!0?{prepareArguments:A=>xd(x.inputSchema,A)}:{},execute:Ad(()=>o,()=>i,x),renderShell:E,renderCall:ef(x.prefixedName,C),renderResult:L})}function j(){let x=o;return x?new Set(Object.keys(x.config.mcpServers).filter(k=>Te(x,k))):new Set}function Q(x,k,A){if(m==="__none__")return[];let _=x.settings?.toolPrefix??"server";return Md(x,k,_,S,j(),A)}function ne(){try{return t.getActiveTools?.()}catch(x){if(x instanceof Error&&x.message.includes("Action methods cannot be called during extension loading"))return;throw x}}function Se(x){if(x.length===0)return[];let k=t.unregisterTool,A=x.filter(B=>k?.(B)===!0),_=x.filter(B=>!A.includes(B)),z=new Set(x),V=ne();if(!V||V.length===0){for(let B of _)P.add(B);return A}let N=V.filter(B=>!z.has(B));if(N.length!==V.length){for(let B of _)P.add(B);t.setActiveTools(N)}return A}function Xe(x,k){let A=new Set,_=Q(x,k,A),z=new Set(_.map(Y=>Y.prefixedName)),V=[],N=[],B=[];for(let Y of _){let ft=Oe(Y),Z=h.get(Y.prefixedName);if(Z!==ft){if(fe(Y,x),h.set(Y.prefixedName,ft),P.delete(Y.prefixedName)){let W=ne();W&&!W.includes(Y.prefixedName)&&t.setActiveTools([...W,Y.prefixedName])}(Z?N:V).push(Y.prefixedName)}}for(let Y of[...h.keys()])z.has(Y)||(h.delete(Y),B.push(Y));return Se(B),{specs:_,reservedDirectNames:A,activeDirectNames:z,added:V,updated:N,deactivated:B}}function dt(x){if(o)for(let[k,A]of x){let _=o.config.mcpServers[k];_&&(o.config.mcpServers[k]={..._,directTools:A})}}function Re(x){let k=o?.config??b,A=ze(),_=Xe(k,A);et(k,A,_.specs),St(k,A,_.reservedDirectNames,_.activeDirectNames),_.added.length+_.updated.length+_.deactivated.length>0&&x?.hasUI&&x.ui.notify(`MCP: direct tools refreshed (+${_.added.length}, ~${_.updated.length}, -${_.deactivated.length})`,"info")}function St(x,k,A=new Set(h.keys()),_=new Set(h.keys())){let z=mf({config:x,cache:k,envOverride:R,existingDirectNames:A,activeDirectNames:_,existingNamespaceNames:M,unavailableServers:j(),pi:t,getState:()=>o,getInitPromise:()=>i,getPiTools:()=>t.getAllTools(),renderOptions:C,renderShell:E,renderResult:L});for(let V of z.added)M.add(V);for(let V of z.deactivated)M.delete(V)}let st=new Set;function pn(x){for(let k of x){if(st.has(k.commandName)){X.debug(`MCP: prompt "${k.originalName}" on ${k.serverName} skipped; /${k.commandName} is already registered`);continue}st.add(k.commandName),t.registerCommand(k.commandName,kd(t,()=>o,k))}}function wt(){pn([...o?.promptMetadata?.values()??[]].flat())}pn(Ed(b));let I=(x,k)=>{if(typeof x!="string"||x.trim()==="")throw new Error("MCP server name must be a non-empty string");if(typeof k!="object"||k===null||Array.isArray(k))throw new Error(`MCP server definition for "${x}" must be an object`);let A=o?.config??b;if(T.has(x)||Object.hasOwn(A.mcpServers,x))throw new Error(`MCP server "${x}" is already registered`);let _=structuredClone(k),z={...structuredClone(_),directTools:!1};T.set(x,{definition:_,entry:z});let V=o;V&&(V.config.mcpServers[x]=z,G(V,x,z),Re(),ge(V));let N=!1;return{dispose:async()=>{if(N)return;N=!0,T.delete(x);let B=o;!B||B.config.mcpServers[x]!==z||(delete B.config.mcpServers[x],B.lifecycle.unregisterServer(x),await B.manager.close(x),Re(),ge(B))}}},q=x=>{if(typeof x!="string"||x.trim()==="")throw new Error("MCP runtime server name must be a non-empty string");let k=T.get(x);if(!k)throw new Error(`MCP runtime server "${x}" is not registered or has been disposed`);let A=o;if(!A)throw new Error(`MCP runtime server "${x}" is unavailable because the adapter has no active state`);let _=A.config.mcpServers[x];if(Object.hasOwn(A.config.mcpServers,x)&&_!==k.entry)throw new Error(`MCP runtime server "${x}" is shadowed by a configured server`);if(_!==k.entry)throw new Error(`MCP runtime server "${x}" is unavailable in the active adapter state`);return{name:x,definition:structuredClone(k.definition),runtime:!0,persisted:!1}};wf.set(t,I),bf.set(t,q),t.events.on(hf,x=>{if(typeof x!="object"||x===null||Array.isArray(x))return;let k=x;if(k.result===void 0){if(k.version!==yf){k.result={ok:!1,error:new Error(`Unsupported MCP runtime registration version: ${String(k.version)}`)};return}try{k.result={ok:!0,registration:I(k.name,k.definition)}}catch(A){k.result={ok:!1,error:A instanceof Error?A:new Error(String(A))}}}}),t.events.on(vf,x=>{if(typeof x!="object"||x===null||Array.isArray(x))return;let k=x;if(k.result===void 0){if(k.version!==Sf){k.result={ok:!1,error:new Error(`Unsupported MCP runtime snapshot version: ${String(k.version)}`)};return}try{k.result={ok:!0,snapshot:q(k.name)}}catch(A){k.result={ok:!1,error:A instanceof Error?A:new Error(String(A))}}}});let ee=()=>t.getAllTools();t.registerFlag("mcp-config",{description:"Path to MCP config file",type:"string"});function me(x,k,A,_,z){k.addCleanup(()=>Ql(k.signal));let V=Al(t,x,k,{...r||e.configPath!==void 0?{...w!==void 0?{configPath:w}:{},...n!==void 0?{config:n}:{}}:{},oauthRuntime:A});return i=V,V.then(async N=>{if(!k.isActive()||_!==c||i!==V){try{await y(N,z)}catch(B){console.error(`MCP: failed to clean stale initialization state: ${_e(B)}`)}return}o=N,l();for(let[B,{entry:Y}]of T){if(Object.hasOwn(N.config.mcpServers,B)){console.error(`MCP: runtime-registered server "${B}" now collides with a configured server; keeping the configured server`);continue}N.config.mcpServers[B]=Y,G(N,B,Y)}N.onToolMetadataUpdated=(B,Y)=>{if(!(o!==N||!k.isActive())){if(wt(),O){X.debug(`MCP: metadata update for ${B} (${Y}) skipped \u2014 directTools frozen`);return}Re(x)}},wt(),Re(x),N.statusEvents=t.events,ge(N),i=null,b.settings?.freezeDirectTools===!0&&(O=!0,X.info(`MCP: direct tools frozen after initial sync \u2014 reconnects won't rebuild the system prompt; use mcp({ connect: "server" }) to rediscover`))}).catch(async N=>{if(!k.isActive()||_!==c||i!==V&&i!==null)return;let B=d(N);if(console.error(`MCP initialization failed: ${B}`),i=null,!o)try{await Promise.all([k.stop("MCP initialization failed"),jn(A)])}catch(Y){console.error(`MCP: failed to clean rejected initialization: ${_e(Y)}`)}})}function Ie(){Object.values(b.mcpServers).some(k=>k.disabled===!0?!1:k.lifecycle==="eager"||k.lifecycle==="keep-alive")&&setImmediate(()=>{if(c!==0||o||i)return;let k=++c,A=Dn(),_=$t(A.signal);s=A,a=_,me({mode:"print",hasUI:!1,cwd:process.cwd(),model:void 0,modelRegistry:void 0,signal:void 0},A,_,k,"stale_load_time_initialization")})}t.on("session_start",async(x,k)=>{let A=++c,_=o,z=s,V=a,N=Dn(),B=$t(N.signal);s=N,a=B,o=null,i=null,l();let Y=z?.stop("MCP extension session restarted")??Promise.resolve();try{await Promise.all([Y,y(_,"session_restart"),V?jn(V):Promise.resolve()])}catch(Z){console.error(`MCP: failed to shut down previous session state: ${_e(Z)}`)}if(A!==c||!N.isActive())return;let ft=me(k,N,B,A,"stale_session_start");m!==void 0&&m!=="__none__"&&Fn(b,ze(),S).length>0&&await ft}),t.on("input",async()=>{let x=s;if(!x?.isActive())return;if(!o&&i)try{await Aa(i,Hr)}catch{return}let k=o;if(!(!k||!x.isActive()))try{await k.lifecycle.ensureConverged(x.signal)}catch(A){ie(A,x.signal)||X.debug(`MCP: keep-alive convergence failed before input: ${_e(A)}`)}}),t.on("session_shutdown",async()=>{++c;let x=o,k=s,A=a;s=null,a=null,o=null,i=null,l();let _=k?.stop("MCP extension session shutdown")??Promise.resolve();try{await Promise.all([_,y(x,"session_shutdown"),A?jn(A):Promise.resolve()])}catch(z){console.error(`MCP: session shutdown cleanup failed: ${_e(z)}`)}}),t.on("tool_result",x=>nf(x.details));let J=x=>t.registerCommand(x,{description:"Show MCP server status",getArgumentCompletions:k=>{let A=k.trimStart(),_=A.match(/^(\S+)\s+(.*)$/);if(!_){let B=[{value:"reconnect",label:"reconnect \u2014 Reconnect servers"},{value:"tools",label:"tools \u2014 List all tools"},{value:"prompts",label:"prompts \u2014 List all MCP prompts"},{value:"setup",label:"setup \u2014 Configure MCP servers"},{value:"logout",label:"logout \u2014 Clear server credentials"},{value:"token",label:"token \u2014 Manage stored bearer tokens"},{value:"disable",label:"disable \u2014 Disable a server"},{value:"enable",label:"enable \u2014 Enable a server"},{value:"status",label:"status \u2014 Show server status"}].filter(({value:Y})=>Y.startsWith(A));return B.length>0?B:null}let[,z,V]=_;if(z!=="reconnect"&&z!=="logout"&&z!=="disable"&&z!=="enable"&&z!=="token"||V===void 0||!o)return null;if(z==="token"){let B=V.trimStart().match(/^(set|remove|status)\s+(.*)$/);if(!B){let W=["set","remove","status"].filter(he=>he.startsWith(V.trimStart())).map(he=>({value:`token ${he} `,label:`${he} \u2014 Bearer token ${he}`}));return W.length>0?W:null}let Y=B[1]??"",ft=B[2]??"",Z=Object.keys(o.config.mcpServers).filter(W=>W.startsWith(ft.trimStart())).map(W=>({value:`token ${Y} ${W}`,label:W}));return Z.length>0?Z:null}let N=Object.keys(o.config.mcpServers).filter(B=>B.startsWith(V.trimStart())).map(B=>({value:`${z} ${B}`,label:B}));return N.length>0?N:null},handler:async(k,A)=>{let _=s,z=typeof A.reload=="function"?A.reload.bind(A):async()=>{},V=A.hasUI,N={hasUI:V,ui:V?_?vr(A.ui,_):A.ui:void 0,cwd:A.cwd,mode:A.mode,signal:_?.signal??A.signal};if(!o&&i)try{let W=await i;_?.throwIfInactive(),o=W}catch(W){let he=W instanceof Error?W.message:String(W);N.hasUI&&N.ui?.notify(`MCP initialization failed: ${he}`,"error");return}if(!o){N.hasUI&&N.ui?.notify("MCP not initialized","error");return}let B=k?.trim()?.split(/\s+/)??[],Y=B[0]??"",ft=B[1],Z=B.slice(1).join(" ");switch(Y){case"reconnect":_?.throwIfInactive(),await Bl(o,N,ft),O&&Re(N);break;case"tools":await jl(o,N);break;case"prompts":await Ll(o,N);break;case"setup":{if(_?.throwIfInactive(),r){N.ui?.notify("MCP setup is unavailable when config is supplied by createMcpAdapter().","info");break}if((await ea(o,t,N,w,"setup"))?.configChanged){_?.throwIfInactive(),await z();return}break}case"logout":{let W=Z;if(!W){N.hasUI&&N.ui?.notify("Usage: /mcp logout <server>","error");return}_?.throwIfInactive(),await Hl(W,o,N);break}case"token":{let W=B[1],he=B.slice(2).join(" ");if(W!=="set"&&W!=="remove"&&W!=="status"){N.hasUI&&N.ui?.notify("Usage: /mcp token set|remove|status <server>","error");return}if(!he){N.hasUI&&N.ui?.notify("Usage: /mcp token set|remove|status <server>","error");return}_?.throwIfInactive(),await Fl(W,he,o,N);break}case"disable":case"enable":{let W=Z;if(r){N.ui?.notify(`/mcp ${Y} is unavailable when config is supplied by createMcpAdapter().`,"info");break}if(!W){N.ui?.notify(`Usage: /mcp ${Y} <server>`,"error");break}if(!o.config.mcpServers[W]){N.ui?.notify(`Server "${W}" not found in effective config`,"error");break}_?.throwIfInactive();let he=bc(w,N.cwd,W,Y==="disable");he.changed?N.ui?.notify(`${Y==="disable"?"Disabled":"Enabled"} server "${W}" in ${he.path} \u2014 run /reload to apply`,"info"):N.ui?.notify(`Server "${W}" is already ${Y==="disable"?"disabled":"enabled"}`,"info");break}default:if(N.hasUI){if(_?.throwIfInactive(),r){N.ui?.notify("MCP status is shown from the in-memory SDK config; configuration discovery is unavailable.","info"),await Pr(o,N);break}if((await ql(o,t,N,w,he=>{dt(he),Re(N)}))?.configChanged){_?.throwIfInactive(),await z();return}}else await Pr(o,N);break}}});J("mcp"),J("pi-mcp"),t.registerCommand("mcp-auth",{description:"Authenticate with an MCP server (OAuth)",handler:async(x,k)=>{let A=s,_=k.hasUI,z={hasUI:_,ui:_?A?vr(k.ui,A):k.ui:void 0,cwd:k.cwd,mode:k.mode,signal:A?.signal??k.signal},V=x?.trim();if(!V&&!z.hasUI)return;if(!o&&i)try{let B=await i;A?.throwIfInactive(),o=B}catch(B){let Y=B instanceof Error?B.message:String(B);z.hasUI&&z.ui?.notify(`MCP initialization failed: ${Y}`,"error");return}if(!o){z.hasUI&&z.ui?.notify("MCP not initialized","error");return}if(!V){if(r){z.ui?.notify("Use /mcp-auth <server> to authenticate a server from the in-memory SDK config.","info");return}await Vl(o,t,z,w);return}(await Zs(V,o.config,z,z.signal,o.oauthRuntime)).ok&&(A?.throwIfInactive(),await Wo(o,z,V))}}),b.settings?.scriptMode!==!1&&t.registerTool({name:"mcpScript",label:"MCP Script",description:"Run trusted JavaScript that makes multiple MCP tool calls in one request \u2014 loop, filter, chain, or fan out between calls. For a single MCP call, search, describe, status check, or auth action, use the mcp tool instead. Discover with await tools.search({ query }) \u2014 resolves to { items: [{ path, name, server, description? }], total, hasMore, nextOffset }, not an { ok, data } envelope. Inspect with await tools.describe({ path }) \u2014 resolves to the tool descriptor with inputTypeScript, or { path, error: { code, message, suggestions } }. Then call tools.call(path, args) \u2014 resolves to { ok: true, data } or { ok: false, error: { code, message } } \u2014 or use direct flat calls when the name is already known; use emit(value) for user-visible output. Load the mcp-scripting skill for the full workflow guide.",promptSnippet:"Batch multiple MCP tool calls in one JavaScript request (loop, filter, chain)",parameters:oe.Object({code:oe.String({description:"Trusted JavaScript MCP script. Use tools.<prefixedToolName>(args) and emit(value)."}),timeoutMs:Pa({minimum:1,description:"Execution timeout in milliseconds (default: 30000)"})}),renderCall:tf(C),renderResult:L,async execute(x,k,A){let _=s;if(!o&&i)try{let z=await Aa(i,Hr);if(z===Ra)return{content:[{type:"text",text:"MCP initialization is still in progress. Try again shortly."}],details:{mode:"script",error:"init_timeout",timeoutMs:Hr}};_?.throwIfInactive(),o=z}catch(z){if(_&&p(z,_))throw z;let V=z instanceof Error?z.message:String(z);return{content:[{type:"text",text:`MCP initialization failed: ${V}`}],details:{mode:"script",error:"init_failed",message:V}}}return o?(_?.throwIfInactive(),uf(o,k.code,k.timeoutMs,ee,A)):{content:[{type:"text",text:u?f("MCP is not initialized after an earlier initialization failure"):"MCP not initialized"}],details:{mode:"script",error:"not_initialized",...u?{message:u}:{}}}}});function we(x){t.registerTool({name:"mcp",label:"MCP",description:x,promptSnippet:"MCP gateway \u2014 status, search, describe, auth, and single MCP tool calls",renderShell:E,renderCall:li(C),parameters:oe.Object({tool:oe.Optional(oe.String({description:"Tool name to call (e.g., 'xcodebuild_list_sims')"})),args:oe.Optional(oe.Union([oe.String({description:`Arguments as a JSON string (e.g., '{"key": "value"}')`}),oe.Object({},{additionalProperties:!0,description:'Arguments as a JSON object (e.g., { "key": "value" })'})],{description:"Tool arguments as a JSON object, or as a JSON string encoding one"})),connect:oe.Optional(oe.String({description:"Server name to connect (lazy connect + metadata refresh)"})),describe:oe.Optional(oe.String({description:"Tool name to describe (shows parameters)"})),instructions:oe.Optional(oe.String({description:"Server name to show that server's usage instructions"})),search:oe.Optional(oe.String({description:"Search tools by name/description"})),regex:oe.Optional(oe.Boolean({description:"Treat search as regex (default: substring match)"})),includeSchemas:oe.Optional(oe.Boolean({description:"Include parameter schemas in search results (default: true)"})),limit:Pa({minimum:1,description:"Maximum search results to return (default: 12)"}),offset:Pa({minimum:0,description:"Search result offset (default: 0)"}),server:oe.Optional(oe.String({description:"Filter to specific server (also disambiguates tool calls)"})),action:oe.Optional(oe.String({description:"Action: 'ui-messages', 'auth-start', or 'auth-complete'"}))}),renderResult:L,async execute(k,A,_,z,V){let N=s,Y=(Z=>{if(Z===void 0||Z==="")return;let W;if(typeof Z=="string")try{W=JSON.parse(Z)}catch(he){throw he instanceof SyntaxError?new Error(`Invalid args JSON: ${he.message}`,{cause:he}):he}else W=Z;if(typeof W!="object"||W===null||Array.isArray(W)){let he=Array.isArray(W)?"array":W===null?"null":typeof W;throw new Error(`Invalid args: expected a JSON object, got ${he}`)}return W})(A.args);if(!(Z=>Z.tool!==void 0||Z.connect!==void 0||Z.describe!==void 0||Z.instructions!==void 0||Z.search!==void 0||Z.server!==void 0||Z.action!==void 0)(A)&&A.args!==void 0)throw new Error('Gateway params were nested inside `args`; pass them top-level (for example, mcp({ search: "..." }) or mcp({ tool: "...", args: {} })).');if(!o&&!i&&u&&(g(V),N=s),!o&&i)try{let Z=await Aa(i,Hr);if(Z===Ra)return{content:[{type:"text",text:"MCP initialization is still in progress. Try again shortly."}],details:{error:"init_timeout",timeoutMs:Hr}};N?.throwIfInactive(),o=Z}catch(Z){if(N&&p(Z,N))throw Z;let W=d(Z);return{content:[{type:"text",text:f("MCP initialization failed",W)}],details:{error:"init_failed",message:W}}}if(!o)return{content:[{type:"text",text:u?f("MCP is not initialized after an earlier initialization failure"):"MCP not initialized"}],details:{error:"not_initialized",...u?{message:u}:{}}};if(N?.throwIfInactive(),A.action==="ui-messages")return jd(o);if(A.action==="auth-start")return A.server?_?ga(o,A.server,_):ga(o,A.server):{content:[{type:"text",text:'auth-start requires `server`. Example: mcp({ action: "auth-start", server: "linear-server" })'}],details:{mode:"auth-start",error:"missing_server"}};if(A.action==="auth-complete"){if(!A.server)return{content:[{type:"text",text:"auth-complete requires `server`."}],details:{mode:"auth-complete",error:"missing_server"}};let Z=Y?.redirectUrl??Y?.code??Y?.input;return typeof Z!="string"||Z.trim().length===0?{content:[{type:"text",text:"auth-complete requires args with `redirectUrl`, `code`, or `input`."}],details:{mode:"auth-complete",error:"missing_input"}}:_?ma(o,A.server,Z,_):ma(o,A.server,Z)}if(A.tool)return tr(o,A.tool,Y,A.server,ee,_);if(A.connect){let Z=await qd(o,A.connect,_);return Re(V),Z}return A.describe?Hd(o,A.describe):A.instructions?zd(o,A.instructions):A.search!==void 0?Fd(o,A.search,A.regex,A.server,A.includeSchemas,A.limit,A.offset):A.server?ha(o,A.server):Bd(o)}}),H=!0,$=x}function et(x,k,A){let _=Fn(x,k,m===void 0||m==="__none__"?void 0:S);if(x.settings?.disableProxyTool!==!0||A.length===0||_.length>0){let V=Td(x);if(!H||$!==V){we(V);return}let N=ne();N&&!N.includes("mcp")&&t.setActiveTools([...N,"mcp"]);return}H&&Se(["mcp"]).includes("mcp")&&(H=!1,$=null)}let Dt=Xe(b,v);et(b,v,Dt.specs),St(b,v,Dt.reservedDirectNames,Dt.activeDirectNames),Ie()}function Iw(t={}){let e=t.config!==void 0?Vt(t.config):void 0;return function(r){$w(r,{...t.configPath!==void 0?{configPath:t.configPath}:{},...e!==void 0?{config:Vt(e)}:{}})}}function RP(t){let{pi:e,name:n,definition:r}=t,o=wf.get(e);if(o)return o(n,r);let i={version:yf,name:n,definition:r};if(e.events.emit(hf,i),!i.result)throw new Error("pi-mcp-adapter is not installed for this Pi instance");if(!i.result.ok)throw i.result.error;return i.result.registration}function EP(t){let{pi:e,name:n}=t,r=bf.get(e);if(r)return r(n);let o={version:Sf,name:n};if(e.events.emit(vf,o),!o.result)throw new Error("pi-mcp-adapter is not installed for this Pi instance");if(!o.result.ok)throw o.result.error;return o.result.snapshot}var kP=Iw();export{hf as MCP_RUNTIME_REGISTER_EVENT,yf as MCP_RUNTIME_REGISTER_VERSION,vf as MCP_RUNTIME_SNAPSHOT_EVENT,Sf as MCP_RUNTIME_SNAPSHOT_VERSION,ir as MCP_STATUS_EVENT,sr as MCP_STATUS_SNAPSHOT_VERSION,Si as MCP_TOOL_APPROVAL_REQUEST_EVENT,Iw as createMcpAdapter,kP as default,EP as getRuntimeMcpServerSnapshot,Ut as namespaceProxyName,df as parseMcpReference,RP as registerMcpServer,Sw as resolveMcpToolReferences};
|