xiaozhi-client 1.6.1 → 1.6.3-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Logger.d.ts +94 -0
- package/dist/Logger.js +3 -0
- package/dist/Logger.js.map +1 -0
- package/dist/ProxyMCPServer.d.ts +172 -0
- package/dist/ProxyMCPServer.js +3 -0
- package/dist/ProxyMCPServer.js.map +1 -0
- package/dist/{webServer.d.ts → WebServer.d.ts} +35 -0
- package/dist/WebServer.js +34 -0
- package/dist/WebServer.js.map +1 -0
- package/dist/WebServerStandalone.d.ts +1 -0
- package/dist/WebServerStandalone.js +35 -0
- package/dist/WebServerStandalone.js.map +1 -0
- package/dist/cli.js +12 -21
- package/dist/cli.js.map +1 -1
- package/dist/configManager.js +2 -2
- package/dist/configManager.js.map +1 -1
- package/dist/mcpCommands.js +2 -2
- package/dist/mcpCommands.js.map +1 -1
- package/dist/mcpServerProxy.d.ts +6 -138
- package/dist/mcpServerProxy.js +9 -7
- package/dist/mcpServerProxy.js.map +1 -1
- package/dist/package.json +9 -5
- package/dist/services/MCPServer.d.ts +489 -0
- package/dist/services/MCPServer.js +8 -0
- package/dist/services/MCPServer.js.map +1 -0
- package/docs/examples-usage.md +647 -0
- package/package.json +30 -33
- package/dist/adaptiveMCPPipe.d.ts +0 -8
- package/dist/adaptiveMCPPipe.js +0 -12
- package/dist/adaptiveMCPPipe.js.map +0 -1
- package/dist/autoCompletion.d.ts +0 -10
- package/dist/autoCompletion.js +0 -3
- package/dist/autoCompletion.js.map +0 -1
- package/dist/logger.d.ts +0 -46
- package/dist/logger.js +0 -3
- package/dist/logger.js.map +0 -1
- package/dist/modelScopeMCPClient.d.ts +0 -43
- package/dist/modelScopeMCPClient.js +0 -3
- package/dist/modelScopeMCPClient.js.map +0 -1
- package/dist/multiEndpointMCPPipe.d.ts +0 -30
- package/dist/multiEndpointMCPPipe.js +0 -8
- package/dist/multiEndpointMCPPipe.js.map +0 -1
- package/dist/services/mcpServer.d.ts +0 -27
- package/dist/services/mcpServer.js +0 -15
- package/dist/services/mcpServer.js.map +0 -1
- package/dist/streamableHttpMCPClient.d.ts +0 -47
- package/dist/streamableHttpMCPClient.js +0 -3
- package/dist/streamableHttpMCPClient.js.map +0 -1
- package/dist/webServer.js +0 -43
- package/dist/webServer.js.map +0 -1
- package/dist/xiaozhi.config.default.json +0 -24
- package/web/README.md +0 -169
package/dist/mcpServerProxy.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
3
|
-
`)}}enableFileLogging(e){e&&!this.writeStream&&this.logFilePath?this.writeStream=y.createWriteStream(this.logFilePath,{flags:"a",encoding:"utf8"}):!e&&this.writeStream&&(this.writeStream.end(),this.writeStream=null)}info(e,...t){this.consolaInstance.info(e,...t),this.logToFile("info",e,...t)}success(e,...t){this.consolaInstance.success(e,...t),this.logToFile("success",e,...t)}warn(e,...t){this.consolaInstance.warn(e,...t),this.logToFile("warn",e,...t)}error(e,...t){this.consolaInstance.error(e,...t),this.logToFile("error",e,...t)}debug(e,...t){this.consolaInstance.debug(e,...t),this.logToFile("debug",e,...t)}log(e,...t){this.consolaInstance.log(e,...t),this.logToFile("log",e,...t)}withTag(e){return this}close(){this.writeStream&&(this.writeStream.end(),this.writeStream=null)}},u=new M;function W(a){if(!a||typeof a!="object")throw new Error("\u670D\u52A1\u914D\u7F6E\u5FC5\u987B\u662F\u4E00\u4E2A\u6709\u6548\u7684\u5BF9\u8C61");if("command"in a&&typeof a.command=="string")return"stdio";if("type"in a&&a.type==="sse")return"sse";if("type"in a&&a.type==="streamable-http"||"url"in a&&typeof a.url=="string")return"streamable-http";throw new Error("\u65E0\u6CD5\u8BC6\u522B\u7684 MCP \u670D\u52A1\u914D\u7F6E\u7C7B\u578B\u3002\u914D\u7F6E\u5FC5\u987B\u5305\u542B command \u5B57\u6BB5\uFF08stdio\uFF09\u3001type: 'sse' \u5B57\u6BB5\uFF08sse\uFF09\u6216 url \u5B57\u6BB5\uFF08streamable-http\uFF09")}c(W,"getMcpServerCommunicationType");function E(a,e){if(!e||typeof e!="object")return{valid:!1,error:`\u670D\u52A1 "${a}" \u7684\u914D\u7F6E\u5FC5\u987B\u662F\u4E00\u4E2A\u5BF9\u8C61`};try{switch(W(e)){case"stdio":if(!e.command||typeof e.command!="string")return{valid:!1,error:`\u670D\u52A1 "${a}" \u7F3A\u5C11\u5FC5\u9700\u7684 command \u5B57\u6BB5\u6216\u5B57\u6BB5\u7C7B\u578B\u4E0D\u6B63\u786E`};if(!Array.isArray(e.args))return{valid:!1,error:`\u670D\u52A1 "${a}" \u7684 args \u5B57\u6BB5\u5FC5\u987B\u662F\u6570\u7EC4`};if(e.env&&typeof e.env!="object")return{valid:!1,error:`\u670D\u52A1 "${a}" \u7684 env \u5B57\u6BB5\u5FC5\u987B\u662F\u5BF9\u8C61`};break;case"sse":if(e.type!=="sse")return{valid:!1,error:`\u670D\u52A1 "${a}" \u7684 type \u5B57\u6BB5\u5FC5\u987B\u662F "sse"`};if(!e.url||typeof e.url!="string")return{valid:!1,error:`\u670D\u52A1 "${a}" \u7F3A\u5C11\u5FC5\u9700\u7684 url \u5B57\u6BB5\u6216\u5B57\u6BB5\u7C7B\u578B\u4E0D\u6B63\u786E`};break;case"streamable-http":if(!e.url||typeof e.url!="string")return{valid:!1,error:`\u670D\u52A1 "${a}" \u7F3A\u5C11\u5FC5\u9700\u7684 url \u5B57\u6BB5\u6216\u5B57\u6BB5\u7C7B\u578B\u4E0D\u6B63\u786E`};if(e.type&&e.type!=="streamable-http")return{valid:!1,error:`\u670D\u52A1 "${a}" \u7684 type \u5B57\u6BB5\u5982\u679C\u5B58\u5728\uFF0C\u5FC5\u987B\u662F "streamable-http"`};break;default:return{valid:!1,error:`\u670D\u52A1 "${a}" \u7684\u914D\u7F6E\u7C7B\u578B\u65E0\u6CD5\u8BC6\u522B`}}return{valid:!0}}catch(t){return{valid:!1,error:`\u670D\u52A1 "${a}" \u7684\u914D\u7F6E\u65E0\u6548: ${t instanceof Error?t.message:"\u672A\u77E5\u9519\u8BEF"}`}}}c(E,"validateMcpServerConfig");var Z=G(K(import.meta.url)),x={heartbeatInterval:3e4,heartbeatTimeout:1e4,reconnectInterval:5e3},j=class a{static{c(this,"ConfigManager")}static instance;defaultConfigPath;config=null;currentConfigPath=null;json5Writer=null;constructor(){this.defaultConfigPath=v(Z,"xiaozhi.config.default.json")}getConfigFilePath(){let e=process.env.XIAOZHI_CONFIG_DIR||process.cwd(),t=["xiaozhi.config.json5","xiaozhi.config.jsonc","xiaozhi.config.json"];for(let o of t){let i=v(e,o);if(I(i))return i}return v(e,"xiaozhi.config.json")}getConfigFileFormat(e){return e.endsWith(".json5")?"json5":e.endsWith(".jsonc")?"jsonc":"json"}static getInstance(){return a.instance||(a.instance=new a),a.instance}configExists(){let e=process.env.XIAOZHI_CONFIG_DIR||process.cwd(),t=["xiaozhi.config.json5","xiaozhi.config.jsonc","xiaozhi.config.json"];for(let o of t){let i=v(e,o);if(I(i))return!0}return!1}initConfig(e="json"){if(!I(this.defaultConfigPath))throw new Error("\u9ED8\u8BA4\u914D\u7F6E\u6587\u4EF6 xiaozhi.config.default.json \u4E0D\u5B58\u5728");if(this.configExists())throw new Error("\u914D\u7F6E\u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u65E0\u9700\u91CD\u590D\u521D\u59CB\u5316");let t=process.env.XIAOZHI_CONFIG_DIR||process.cwd(),o=`xiaozhi.config.${e}`,i=v(t,o);H(this.defaultConfigPath,i),this.config=null,this.json5Writer=null}loadConfig(){if(!this.configExists())throw new Error("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u8FD0\u884C xiaozhi init \u521D\u59CB\u5316\u914D\u7F6E");try{let e=this.getConfigFilePath();this.currentConfigPath=e;let t=this.getConfigFileFormat(e),i=L(e,"utf8").replace(/^\uFEFF/,""),r;switch(t){case"json5":r=O.parse(i),this.json5Writer=A.load(i);break;case"jsonc":r=b.parse(i);break;default:r=JSON.parse(i);break}return this.validateConfig(r),r}catch(e){throw e instanceof SyntaxError?new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF: ${e.message}`):e}}validateConfig(e){if(!e||typeof e!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1A\u6839\u5BF9\u8C61\u65E0\u6548");let t=e;if(t.mcpEndpoint===void 0||t.mcpEndpoint===null)throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u5B57\u6BB5\u65E0\u6548");if(typeof t.mcpEndpoint!="string")if(Array.isArray(t.mcpEndpoint)){if(t.mcpEndpoint.length===0)throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u6570\u7EC4\u4E0D\u80FD\u4E3A\u7A7A");for(let o of t.mcpEndpoint)if(typeof o!="string"||o.trim()==="")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u6570\u7EC4\u4E2D\u7684\u6BCF\u4E2A\u5143\u7D20\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32")}else throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u6216\u5B57\u7B26\u4E32\u6570\u7EC4");if(!t.mcpServers||typeof t.mcpServers!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers \u5B57\u6BB5\u65E0\u6548");for(let[o,i]of Object.entries(t.mcpServers)){if(!i||typeof i!="object")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${o} \u65E0\u6548`);let r=E(o,i);if(!r.valid)throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1A${r.error}`)}}getConfig(){return this.config=this.loadConfig(),JSON.parse(JSON.stringify(this.config))}getMutableConfig(){return this.config||(this.config=this.loadConfig()),this.config}getMcpEndpoint(){let e=this.getConfig();return Array.isArray(e.mcpEndpoint)?e.mcpEndpoint[0]||"":e.mcpEndpoint}getMcpEndpoints(){let e=this.getConfig();return Array.isArray(e.mcpEndpoint)?[...e.mcpEndpoint]:e.mcpEndpoint?[e.mcpEndpoint]:[]}getMcpServers(){return this.getConfig().mcpServers}getMcpServerConfig(){return this.getConfig().mcpServerConfig||{}}getServerToolsConfig(e){return this.getMcpServerConfig()[e]?.tools||{}}isToolEnabled(e,t){return this.getServerToolsConfig(e)[t]?.enable!==!1}updateMcpEndpoint(e){if(Array.isArray(e)){if(e.length===0)throw new Error("MCP \u7AEF\u70B9\u6570\u7EC4\u4E0D\u80FD\u4E3A\u7A7A");for(let o of e)if(!o||typeof o!="string")throw new Error("MCP \u7AEF\u70B9\u6570\u7EC4\u4E2D\u7684\u6BCF\u4E2A\u5143\u7D20\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32")}else if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getMutableConfig();t.mcpEndpoint=e,this.saveConfig(t)}addMcpEndpoint(e){if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getMutableConfig(),o=this.getMcpEndpoints();if(o.includes(e))throw new Error(`MCP \u7AEF\u70B9 ${e} \u5DF2\u5B58\u5728`);let i=[...o,e];t.mcpEndpoint=i,this.saveConfig(t)}removeMcpEndpoint(e){if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getMutableConfig(),o=this.getMcpEndpoints();if(o.indexOf(e)===-1)throw new Error(`MCP \u7AEF\u70B9 ${e} \u4E0D\u5B58\u5728`);if(o.length===1)throw new Error("\u4E0D\u80FD\u5220\u9664\u6700\u540E\u4E00\u4E2A MCP \u7AEF\u70B9");let r=o.filter(s=>s!==e);t.mcpEndpoint=r,this.saveConfig(t)}updateMcpServer(e,t){if(!e||typeof e!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let o=E(e,t);if(!o.valid)throw new Error(o.error||"\u670D\u52A1\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");let i=this.getMutableConfig();i.mcpServers[e]=t,this.saveConfig(i)}removeMcpServer(e){if(!e||typeof e!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getConfig();if(!t.mcpServers[e])throw new Error(`\u670D\u52A1 ${e} \u4E0D\u5B58\u5728`);let o={...t.mcpServers};delete o[e];let i={...t,mcpServers:o};this.saveConfig(i)}updateServerToolsConfig(e,t){let o=this.getMutableConfig();o.mcpServerConfig||(o.mcpServerConfig={}),Object.keys(t).length===0?delete o.mcpServerConfig[e]:o.mcpServerConfig[e]={tools:t},this.saveConfig(o)}removeServerToolsConfig(e){let o={...this.getConfig()};o.mcpServerConfig&&(delete o.mcpServerConfig[e],this.saveConfig(o))}setToolEnabled(e,t,o,i){let r=this.getMutableConfig();r.mcpServerConfig||(r.mcpServerConfig={}),r.mcpServerConfig[e]||(r.mcpServerConfig[e]={tools:{}}),r.mcpServerConfig[e].tools[t]={...r.mcpServerConfig[e].tools[t],enable:o,...i&&{description:i}},this.saveConfig(r)}saveConfig(e){try{this.validateConfig(e);let t;this.currentConfigPath?t=this.currentConfigPath:(t=this.getConfigFilePath(),this.currentConfigPath=t);let o=this.getConfigFileFormat(t),i;switch(o){case"json5":try{this.json5Writer?(this.json5Writer.write(e),i=this.json5Writer.toSource()):(console.warn("\u6CA1\u6709 json5Writer \u5B9E\u4F8B\uFF0C\u56DE\u9000\u5230\u6807\u51C6 JSON5 \u683C\u5F0F"),i=O.stringify(e,null,2))}catch(r){console.warn("\u4F7F\u7528 json5-writer \u4FDD\u5B58\u5931\u8D25\uFF0C\u56DE\u9000\u5230\u6807\u51C6 JSON5 \u683C\u5F0F:",r),i=O.stringify(e,null,2)}break;case"jsonc":try{i=b.stringify(e,null,2)}catch(r){console.warn("\u4F7F\u7528 comment-json \u4FDD\u5B58\u5931\u8D25\uFF0C\u56DE\u9000\u5230\u6807\u51C6 JSON \u683C\u5F0F:",r),i=JSON.stringify(e,null,2)}break;default:i=JSON.stringify(e,null,2);break}B(t,i,"utf8"),this.config=e,this.notifyConfigUpdate(e)}catch(t){throw new Error(`\u4FDD\u5B58\u914D\u7F6E\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}}reloadConfig(){this.config=null,this.currentConfigPath=null,this.json5Writer=null}getConfigPath(){return this.getConfigFilePath()}getDefaultConfigPath(){return this.defaultConfigPath}getConnectionConfig(){let t=this.getConfig().connection||{};return{heartbeatInterval:t.heartbeatInterval??x.heartbeatInterval,heartbeatTimeout:t.heartbeatTimeout??x.heartbeatTimeout,reconnectInterval:t.reconnectInterval??x.reconnectInterval}}getHeartbeatInterval(){return this.getConnectionConfig().heartbeatInterval}getHeartbeatTimeout(){return this.getConnectionConfig().heartbeatTimeout}getReconnectInterval(){return this.getConnectionConfig().reconnectInterval}updateConnectionConfig(e){let t=this.getMutableConfig();t.connection||(t.connection={}),Object.assign(t.connection,e),this.saveConfig(t)}async updateToolUsageStats(e,t,o){try{let i=this.getMutableConfig();i.mcpServerConfig||(i.mcpServerConfig={}),i.mcpServerConfig[e]||(i.mcpServerConfig[e]={tools:{}}),i.mcpServerConfig[e].tools[t]||(i.mcpServerConfig[e].tools[t]={enable:!0});let r=i.mcpServerConfig[e].tools[t],s=r.usageCount||0,l=r.lastUsedTime;r.usageCount=s+1,(!l||new Date(o)>new Date(l))&&(r.lastUsedTime=X(o).format("YYYY-MM-DD HH:mm:ss")),this.saveConfig(i),u.debug(`\u5DE5\u5177\u4F7F\u7528\u7EDF\u8BA1\u5DF2\u66F4\u65B0: ${e}/${t}, \u4F7F\u7528\u6B21\u6570: ${r.usageCount}`)}catch(i){u.error(`\u66F4\u65B0\u5DE5\u5177\u4F7F\u7528\u7EDF\u8BA1\u5931\u8D25 (${e}/${t}): ${i instanceof Error?i.message:String(i)}`)}}setHeartbeatInterval(e){if(e<=0)throw new Error("\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatInterval:e})}setHeartbeatTimeout(e){if(e<=0)throw new Error("\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatTimeout:e})}setReconnectInterval(e){if(e<=0)throw new Error("\u91CD\u8FDE\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({reconnectInterval:e})}getModelScopeConfig(){return this.getConfig().modelscope||{}}getModelScopeApiKey(){return this.getModelScopeConfig().apiKey||process.env.MODELSCOPE_API_TOKEN}updateModelScopeConfig(e){let t=this.getMutableConfig();t.modelscope||(t.modelscope={}),Object.assign(t.modelscope,e),this.saveConfig(t)}setModelScopeApiKey(e){if(!e||typeof e!="string")throw new Error("API Key \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");this.updateModelScopeConfig({apiKey:e})}getWebUIConfig(){return this.getConfig().webUI||{}}getWebUIPort(){return this.getWebUIConfig().port??9999}notifyConfigUpdate(e){try{let t=global.__webServer;t&&typeof t.broadcastConfigUpdate=="function"&&(t.broadcastConfigUpdate(e),console.log("\u5DF2\u901A\u8FC7 WebSocket \u5E7F\u64AD\u914D\u7F6E\u66F4\u65B0"))}catch(t){console.warn("\u901A\u77E5 Web \u754C\u9762\u914D\u7F6E\u66F4\u65B0\u5931\u8D25:",t instanceof Error?t.message:String(t))}}updateWebUIConfig(e){let t=this.getMutableConfig();t.webUI||(t.webUI={}),Object.assign(t.webUI,e),this.saveConfig(t)}setWebUIPort(e){if(!Number.isInteger(e)||e<=0||e>65535)throw new Error("\u7AEF\u53E3\u53F7\u5FC5\u987B\u662F 1-65535 \u4E4B\u95F4\u7684\u6574\u6570");this.updateWebUIConfig({port:e})}},g=j.getInstance();import{Client as Y}from"@modelcontextprotocol/sdk/client/index.js";import{SSEClientTransport as V}from"@modelcontextprotocol/sdk/client/sse.js";import{EventSource as Q}from"eventsource";global.EventSource=Q;var h=u.withTag("ModelScopeMCP"),w=class{static{c(this,"ModelScopeMCPClient")}name;config;client=null;transport=null;initialized=!1;tools=[];originalTools=[];constructor(e,t){this.name=e,this.config=t}generatePrefixedToolName(e){return`${this.name.replace(/-/g,"_")}_xzcli_${e}`}getOriginalToolName(e){let o=`${this.name.replace(/-/g,"_")}_xzcli_`;return e.startsWith(o)?e.substring(o.length):null}async start(){h.info(`\u6B63\u5728\u542F\u52A8 ModelScope MCP \u5BA2\u6237\u7AEF\uFF1A${this.name}`);try{let e=g.getModelScopeApiKey();if(!e||e==="")throw new Error("\u672A\u8BBE\u7F6E ModelScope API Key\u3002\u8BF7\u5728\u914D\u7F6E\u6587\u4EF6\u4E2D\u8BBE\u7F6E modelscope.apiKey \u6216\u8BBE\u7F6E MODELSCOPE_API_TOKEN \u73AF\u5883\u53D8\u91CF\u3002");let t={eventSourceInit:{fetch:c(async(o,i)=>{let r={...i?.headers,Authorization:`Bearer ${e}`};return fetch(o,{...i,headers:r})},"fetch")},requestInit:{headers:{Authorization:`Bearer ${e}`}}};this.transport=new V(new URL(this.config.url),t),this.client=new Y({name:"xiaozhi-modelscope-client",version:"1.0.0"},{capabilities:{}}),h.info(`\u6B63\u5728\u8FDE\u63A5\u5230 ${this.config.url}`),await this.client.connect(this.transport),h.info(`\u6210\u529F\u8FDE\u63A5\u5230 ModelScope MCP \u670D\u52A1\u5668\uFF1A${this.name}`),await this.refreshTools(),this.initialized=!0,h.info(`${this.name} ModelScope \u5BA2\u6237\u7AEF\u5DF2\u5C31\u7EEA\uFF0C\u5171 ${this.tools.length} \u4E2A\u5DE5\u5177`)}catch(e){throw h.error(`\u542F\u52A8 ModelScope MCP \u5BA2\u6237\u7AEF ${this.name} \u5931\u8D25\uFF1A${e instanceof Error?e.message:String(e)}`),e}}async refreshTools(){try{if(!this.client)throw new Error("\u5BA2\u6237\u7AEF\u672A\u521D\u59CB\u5316");let e=await this.client.listTools();this.originalTools=e.tools||[];let t=this.originalTools.map(o=>({...o,name:this.generatePrefixedToolName(o.name)}));this.tools=this.filterEnabledTools(t),await this.updateToolsConfig(),h.info(`${this.name} \u52A0\u8F7D\u4E86 ${this.originalTools.length} \u4E2A\u5DE5\u5177\uFF1A${this.originalTools.map(o=>o.name).join(", ")}`),h.info(`${this.name} \u542F\u7528\u4E86 ${this.tools.length} \u4E2A\u5DE5\u5177\uFF1A${this.tools.map(o=>o.name).join(", ")}`)}catch(e){h.error(`\u4ECE ${this.name} \u83B7\u53D6\u5DE5\u5177\u5931\u8D25\uFF1A${e instanceof Error?e.message:String(e)}`),this.tools=[],this.originalTools=[]}}filterEnabledTools(e){return e.filter(t=>{let o=this.getOriginalToolName(t.name);return o?g.isToolEnabled(this.name,o):!0})}async updateToolsConfig(){try{let e=g.getServerToolsConfig(this.name),t={};for(let i of this.originalTools){let r=e[i.name];t[i.name]={description:i.description||"",enable:r?.enable!==!1}}(Object.keys(t).some(i=>{let r=e[i],s=t[i];return!r||r.enable!==s.enable||r.description!==s.description})||Object.keys(e).length===0)&&(g.updateServerToolsConfig(this.name,t),h.info(`${this.name} \u5DF2\u66F4\u65B0\u5DE5\u5177\u914D\u7F6E`))}catch(e){h.error(`\u66F4\u65B0 ${this.name} \u7684\u5DE5\u5177\u914D\u7F6E\u5931\u8D25\uFF1A${e instanceof Error?e.message:String(e)}`)}}async callTool(e,t){try{if(!this.client)throw new Error("\u5BA2\u6237\u7AEF\u672A\u521D\u59CB\u5316");let o=this.getOriginalToolName(e);if(!o)throw new Error(`\u65E0\u6548\u7684\u5DE5\u5177\u540D\u79F0\u683C\u5F0F\uFF1A${e}`);h.info(`\u8C03\u7528 ModelScope \u5DE5\u5177 ${o}\uFF0C\u53C2\u6570\uFF1A${JSON.stringify(t)}`);let i=await this.client.callTool({name:o,arguments:t});return h.info(`ModelScope \u5DE5\u5177\u8C03\u7528\u8FD4\u56DE: ${JSON.stringify(i).substring(0,500)}...`),i}catch(o){throw h.error(`\u5728 ${this.name} \u4E0A\u8C03\u7528\u5DE5\u5177 ${e} \u5931\u8D25\uFF1A${o instanceof Error?o.message:String(o)}`),o}}async stop(){if(this.client){h.info(`\u6B63\u5728\u505C\u6B62 ${this.name} ModelScope \u5BA2\u6237\u7AEF`);try{await this.client.close()}catch(e){h.error(`\u5173\u95ED\u5BA2\u6237\u7AEF\u65F6\u51FA\u9519\uFF1A${e instanceof Error?e.message:String(e)}`)}this.client=null,this.transport=null}this.initialized=!1}};import{Client as ee}from"@modelcontextprotocol/sdk/client/index.js";import{SSEClientTransport as te}from"@modelcontextprotocol/sdk/client/sse.js";import{EventSource as oe}from"eventsource";global.EventSource=oe;var p=u.withTag("SSEMCP"),$=class{static{c(this,"SSEMCPClient")}name;config;client=null;transport=null;initialized=!1;tools=[];originalTools=[];constructor(e,t){this.name=e,this.config=t}generatePrefixedToolName(e){return`${this.name.replace(/-/g,"_")}_xzcli_${e}`}filterEnabledTools(e){return e.filter(t=>{let o=this.getOriginalToolName(t.name);return o?g.isToolEnabled(this.name,o):!1})}async updateToolsConfig(){try{let e=g.getServerToolsConfig(this.name),t={};for(let o of this.originalTools){let i=e[o.name];t[o.name]={description:o.description||i?.description||"",enable:i?.enable!==!1}}for(let[o,i]of Object.entries(e))t[o]||(t[o]=i);g.updateServerToolsConfig(this.name,t)}catch(e){p.debug(`\u66F4\u65B0 ${this.name} \u5DE5\u5177\u914D\u7F6E\u5931\u8D25\uFF1A${e instanceof Error?e.message:String(e)}`)}}async start(){p.info(`\u6B63\u5728\u542F\u52A8 SSE MCP \u5BA2\u6237\u7AEF\uFF1A${this.name}`);try{this.transport=new te(new URL(this.config.url)),this.client=new ee({name:"xiaozhi-sse-client",version:"1.0.0"},{capabilities:{}}),p.info(`\u6B63\u5728\u8FDE\u63A5\u5230 ${this.config.url}`),await this.client.connect(this.transport),p.info(`\u6210\u529F\u8FDE\u63A5\u5230 SSE MCP \u670D\u52A1\u5668\uFF1A${this.name}`),await this.refreshTools(),this.initialized=!0,p.info(`${this.name} SSE \u5BA2\u6237\u7AEF\u5DF2\u5C31\u7EEA\uFF0C\u5171 ${this.tools.length} \u4E2A\u5DE5\u5177`)}catch(e){throw p.error(`\u542F\u52A8 SSE MCP \u5BA2\u6237\u7AEF ${this.name} \u5931\u8D25\uFF1A${e instanceof Error?e.message:String(e)}`),e}}async refreshTools(){try{if(!this.client)throw new Error("\u5BA2\u6237\u7AEF\u672A\u521D\u59CB\u5316");let e=await this.client.listTools();this.originalTools=e.tools||[];let t=this.originalTools.map(o=>({...o,name:this.generatePrefixedToolName(o.name)}));this.tools=this.filterEnabledTools(t),await this.updateToolsConfig(),p.info(`${this.name} \u52A0\u8F7D\u4E86 ${this.originalTools.length} \u4E2A\u5DE5\u5177\uFF1A${this.originalTools.map(o=>o.name).join(", ")}`),p.info(`${this.name} \u542F\u7528\u4E86 ${this.tools.length} \u4E2A\u5DE5\u5177\uFF1A${this.tools.map(o=>o.name).join(", ")}`)}catch(e){throw p.error(`\u5237\u65B0 ${this.name} \u5DE5\u5177\u5217\u8868\u5931\u8D25\uFF1A${e instanceof Error?e.message:String(e)}`),e}}getOriginalToolName(e){let o=`${this.name.replace(/-/g,"_")}_xzcli_`;return e.startsWith(o)?e.substring(o.length):null}async callTool(e,t){try{if(!this.client)throw new Error("\u5BA2\u6237\u7AEF\u672A\u521D\u59CB\u5316");let o=this.getOriginalToolName(e);if(!o)throw new Error(`\u65E0\u6548\u7684\u5DE5\u5177\u540D\u79F0\u683C\u5F0F\uFF1A${e}`);p.info(`\u8C03\u7528 SSE \u5DE5\u5177 ${o}\uFF0C\u53C2\u6570\uFF1A${JSON.stringify(t)}`);let i=await this.client.callTool({name:o,arguments:t});return p.info(`SSE \u5DE5\u5177\u8C03\u7528\u8FD4\u56DE: ${JSON.stringify(i).substring(0,500)}...`),i}catch(o){throw p.error(`\u5728 ${this.name} \u4E0A\u8C03\u7528\u5DE5\u5177 ${e} \u5931\u8D25\uFF1A${o instanceof Error?o.message:String(o)}`),o}}async stop(){p.info(`\u6B63\u5728\u505C\u6B62 SSE MCP \u5BA2\u6237\u7AEF\uFF1A${this.name}`);try{this.client&&(await this.client.close(),this.client=null),this.transport&&(this.transport=null),p.info(`SSE MCP \u5BA2\u6237\u7AEF ${this.name} \u5DF2\u505C\u6B62`)}catch(e){p.error(`\u505C\u6B62 SSE MCP \u5BA2\u6237\u7AEF ${this.name} \u5931\u8D25\uFF1A${e instanceof Error?e.message:String(e)}`)}finally{this.initialized=!1}}};var m=u.withTag("StreamableHTTPMCP"),P=class{static{c(this,"StreamableHTTPMCPClient")}name;config;requestId=1;initialized=!1;tools=[];originalTools=[];constructor(e,t){this.name=e,this.config=t}generatePrefixedToolName(e){return`${this.name.replace(/-/g,"_")}_xzcli_${e}`}getOriginalToolName(e){let o=`${this.name.replace(/-/g,"_")}_xzcli_`;return e.startsWith(o)?e.substring(o.length):null}async sendRequest(e,t){let o={jsonrpc:"2.0",method:e,params:t,id:this.requestId++};m.debug(`\u53D1\u9001\u8BF7\u6C42\u5230 ${this.name}: ${JSON.stringify(o)}`);try{let i=(await import("node-fetch")).default,r=await i(this.config.url,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json, text/event-stream"},body:JSON.stringify(o)});if(!r.ok)throw new Error(`HTTP error! status: ${r.status}`);let s=await r.json();if(s.error)throw new Error(`JSON-RPC error: ${s.error.message} (code: ${s.error.code})`);return s.result}catch(i){throw m.error(`\u8BF7\u6C42\u5931\u8D25 (${e}): ${i instanceof Error?i.message:String(i)}`),i}}async sendNotification(e,t){let o={jsonrpc:"2.0",method:e,params:t};m.debug(`\u53D1\u9001\u901A\u77E5\u5230 ${this.name}: ${JSON.stringify(o)}`);try{let i=(await import("node-fetch")).default,r=await i(this.config.url,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json, text/event-stream"},body:JSON.stringify(o)});if(!r.ok)throw new Error(`HTTP error! status: ${r.status}`);m.debug(`\u901A\u77E5 ${e} \u53D1\u9001\u6210\u529F`)}catch(i){throw m.debug(`\u901A\u77E5\u53D1\u9001\u5931\u8D25 (${e}): ${i instanceof Error?i.message:String(i)}`),i}}async start(){m.info(`\u6B63\u5728\u542F\u52A8 Streamable HTTP MCP \u5BA2\u6237\u7AEF\uFF1A${this.name}`);try{await this.sendRequest("initialize",{protocolVersion:"2024-11-05",capabilities:{tools:{}},clientInfo:{name:"xiaozhi-streamable-http-client",version:"1.0.0"}});try{await this.sendNotification("notifications/initialized")}catch(t){m.debug(`${this.name} \u4E0D\u652F\u6301 notifications/initialized: ${t}`)}let e=await this.sendRequest("tools/list");e?.tools&&(this.originalTools=e.tools,await this.updateToolsConfig(),this.tools=this.originalTools.filter(t=>g.isToolEnabled(this.name,t.name)).map(t=>({...t,name:this.generatePrefixedToolName(t.name)})),m.info(`Streamable HTTP MCP \u5BA2\u6237\u7AEF ${this.name} \u5DF2\u521D\u59CB\u5316\uFF0C\u5305\u542B ${this.tools.length}/${this.originalTools.length} \u4E2A\u5DF2\u542F\u7528\u7684\u5DE5\u5177`)),this.initialized=!0}catch(e){throw m.error(`\u542F\u52A8 Streamable HTTP MCP \u5BA2\u6237\u7AEF ${this.name} \u5931\u8D25\uFF1A${e instanceof Error?e.message:String(e)}`),e}}async refreshTools(){try{let e=await this.sendRequest("tools/list");e?.tools&&(this.originalTools=e.tools,await this.updateToolsConfig(),this.tools=this.originalTools.filter(t=>g.isToolEnabled(this.name,t.name)).map(t=>({...t,name:this.generatePrefixedToolName(t.name)})),m.info(`\u5DF2\u5237\u65B0 ${this.name} \u7684\u5DE5\u5177\u5217\u8868\uFF0C\u5305\u542B ${this.tools.length}/${this.originalTools.length} \u4E2A\u5DF2\u542F\u7528\u7684\u5DE5\u5177`))}catch(e){m.error(`\u5237\u65B0 ${this.name} \u7684\u5DE5\u5177\u5217\u8868\u5931\u8D25\uFF1A${e instanceof Error?e.message:String(e)}`)}}async callTool(e,t){try{let o=this.getOriginalToolName(e);if(!o)throw new Error(`\u65E0\u6548\u7684\u5DE5\u5177\u540D\u79F0\u683C\u5F0F\uFF1A${e}`);return await this.sendRequest("tools/call",{name:o,arguments:t})}catch(o){throw m.error(`\u5728 ${this.name} \u4E0A\u8C03\u7528\u5DE5\u5177 ${e} \u5931\u8D25\uFF1A${o instanceof Error?o.message:String(o)}`),o}}async updateToolsConfig(){try{let e=g.getServerToolsConfig(this.name),t={};for(let i of this.originalTools){let r=e[i.name];t[i.name]={description:i.description||"",enable:r?.enable!==!1}}(Object.keys(t).some(i=>{let r=e[i],s=t[i];return!r||r.enable!==s.enable||r.description!==s.description})||Object.keys(e).length===0)&&(g.updateServerToolsConfig(this.name,t),m.info(`${this.name} \u5DF2\u66F4\u65B0\u5DE5\u5177\u914D\u7F6E`))}catch(e){m.error(`\u66F4\u65B0 ${this.name} \u7684\u5DE5\u5177\u914D\u7F6E\u5931\u8D25\uFF1A${e instanceof Error?e.message:String(e)}`)}}async stop(){m.info(`\u6B63\u5728\u505C\u6B62 ${this.name} \u5BA2\u6237\u7AEF`),this.initialized=!1}};var se=re(D(import.meta.url)),n=u.withTag("MCPProxy"),J=f.env.XIAOZHI_CONFIG_DIR||f.cwd();u.initLogFile(J);u.enableFileLogging(!0);n.info(`\u65E5\u5FD7\u6587\u4EF6\u5DF2\u521D\u59CB\u5316: ${J}/xiaozhi.log`);var R=class{static{c(this,"MCPClient")}name;config;process;initialized;tools;originalTools;requestId;pendingRequests;messageBuffer;constructor(e,t){this.name=e,this.config=t,this.process=null,this.initialized=!1,this.tools=[],this.originalTools=[],this.requestId=1,this.pendingRequests=new Map,this.messageBuffer=""}resolveCommand(e,t){if(f.platform==="win32"){if(e==="npm"||e==="npx")return{resolvedCommand:`${e}.cmd`,resolvedArgs:t};if(e==="uvx")return{resolvedCommand:"uvx.bat",resolvedArgs:t}}return{resolvedCommand:e,resolvedArgs:t}}generatePrefixedToolName(e){return`${this.name.replace(/-/g,"_")}_xzcli_${e}`}getOriginalToolName(e){let o=`${this.name.replace(/-/g,"_")}_xzcli_`;return e.startsWith(o)?e.substring(o.length):null}async start(){n.info(`\u6B63\u5728\u542F\u52A8 MCP \u5BA2\u6237\u7AEF\uFF1A${this.name}`);let{command:e,args:t,env:o}=this.config,{resolvedCommand:i,resolvedArgs:r}=this.resolveCommand(e,t),s={stdio:["pipe","pipe","pipe"]},l=f.env.XIAOZHI_CONFIG_DIR||f.cwd();s.cwd=l,o?s.env={...f.env,...o}:s.env={...f.env},f.platform==="win32"&&(e==="npm"||e==="npx"||e==="uvx")&&(s.shell=!0),n.debug(`${this.name} \u6B63\u5728\u751F\u6210\u8FDB\u7A0B\uFF1A${i} ${r.join(" ")} \u5DE5\u4F5C\u76EE\u5F55\uFF1A${s.cwd}`),n.debug(`${this.name} \u5E73\u53F0\uFF1A${f.platform}\uFF0Cshell \u6A21\u5F0F\uFF1A${s.shell||!1}`),this.process=ie(i,r,s),this.process.stdout?.on("data",d=>{this.handleStdoutData(d.toString())}),this.process.stderr?.on("data",d=>{n.debug(`${this.name} \u6807\u51C6\u9519\u8BEF\u8F93\u51FA\uFF1A${d.toString().trim()}`)}),this.process.on("exit",(d,T)=>{n.error(`${this.name} \u8FDB\u7A0B\u5DF2\u9000\u51FA\uFF0C\u9000\u51FA\u7801\uFF1A${d}\uFF0C\u4FE1\u53F7\uFF1A${T}`),this.initialized=!1}),this.process.on("error",d=>{n.error(`${this.name} \u8FDB\u7A0B\u9519\u8BEF\uFF1A${d.message}`),this.initialized=!1}),await this.initialize()}handleStdoutData(e){this.messageBuffer=`${this.messageBuffer}${e}`;let t=this.messageBuffer.split(`
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
`)}catch(t){n.debug(`${this.name} notifications/initialized \u53D1\u9001\u5931\u8D25\uFF08\u67D0\u4E9B\u670D\u52A1\u5668\u4E0D\u652F\u6301\u6B64\u901A\u77E5\uFF09\uFF1A${t instanceof Error?t.message:String(t)}`)}await this.refreshTools(),this.initialized=!0,n.info(`${this.name} \u5BA2\u6237\u7AEF\u5DF2\u5C31\u7EEA\uFF0C\u5171 ${this.tools.length} \u4E2A\u5DE5\u5177`)}catch(e){throw n.error(`\u521D\u59CB\u5316 ${this.name} \u5931\u8D25\uFF1A${e instanceof Error?e.message:String(e)}`),e}}async refreshTools(){try{let e=await this.sendRequest("tools/list");this.originalTools=e.tools||[];let t=this.originalTools.map(o=>({...o,name:this.generatePrefixedToolName(o.name)}));this.tools=this.filterEnabledTools(t),await this.updateToolsConfig(),n.info(`${this.name} \u52A0\u8F7D\u4E86 ${this.originalTools.length} \u4E2A\u5DE5\u5177\uFF1A${this.originalTools.map(o=>o.name).join(", ")}`),n.info(`${this.name} \u542F\u7528\u4E86 ${this.tools.length} \u4E2A\u5DE5\u5177\uFF1A${this.tools.map(o=>o.name).join(", ")}`)}catch(e){n.error(`\u4ECE ${this.name} \u83B7\u53D6\u5DE5\u5177\u5931\u8D25\uFF1A${e instanceof Error?e.message:String(e)}`),this.tools=[],this.originalTools=[]}}filterEnabledTools(e){return e.filter(t=>{let o=this.getOriginalToolName(t.name);return o?g.isToolEnabled(this.name,o):!0})}async updateToolsConfig(){try{let e=g.getServerToolsConfig(this.name),t={};for(let i of this.originalTools){let r=e[i.name];t[i.name]={description:i.description||"",enable:r?.enable!==!1}}(Object.keys(t).some(i=>{let r=e[i],s=t[i];return!r||r.enable!==s.enable||r.description!==s.description})||Object.keys(e).length===0)&&(g.updateServerToolsConfig(this.name,t),n.info(`${this.name} \u5DF2\u66F4\u65B0\u5DE5\u5177\u914D\u7F6E`))}catch(e){n.error(`\u66F4\u65B0 ${this.name} \u7684\u5DE5\u5177\u914D\u7F6E\u5931\u8D25\uFF1A${e instanceof Error?e.message:String(e)}`)}}async callTool(e,t){let o=Date.now();try{let i=this.getOriginalToolName(e);if(!i)throw new Error(`\u65E0\u6548\u7684\u5DE5\u5177\u540D\u79F0\u683C\u5F0F\uFF1A${e}`);n.info(`[MCP\u5BA2\u6237\u7AEF ${this.name}] \u5DE5\u5177\u8C03\u7528\u5F00\u59CB`),n.info(`[MCP\u5BA2\u6237\u7AEF ${this.name}] \u5DE5\u5177\u540D\u79F0: ${i} (\u524D\u7F00: ${e})`),n.info(`[MCP\u5BA2\u6237\u7AEF ${this.name}] \u8BF7\u6C42\u53C2\u6570: ${JSON.stringify(t,null,2)}`);let r=await this.sendRequest("tools/call",{name:i,arguments:t}),s=Date.now()-o;return n.info(`[MCP\u5BA2\u6237\u7AEF ${this.name}] \u5DE5\u5177\u8C03\u7528\u6210\u529F`),n.info(`[MCP\u5BA2\u6237\u7AEF ${this.name}] \u5DE5\u5177\u540D\u79F0: ${i}`),n.info(`[MCP\u5BA2\u6237\u7AEF ${this.name}] \u6267\u884C\u8017\u65F6: ${s}ms`),n.info(`[MCP\u5BA2\u6237\u7AEF ${this.name}] \u5B8C\u6574\u7ED3\u679C: ${JSON.stringify(r,null,2)}`),r}catch(i){let r=Date.now()-o;throw n.error(`[MCP\u5BA2\u6237\u7AEF ${this.name}] \u5DE5\u5177\u8C03\u7528\u5931\u8D25\u5DE5\u5177: ${e} -> ${this.getOriginalToolName(e)||"\u672A\u77E5"}\u8017\u65F6: ${r}ms\u9519\u8BEF: ${i instanceof Error?i.message:String(i)}`),n.error(`[MCP\u5BA2\u6237\u7AEF ${this.name}] \u9519\u8BEF\u5806\u6808: ${i instanceof Error?i.stack:"\u65E0\u5806\u6808\u4FE1\u606F"}`),i}}stop(){this.process&&(n.info(`\u6B63\u5728\u505C\u6B62 ${this.name} \u5BA2\u6237\u7AEF`),this.process.kill("SIGTERM"),this.process=null),this.initialized=!1}};function ae(){try{if(g.configExists()){let e=g.getMcpServers();return n.info(`\u4ECE\u914D\u7F6E\u6587\u4EF6\u52A0\u8F7D\u4E86 ${Object.keys(e).length} \u4E2A MCP \u670D\u52A1`),e}let a=ne(se,"mcp_server.json");if(F)try{let e=F(a,"utf8"),t=JSON.parse(e);if(!t.mcpServers||typeof t.mcpServers!="object")throw new Error("\u65E0\u6548\u7684\u914D\u7F6E\uFF1AmcpServers \u90E8\u5206\u672A\u627E\u5230\u6216\u65E0\u6548");return n.info(`\u4ECE\u65E7\u914D\u7F6E\u6587\u4EF6\u52A0\u8F7D\u4E86 ${Object.keys(t.mcpServers).length} \u4E2A MCP \u670D\u52A1\uFF08\u5EFA\u8BAE\u8FC1\u79FB\u5230\u65B0\u914D\u7F6E\u683C\u5F0F\uFF09`),t.mcpServers}catch{throw n.error('\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u8BF7\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E'),new Error('\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u8BF7\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E')}throw new Error('\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u8BF7\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E')}catch(a){throw n.error(`\u52A0\u8F7D MCP \u914D\u7F6E\u5931\u8D25\uFF1A${a instanceof Error?a.message:String(a)}`),a}}c(ae,"loadMCPConfig");var z=class{static{c(this,"MCPServerProxy")}clients;toolMap;initialized;config;constructor(){this.clients=new Map,this.toolMap=new Map,this.initialized=!1,this.config=null}async cleanupRemovedServers(){try{let e=Object.keys(this.config||{}),t=g.getMcpServerConfig();if(!t||typeof t!="object"){n.debug("mcpServerConfig \u4E3A\u7A7A\u6216\u4E0D\u662F\u5BF9\u8C61\uFF0C\u65E0\u9700\u6E05\u7406");return}let i=Object.keys(t).filter(r=>!e.includes(r));if(i.length>0){n.info(`\u6B63\u5728\u6E05\u7406\u5DF2\u5220\u9664\u7684\u670D\u52A1\u914D\u7F6E: ${i.join(", ")}`);for(let r of i)try{g.removeServerToolsConfig(r),n.info(`\u5DF2\u6E05\u7406\u670D\u52A1 "${r}" \u7684\u5DE5\u5177\u914D\u7F6E`)}catch(s){n.error(`\u6E05\u7406\u670D\u52A1 "${r}" \u7684\u5DE5\u5177\u914D\u7F6E\u65F6\u51FA\u9519: ${s}`)}}}catch(e){n.error(`\u6E05\u7406\u5DF2\u5220\u9664\u670D\u52A1\u65F6\u51FA\u9519: ${e}`)}}async start(){n.info("\u6B63\u5728\u542F\u52A8 MCP \u670D\u52A1\u4EE3\u7406"),this.config=ae(),await this.cleanupRemovedServers();let e=[];for(let[t,o]of Object.entries(this.config)){n.info(`\u6B63\u5728\u521D\u59CB\u5316 MCP \u5BA2\u6237\u7AEF\uFF1A${t}`);let i;if("url"in o){let r=o.url;"type"in o&&o.type==="sse"||(()=>{try{return new URL(r).pathname.endsWith("/sse")}catch{return r.includes("/sse")}})()||r.includes("modelscope.net")?r.includes("modelscope.net")?i=new w(t,o):i=new $(t,o):i=new P(t,o)}else i=new R(t,o);this.clients.set(t,i),e.push(i.start())}try{let t=await Promise.allSettled(e),o=0;for(let i=0;i<t.length;i++){let r=t[i],s=Object.keys(this.config)[i];r.status==="fulfilled"?(o++,n.info(`\u6210\u529F\u542F\u52A8 MCP \u5BA2\u6237\u7AEF\uFF1A${s}`)):(n.error(`\u542F\u52A8 MCP \u5BA2\u6237\u7AEF ${s} \u5931\u8D25\uFF1A${r.reason.message}`),this.clients.delete(s))}if(o===0)throw new Error("\u6CA1\u6709\u6210\u529F\u542F\u52A8\u4EFB\u4F55 MCP \u5BA2\u6237\u7AEF");this.buildToolMap(),this.initialized=!0,n.info(`MCP \u670D\u52A1\u4EE3\u7406\u521D\u59CB\u5316\u6210\u529F\uFF0C\u542F\u52A8\u4E86 ${o}/${Object.keys(this.config).length} \u4E2A\u5BA2\u6237\u7AEF`)}catch(t){throw n.error(`\u542F\u52A8 MCP \u5BA2\u6237\u7AEF\u5931\u8D25\uFF1A${t instanceof Error?t.message:String(t)}`),t}}buildToolMap(){this.toolMap.clear();for(let[e,t]of this.clients)for(let o of t.tools)this.toolMap.has(o.name)?n.error(`\u91CD\u590D\u7684\u5DE5\u5177\u540D\u79F0\uFF1A${o.name} (\u6765\u81EA ${e} \u548C ${this.toolMap.get(o.name)})`):this.toolMap.set(o.name,e);n.info(`\u5DF2\u6784\u5EFA\u5DE5\u5177\u6620\u5C04\uFF0C\u5171 ${this.toolMap.size} \u4E2A\u5DE5\u5177`),n.debug(`\u5DE5\u5177\u6620\u5C04\uFF1A${Array.from(this.toolMap.keys()).join(", ")}`)}getAllTools(){let e=[];for(let t of this.clients.values())e.push(...t.tools);return e}getAllServers(){let e=[];for(let[t,o]of this.clients)e.push({name:t,toolCount:o.originalTools.length,enabledToolCount:o.tools.length});return e}getServerTools(e){let t=this.clients.get(e);if(!t)throw new Error(`\u672A\u627E\u5230\u670D\u52A1\u5668 ${e}`);return t.originalTools.map(o=>({name:o.name,description:o.description||"",enabled:g.isToolEnabled(e,o.name)}))}async refreshServerTools(e){let t=this.clients.get(e);if(!t)throw new Error(`\u672A\u627E\u5230\u670D\u52A1\u5668 ${e}`);await t.refreshTools(),this.buildToolMap()}async refreshAllTools(){let e=Array.from(this.clients.values()).map(t=>t.refreshTools());await Promise.allSettled(e),this.buildToolMap()}async callTool(e,t){let o=Date.now(),i=this.toolMap.get(e);if(!i)throw new Error(`\u672A\u77E5\u7684\u5DE5\u5177\uFF1A${e}`);let r=this.clients.get(i);if(!r||!r.initialized)throw new Error(`\u5BA2\u6237\u7AEF ${i} \u4E0D\u53EF\u7528`);n.info("[\u4EE3\u7406\u5C42] \u5DE5\u5177\u8C03\u7528\u5F00\u59CB"),n.info(`[\u4EE3\u7406\u5C42] \u5DE5\u5177\u540D\u79F0: ${e}`),n.info(`[\u4EE3\u7406\u5C42] \u6240\u5C5E\u5BA2\u6237\u7AEF: ${i}`),n.info(`[\u4EE3\u7406\u5C42] \u8BF7\u6C42\u53C2\u6570: ${JSON.stringify(t,null,2)}`);try{let s=await r.callTool(e,t),l=Date.now()-o;return n.info("[\u4EE3\u7406\u5C42] \u5DE5\u5177\u8C03\u7528\u6210\u529F"),n.info(`[\u4EE3\u7406\u5C42] \u5DE5\u5177\u540D\u79F0: ${e}`),n.info(`[\u4EE3\u7406\u5C42] \u6240\u5C5E\u5BA2\u6237\u7AEF: ${i}`),n.info(`[\u4EE3\u7406\u5C42] \u6267\u884C\u8017\u65F6: ${l}ms`),n.info(`[\u4EE3\u7406\u5C42] \u5B8C\u6574\u7ED3\u679C: ${JSON.stringify(s,null,2)}`),setImmediate(()=>{let d=r.getOriginalToolName(e);d&&this.updateToolUsageStatsAsync(i,d,new Date().toISOString())}),s}catch(s){let l=Date.now()-o;throw n.error("[\u4EE3\u7406\u5C42] \u5DE5\u5177\u8C03\u7528\u5931\u8D25"),n.error(`[\u4EE3\u7406\u5C42] \u5DE5\u5177\u540D\u79F0: ${e}`),n.error(`[\u4EE3\u7406\u5C42] \u6240\u5C5E\u5BA2\u6237\u7AEF: ${i}`),n.error(`[\u4EE3\u7406\u5C42] \u6267\u884C\u8017\u65F6: ${l}ms`),n.error(`[\u4EE3\u7406\u5C42] \u9519\u8BEF\u4FE1\u606F: ${s instanceof Error?s.message:String(s)}`),s}}updateToolUsageStatsAsync(e,t,o){Promise.resolve().then(async()=>{try{await g.updateToolUsageStats(e,t,o)}catch(i){n.error(`\u5F02\u6B65\u66F4\u65B0\u5DE5\u5177\u4F7F\u7528\u7EDF\u8BA1\u5931\u8D25 (${e}/${t}): ${i instanceof Error?i.message:String(i)}`)}})}stop(){n.info("\u6B63\u5728\u505C\u6B62 MCP \u670D\u52A1\u4EE3\u7406");for(let e of this.clients.values())e.stop();this.initialized=!1}},N=class{static{c(this,"JSONRPCServer")}proxy;requestId;constructor(e){this.proxy=e,this.requestId=1}async handleMessage(e){try{let t=JSON.parse(e);if(n.debug(`\u6536\u5230\u8BF7\u6C42\uFF1A${JSON.stringify(t).substring(0,200)}...`),t.method){if(t.id!==void 0){let o=await this.handleRequest(t);return JSON.stringify(o)}return await this.handleNotification(t),null}throw new Error("\u65E0\u6548\u7684 JSON-RPC \u6D88\u606F")}catch(t){return n.error(`\u5904\u7406\u6D88\u606F\u65F6\u51FA\u9519\uFF1A${t instanceof Error?t.message:String(t)}`),JSON.stringify({jsonrpc:"2.0",id:null,error:{code:-32700,message:"\u89E3\u6790\u9519\u8BEF"}})}}async handleRequest(e){let{id:t,method:o,params:i={}}=e;try{let r;switch(o){case"initialize":r=await this.handleInitialize(i);break;case"tools/list":r=await this.handleToolsList(i);break;case"tools/call":r=await this.handleToolsCall(i);break;case"ping":r=await this.handlePing(i);break;default:throw new Error(`\u672A\u77E5\u7684\u65B9\u6CD5\uFF1A${o}`)}return{jsonrpc:"2.0",id:t,result:r}}catch(r){return n.error(`\u5904\u7406\u8BF7\u6C42 ${o} \u65F6\u51FA\u9519\uFF1A${r instanceof Error?r.message:String(r)}`),{jsonrpc:"2.0",id:t,error:{code:-32603,message:r instanceof Error?r.message:String(r)}}}}async handleNotification(e){let{method:t}=e;switch(t){case"notifications/initialized":n.info("\u5BA2\u6237\u7AEF\u53D1\u9001\u4E86\u521D\u59CB\u5316\u901A\u77E5");break;default:n.debug(`\u6536\u5230\u901A\u77E5\uFF1A${t}`);break}}async handleInitialize(e){return n.info(`\u6536\u5230\u5BA2\u6237\u7AEF\u7684\u521D\u59CB\u5316\u8BF7\u6C42\uFF1A${JSON.stringify(e.clientInfo)}`),{protocolVersion:"2024-11-05",capabilities:{tools:{listChanged:!1}},serverInfo:{name:"MCPServerProxy",version:"0.3.0"}}}async handleToolsList(e){if(!this.proxy.initialized)throw new Error("\u4EE3\u7406\u672A\u521D\u59CB\u5316");let t=this.proxy.getAllTools();return n.info(`\u8FD4\u56DE ${t.length} \u4E2A\u5DE5\u5177`),{tools:t}}async handleToolsCall(e){let{name:t,arguments:o}=e,i=Date.now();if(!t)throw new Error("\u5DE5\u5177\u540D\u79F0\u662F\u5FC5\u9700\u7684");n.info("=== \u5DE5\u5177\u8C03\u7528\u5F00\u59CB ==="),n.info(`\u5DE5\u5177\u540D\u79F0: ${t}`),n.info(`\u8BF7\u6C42\u53C2\u6570: ${JSON.stringify(o,null,2)}`),n.info(`\u8C03\u7528\u65F6\u95F4: ${new Date().toISOString()}`);try{let r=await this.proxy.callTool(t,o||{}),s=Date.now()-i;return n.info("=== \u5DE5\u5177\u8C03\u7528\u6210\u529F ==="),n.info(`\u5DE5\u5177\u540D\u79F0: ${t}`),n.info(`\u6267\u884C\u8017\u65F6: ${s}ms`),n.info(`\u5B8C\u6574\u7ED3\u679C: ${JSON.stringify(r,null,2)}`),n.info(`\u7ED3\u679C\u7C7B\u578B: ${typeof r}`),r&&typeof r=="object"&&n.info(`\u7ED3\u679C\u957F\u5EA6: ${Array.isArray(r)?r.length:Object.keys(r).length} \u9879`),r}catch(r){let s=Date.now()-i;throw n.error("=== \u5DE5\u5177\u8C03\u7528\u5931\u8D25 ==="),n.error(`\u5DE5\u5177\u540D\u79F0: ${t}`),n.error(`\u6267\u884C\u8017\u65F6: ${s}ms`),n.error(`\u9519\u8BEF\u4FE1\u606F: ${r instanceof Error?r.message:String(r)}`),n.error(`\u9519\u8BEF\u5806\u6808: ${r instanceof Error?r.stack:"\u65E0\u5806\u6808\u4FE1\u606F"}`),r}}async handlePing(e){return n.debug("\u6536\u5230 ping \u8BF7\u6C42"),{}}};function le(){return f.env.MCP_SERVER_MODE==="true"}c(le,"isMCPServerMode");async function ce(){n.info("\u6B63\u5728\u542F\u52A8 MCP \u670D\u52A1\u4EE3\u7406");let a=new z,e=new N(a),t=c(()=>{n.info("\u6B63\u5728\u5173\u95ED MCP \u670D\u52A1\u4EE3\u7406"),a.stop(),f.exit(0)},"cleanup");f.on("SIGINT",t),f.on("SIGTERM",t);try{await a.start(),le()&&(n.info("MCP proxy ready in server mode"),console.log("MCP proxy ready")),f.stdin.setEncoding("utf8");let o="";f.stdin.on("data",async i=>{o=`${o}${i}`;let r=o.split(`
|
|
7
|
-
|
|
8
|
-
`)}catch(
|
|
2
|
+
var G=Object.defineProperty;var s=(o,e)=>G(o,"name",{value:e,configurable:!0});import{dirname as ye}from"path";import p from"process";import{fileURLToPath as Te}from"url";import*as l from"fs";import*as g from"path";import u from"chalk";import f from"pino";function q(o){let e=o.getFullYear(),t=String(o.getMonth()+1).padStart(2,"0"),n=String(o.getDate()).padStart(2,"0"),i=String(o.getHours()).padStart(2,"0"),r=String(o.getMinutes()).padStart(2,"0"),c=String(o.getSeconds()).padStart(2,"0");return`${e}-${t}-${n} ${i}:${r}:${c}`}s(q,"formatDateTime");var R=class{static{s(this,"Logger")}logFilePath=null;pinoInstance;isDaemonMode;maxLogFileSize=10*1024*1024;maxLogFiles=5;constructor(){this.isDaemonMode=process.env.XIAOZHI_DAEMON==="true",this.pinoInstance=this.createPinoInstance()}createPinoInstance(){let e=[];if(!this.isDaemonMode){let t=this.createOptimizedConsoleStream();e.push({level:"debug",stream:t})}return this.logFilePath&&e.push({level:"debug",stream:f.destination({dest:this.logFilePath,sync:!1,append:!0,mkdir:!0})}),e.length===0&&e.push({level:"debug",stream:f.destination({dest:"/dev/null"})}),f({level:"debug",timestamp:f.stdTimeFunctions?.isoTime||(()=>`,"time":${Date.now()}`),formatters:{level:s((t,n)=>({level:n}),"level")},base:null,serializers:{err:f.stdSerializers?.err||(t=>t)}},f.multistream(e,{dedupe:!0}))}createOptimizedConsoleStream(){let e=new Map([[20,{name:"DEBUG",color:u.gray}],[30,{name:"INFO",color:u.blue}],[40,{name:"WARN",color:u.yellow}],[50,{name:"ERROR",color:u.red}],[60,{name:"FATAL",color:u.red}]]);return{write:s(t=>{try{let n=JSON.parse(t),i=this.formatConsoleMessageOptimized(n,e);this.safeWrite(`${i}
|
|
3
|
+
`)}catch{this.safeWrite(t)}},"write")}}safeWrite(e){try{process.stderr&&typeof process.stderr.write=="function"?process.stderr.write(e):console&&typeof console.error=="function"&&console.error(e.trim())}catch{}}formatConsoleMessageOptimized(e,t){let n=q(new Date),i=t.get(e.level)||{name:"UNKNOWN",color:s(h=>h,"color")},r=i.color(`[${i.name}]`),c=e.msg;if(e.args&&Array.isArray(e.args)){let h=e.args.map(E=>typeof E=="object"?JSON.stringify(E):String(E)).join(" ");c=`${c} ${h}`}return`[${n}] ${r} ${c}`}initLogFile(e){this.logFilePath=g.join(e,"xiaozhi.log"),this.rotateLogFileIfNeeded(),l.existsSync(this.logFilePath)||l.writeFileSync(this.logFilePath,""),this.pinoInstance=this.createPinoInstance()}enableFileLogging(e){e&&this.logFilePath&&(this.pinoInstance=this.createPinoInstance())}info(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.info(e):this.pinoInstance.info({args:t},e):this.pinoInstance.info(e,t[0]||"")}success(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.info(e):this.pinoInstance.info({args:t},e):this.pinoInstance.info(e,t[0]||"")}warn(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.warn(e):this.pinoInstance.warn({args:t},e):this.pinoInstance.warn(e,t[0]||"")}error(e,...t){if(typeof e=="string")if(t.length===0)this.pinoInstance.error(e);else{let n=t.map(i=>i instanceof Error?{message:i.message,stack:i.stack,name:i.name,cause:i.cause}:i);this.pinoInstance.error({args:n},e)}else{let n=this.enhanceErrorObject(e);this.pinoInstance.error(n,t[0]||"")}}debug(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.debug(e):this.pinoInstance.debug({args:t},e):this.pinoInstance.debug(e,t[0]||"")}log(e,...t){typeof e=="string"?t.length===0?this.pinoInstance.info(e):this.pinoInstance.info({args:t},e):this.pinoInstance.info(e,t[0]||"")}enhanceErrorObject(e){let t={...e};for(let[n,i]of Object.entries(t))i instanceof Error&&(t[n]={message:i.message,stack:i.stack,name:i.name,cause:i.cause});return t}rotateLogFileIfNeeded(){if(!(!this.logFilePath||!l.existsSync(this.logFilePath)))try{l.statSync(this.logFilePath).size>this.maxLogFileSize&&this.rotateLogFile()}catch{}}rotateLogFile(){if(this.logFilePath)try{let e=g.dirname(this.logFilePath),t=g.basename(this.logFilePath,".log");for(let i=this.maxLogFiles-1;i>=1;i--){let r=g.join(e,`${t}.${i}.log`),c=g.join(e,`${t}.${i+1}.log`);l.existsSync(r)&&(i===this.maxLogFiles-1?l.unlinkSync(r):l.renameSync(r,c))}let n=g.join(e,`${t}.1.log`);l.renameSync(this.logFilePath,n)}catch{}}cleanupOldLogs(){if(this.logFilePath)try{let e=g.dirname(this.logFilePath),t=g.basename(this.logFilePath,".log");for(let n=this.maxLogFiles+1;n<=this.maxLogFiles+10;n++){let i=g.join(e,`${t}.${n}.log`);l.existsSync(i)&&l.unlinkSync(i)}}catch{}}setLogFileOptions(e,t){this.maxLogFileSize=e,this.maxLogFiles=t}withTag(e){return this}close(){}},a=new R;import{copyFileSync as Y,existsSync as $,readFileSync as V,writeFileSync as X}from"fs";import{dirname as Z,resolve as m}from"path";import{fileURLToPath as ee}from"url";import*as S from"comment-json";import te from"dayjs";import O from"json5";import*as j from"json5-writer";function Q(o){if(!o||typeof o!="object")throw new Error("\u670D\u52A1\u914D\u7F6E\u5FC5\u987B\u662F\u4E00\u4E2A\u6709\u6548\u7684\u5BF9\u8C61");if("command"in o&&typeof o.command=="string")return"stdio";if("type"in o&&o.type==="sse")return"sse";if("type"in o&&o.type==="streamable-http"||"url"in o&&typeof o.url=="string")return"streamable-http";throw new Error("\u65E0\u6CD5\u8BC6\u522B\u7684 MCP \u670D\u52A1\u914D\u7F6E\u7C7B\u578B\u3002\u914D\u7F6E\u5FC5\u987B\u5305\u542B command \u5B57\u6BB5\uFF08stdio\uFF09\u3001type: 'sse' \u5B57\u6BB5\uFF08sse\uFF09\u6216 url \u5B57\u6BB5\uFF08streamable-http\uFF09")}s(Q,"getMcpServerCommunicationType");function I(o,e){if(!e||typeof e!="object")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684\u914D\u7F6E\u5FC5\u987B\u662F\u4E00\u4E2A\u5BF9\u8C61`};try{switch(Q(e)){case"stdio":if(!e.command||typeof e.command!="string")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7F3A\u5C11\u5FC5\u9700\u7684 command \u5B57\u6BB5\u6216\u5B57\u6BB5\u7C7B\u578B\u4E0D\u6B63\u786E`};if(!Array.isArray(e.args))return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684 args \u5B57\u6BB5\u5FC5\u987B\u662F\u6570\u7EC4`};if(e.env&&typeof e.env!="object")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684 env \u5B57\u6BB5\u5FC5\u987B\u662F\u5BF9\u8C61`};break;case"sse":if(e.type!=="sse")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684 type \u5B57\u6BB5\u5FC5\u987B\u662F "sse"`};if(!e.url||typeof e.url!="string")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7F3A\u5C11\u5FC5\u9700\u7684 url \u5B57\u6BB5\u6216\u5B57\u6BB5\u7C7B\u578B\u4E0D\u6B63\u786E`};break;case"streamable-http":if(!e.url||typeof e.url!="string")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7F3A\u5C11\u5FC5\u9700\u7684 url \u5B57\u6BB5\u6216\u5B57\u6BB5\u7C7B\u578B\u4E0D\u6B63\u786E`};if(e.type&&e.type!=="streamable-http")return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684 type \u5B57\u6BB5\u5982\u679C\u5B58\u5728\uFF0C\u5FC5\u987B\u662F "streamable-http"`};break;default:return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684\u914D\u7F6E\u7C7B\u578B\u65E0\u6CD5\u8BC6\u522B`}}return{valid:!0}}catch(t){return{valid:!1,error:`\u670D\u52A1 "${o}" \u7684\u914D\u7F6E\u65E0\u6548: ${t instanceof Error?t.message:"\u672A\u77E5\u9519\u8BEF"}`}}}s(I,"validateMcpServerConfig");var ne=Z(ee(import.meta.url)),x={heartbeatInterval:3e4,heartbeatTimeout:1e4,reconnectInterval:5e3},A=class o{static{s(this,"ConfigManager")}static instance;defaultConfigPath;config=null;currentConfigPath=null;json5Writer=null;constructor(){this.defaultConfigPath=m(ne,"xiaozhi.config.default.json")}getConfigFilePath(){let e=process.env.XIAOZHI_CONFIG_DIR||process.cwd(),t=["xiaozhi.config.json5","xiaozhi.config.jsonc","xiaozhi.config.json"];for(let n of t){let i=m(e,n);if($(i))return i}return m(e,"xiaozhi.config.json")}getConfigFileFormat(e){return e.endsWith(".json5")?"json5":e.endsWith(".jsonc")?"jsonc":"json"}static getInstance(){return o.instance||(o.instance=new o),o.instance}configExists(){let e=process.env.XIAOZHI_CONFIG_DIR||process.cwd(),t=["xiaozhi.config.json5","xiaozhi.config.jsonc","xiaozhi.config.json"];for(let n of t){let i=m(e,n);if($(i))return!0}return!1}initConfig(e="json"){if(!$(this.defaultConfigPath))throw new Error("\u9ED8\u8BA4\u914D\u7F6E\u6587\u4EF6 xiaozhi.config.default.json \u4E0D\u5B58\u5728");if(this.configExists())throw new Error("\u914D\u7F6E\u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u65E0\u9700\u91CD\u590D\u521D\u59CB\u5316");let t=process.env.XIAOZHI_CONFIG_DIR||process.cwd(),n=`xiaozhi.config.${e}`,i=m(t,n);Y(this.defaultConfigPath,i),this.config=null,this.json5Writer=null}loadConfig(){if(!this.configExists())throw new Error("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u8FD0\u884C xiaozhi init \u521D\u59CB\u5316\u914D\u7F6E");try{let e=this.getConfigFilePath();this.currentConfigPath=e;let t=this.getConfigFileFormat(e),i=V(e,"utf8").replace(/^\uFEFF/,""),r;switch(t){case"json5":r=O.parse(i),this.json5Writer=j.load(i);break;case"jsonc":r=S.parse(i);break;default:r=JSON.parse(i);break}return this.validateConfig(r),r}catch(e){throw e instanceof SyntaxError?new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF: ${e.message}`):e}}validateConfig(e){if(!e||typeof e!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1A\u6839\u5BF9\u8C61\u65E0\u6548");let t=e;if(t.mcpEndpoint===void 0||t.mcpEndpoint===null)throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u5B57\u6BB5\u65E0\u6548");if(typeof t.mcpEndpoint!="string")if(Array.isArray(t.mcpEndpoint)){if(t.mcpEndpoint.length===0)throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u6570\u7EC4\u4E0D\u80FD\u4E3A\u7A7A");for(let n of t.mcpEndpoint)if(typeof n!="string"||n.trim()==="")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u6570\u7EC4\u4E2D\u7684\u6BCF\u4E2A\u5143\u7D20\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32")}else throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpEndpoint \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u6216\u5B57\u7B26\u4E32\u6570\u7EC4");if(!t.mcpServers||typeof t.mcpServers!="object")throw new Error("\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers \u5B57\u6BB5\u65E0\u6548");for(let[n,i]of Object.entries(t.mcpServers)){if(!i||typeof i!="object")throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1AmcpServers.${n} \u65E0\u6548`);let r=I(n,i);if(!r.valid)throw new Error(`\u914D\u7F6E\u6587\u4EF6\u683C\u5F0F\u9519\u8BEF\uFF1A${r.error}`)}}getConfig(){return this.config=this.loadConfig(),JSON.parse(JSON.stringify(this.config))}getMutableConfig(){return this.config||(this.config=this.loadConfig()),this.config}getMcpEndpoint(){let e=this.getConfig();return Array.isArray(e.mcpEndpoint)?e.mcpEndpoint[0]||"":e.mcpEndpoint}getMcpEndpoints(){let e=this.getConfig();return Array.isArray(e.mcpEndpoint)?[...e.mcpEndpoint]:e.mcpEndpoint?[e.mcpEndpoint]:[]}getMcpServers(){return this.getConfig().mcpServers}getMcpServerConfig(){return this.getConfig().mcpServerConfig||{}}getServerToolsConfig(e){return this.getMcpServerConfig()[e]?.tools||{}}isToolEnabled(e,t){return this.getServerToolsConfig(e)[t]?.enable!==!1}updateMcpEndpoint(e){if(Array.isArray(e)){if(e.length===0)throw new Error("MCP \u7AEF\u70B9\u6570\u7EC4\u4E0D\u80FD\u4E3A\u7A7A");for(let n of e)if(!n||typeof n!="string")throw new Error("MCP \u7AEF\u70B9\u6570\u7EC4\u4E2D\u7684\u6BCF\u4E2A\u5143\u7D20\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32")}else if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getMutableConfig();t.mcpEndpoint=e,this.saveConfig(t)}addMcpEndpoint(e){if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getMutableConfig(),n=this.getMcpEndpoints();if(n.includes(e))throw new Error(`MCP \u7AEF\u70B9 ${e} \u5DF2\u5B58\u5728`);let i=[...n,e];t.mcpEndpoint=i,this.saveConfig(t)}removeMcpEndpoint(e){if(!e||typeof e!="string")throw new Error("MCP \u7AEF\u70B9\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getMutableConfig(),n=this.getMcpEndpoints();if(n.indexOf(e)===-1)throw new Error(`MCP \u7AEF\u70B9 ${e} \u4E0D\u5B58\u5728`);if(n.length===1)throw new Error("\u4E0D\u80FD\u5220\u9664\u6700\u540E\u4E00\u4E2A MCP \u7AEF\u70B9");let r=n.filter(c=>c!==e);t.mcpEndpoint=r,this.saveConfig(t)}updateMcpServer(e,t){if(!e||typeof e!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let n=I(e,t);if(!n.valid)throw new Error(n.error||"\u670D\u52A1\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25");let i=this.getMutableConfig();i.mcpServers[e]=t,this.saveConfig(i)}removeMcpServer(e){if(!e||typeof e!="string")throw new Error("\u670D\u52A1\u540D\u79F0\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");let t=this.getConfig();if(!t.mcpServers[e])throw new Error(`\u670D\u52A1 ${e} \u4E0D\u5B58\u5728`);let n={...t.mcpServers};delete n[e];let i={...t,mcpServers:n};this.saveConfig(i)}updateServerToolsConfig(e,t){let n=this.getMutableConfig();n.mcpServerConfig||(n.mcpServerConfig={}),Object.keys(t).length===0?delete n.mcpServerConfig[e]:n.mcpServerConfig[e]={tools:t},this.saveConfig(n)}removeServerToolsConfig(e){let n={...this.getConfig()};n.mcpServerConfig&&(delete n.mcpServerConfig[e],this.saveConfig(n))}setToolEnabled(e,t,n,i){let r=this.getMutableConfig();r.mcpServerConfig||(r.mcpServerConfig={}),r.mcpServerConfig[e]||(r.mcpServerConfig[e]={tools:{}}),r.mcpServerConfig[e].tools[t]={...r.mcpServerConfig[e].tools[t],enable:n,...i&&{description:i}},this.saveConfig(r)}saveConfig(e){try{this.validateConfig(e);let t;this.currentConfigPath?t=this.currentConfigPath:(t=this.getConfigFilePath(),this.currentConfigPath=t);let n=this.getConfigFileFormat(t),i;switch(n){case"json5":try{this.json5Writer?(this.json5Writer.write(e),i=this.json5Writer.toSource()):(console.warn("\u6CA1\u6709 json5Writer \u5B9E\u4F8B\uFF0C\u56DE\u9000\u5230\u6807\u51C6 JSON5 \u683C\u5F0F"),i=O.stringify(e,null,2))}catch(r){console.warn("\u4F7F\u7528 json5-writer \u4FDD\u5B58\u5931\u8D25\uFF0C\u56DE\u9000\u5230\u6807\u51C6 JSON5 \u683C\u5F0F:",r),i=O.stringify(e,null,2)}break;case"jsonc":try{i=S.stringify(e,null,2)}catch(r){console.warn("\u4F7F\u7528 comment-json \u4FDD\u5B58\u5931\u8D25\uFF0C\u56DE\u9000\u5230\u6807\u51C6 JSON \u683C\u5F0F:",r),i=JSON.stringify(e,null,2)}break;default:i=JSON.stringify(e,null,2);break}X(t,i,"utf8"),this.config=e,this.notifyConfigUpdate(e)}catch(t){throw new Error(`\u4FDD\u5B58\u914D\u7F6E\u5931\u8D25: ${t instanceof Error?t.message:String(t)}`)}}reloadConfig(){this.config=null,this.currentConfigPath=null,this.json5Writer=null}getConfigPath(){return this.getConfigFilePath()}getDefaultConfigPath(){return this.defaultConfigPath}getConnectionConfig(){let t=this.getConfig().connection||{};return{heartbeatInterval:t.heartbeatInterval??x.heartbeatInterval,heartbeatTimeout:t.heartbeatTimeout??x.heartbeatTimeout,reconnectInterval:t.reconnectInterval??x.reconnectInterval}}getHeartbeatInterval(){return this.getConnectionConfig().heartbeatInterval}getHeartbeatTimeout(){return this.getConnectionConfig().heartbeatTimeout}getReconnectInterval(){return this.getConnectionConfig().reconnectInterval}updateConnectionConfig(e){let t=this.getMutableConfig();t.connection||(t.connection={}),Object.assign(t.connection,e),this.saveConfig(t)}async updateToolUsageStats(e,t,n){try{let i=this.getMutableConfig();i.mcpServerConfig||(i.mcpServerConfig={}),i.mcpServerConfig[e]||(i.mcpServerConfig[e]={tools:{}}),i.mcpServerConfig[e].tools[t]||(i.mcpServerConfig[e].tools[t]={enable:!0});let r=i.mcpServerConfig[e].tools[t],c=r.usageCount||0,h=r.lastUsedTime;r.usageCount=c+1,(!h||new Date(n)>new Date(h))&&(r.lastUsedTime=te(n).format("YYYY-MM-DD HH:mm:ss")),this.saveConfig(i),a.debug(`\u5DE5\u5177\u4F7F\u7528\u7EDF\u8BA1\u5DF2\u66F4\u65B0: ${e}/${t}, \u4F7F\u7528\u6B21\u6570: ${r.usageCount}`)}catch(i){a.error(`\u66F4\u65B0\u5DE5\u5177\u4F7F\u7528\u7EDF\u8BA1\u5931\u8D25 (${e}/${t}): ${i instanceof Error?i.message:String(i)}`)}}setHeartbeatInterval(e){if(e<=0)throw new Error("\u5FC3\u8DF3\u68C0\u6D4B\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatInterval:e})}setHeartbeatTimeout(e){if(e<=0)throw new Error("\u5FC3\u8DF3\u8D85\u65F6\u65F6\u95F4\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({heartbeatTimeout:e})}setReconnectInterval(e){if(e<=0)throw new Error("\u91CD\u8FDE\u95F4\u9694\u5FC5\u987B\u5927\u4E8E0");this.updateConnectionConfig({reconnectInterval:e})}getModelScopeConfig(){return this.getConfig().modelscope||{}}getModelScopeApiKey(){return this.getModelScopeConfig().apiKey||process.env.MODELSCOPE_API_TOKEN}updateModelScopeConfig(e){let t=this.getMutableConfig();t.modelscope||(t.modelscope={}),Object.assign(t.modelscope,e),this.saveConfig(t)}setModelScopeApiKey(e){if(!e||typeof e!="string")throw new Error("API Key \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");this.updateModelScopeConfig({apiKey:e})}getWebUIConfig(){return this.getConfig().webUI||{}}getWebUIPort(){return this.getWebUIConfig().port??9999}notifyConfigUpdate(e){try{let t=global.__webServer;t&&typeof t.broadcastConfigUpdate=="function"&&(t.broadcastConfigUpdate(e),console.log("\u5DF2\u901A\u8FC7 WebSocket \u5E7F\u64AD\u914D\u7F6E\u66F4\u65B0"))}catch(t){console.warn("\u901A\u77E5 Web \u754C\u9762\u914D\u7F6E\u66F4\u65B0\u5931\u8D25:",t instanceof Error?t.message:String(t))}}updateWebUIConfig(e){let t=this.getMutableConfig();t.webUI||(t.webUI={}),Object.assign(t.webUI,e),this.saveConfig(t)}setWebUIPort(e){if(!Number.isInteger(e)||e<=0||e>65535)throw new Error("\u7AEF\u53E3\u53F7\u5FC5\u987B\u662F 1-65535 \u4E4B\u95F4\u7684\u6574\u6570");this.updateWebUIConfig({port:e})}},C=A.getInstance();import{randomUUID as ie}from"crypto";import D from"express";var d=class{static{s(this,"TransportAdapter")}logger;messageHandler;connectionId;config;state="disconnected";constructor(e,t){this.messageHandler=e,this.config=t,this.connectionId=this.generateConnectionId(),this.logger=a}async handleIncomingMessage(e){try{this.logger.debug(`\u5904\u7406\u63A5\u6536\u5230\u7684\u6D88\u606F: ${e.method}`,e);let t=await this.messageHandler.handleMessage(e);this.logger.debug("\u53D1\u9001\u54CD\u5E94\u6D88\u606F:",t),await this.sendMessage(t)}catch(t){this.logger.error(`\u5904\u7406\u6D88\u606F\u65F6\u51FA\u9519: ${e.method}`,t);let n=this.createErrorResponse(t,e.id);await this.sendMessage(n)}}createErrorResponse(e,t){let n=-32603;return e.message.includes("\u672A\u627E\u5230\u5DE5\u5177")||e.message.includes("\u672A\u77E5\u7684\u65B9\u6CD5")?n=-32601:(e.message.includes("\u53C2\u6570")||e.message.includes("\u4E0D\u80FD\u4E3A\u7A7A"))&&(n=-32602),{jsonrpc:"2.0",error:{code:n,message:e.message,data:{stack:e.stack}},id:t||null}}generateConnectionId(){let e=Date.now(),t=Math.random().toString(36).substr(2,9);return`${this.config.name}_${e}_${t}`}getConnectionId(){return this.connectionId}getState(){return this.state}setState(e){let t=this.state;this.state=e,t!==e&&(this.logger.info(`\u8FDE\u63A5\u72B6\u6001\u53D8\u66F4: ${t} -> ${e}`),this.onStateChange(t,e))}onStateChange(e,t){}getConfig(){return{...this.config}}getMessageHandler(){return this.messageHandler}parseMessage(e){try{let t=JSON.parse(e.trim());return!t.jsonrpc||t.jsonrpc!=="2.0"?(this.logger.warn("\u6536\u5230\u975E JSON-RPC 2.0 \u683C\u5F0F\u7684\u6D88\u606F",t),null):t.method?t:(this.logger.warn("\u6536\u5230\u6CA1\u6709 method \u5B57\u6BB5\u7684\u6D88\u606F",t),null)}catch(t){return this.logger.error("\u89E3\u6790 JSON \u6D88\u606F\u5931\u8D25",{data:e,error:t}),null}}serializeMessage(e){try{return JSON.stringify(e)}catch(t){this.logger.error("\u5E8F\u5217\u5316\u6D88\u606F\u5931\u8D25",{message:e,error:t});let n=t instanceof Error?t.message:String(t);throw new Error(`\u6D88\u606F\u5E8F\u5217\u5316\u5931\u8D25: ${n}`)}}validateMessage(e){return!(!e||typeof e!="object"||e.jsonrpc!=="2.0"||e.method&&typeof e.method!="string"||!e.method&&!e.result&&!e.error)}createTimeoutPromise(e,t){return Promise.race([e,new Promise((n,i)=>{setTimeout(()=>{i(new Error(`\u64CD\u4F5C\u8D85\u65F6: ${t}ms`))},t)})])}};var v=class extends d{static{s(this,"HTTPAdapter")}app;server=null;clients=new Map;port;host;enableSSE;enableRPC;corsOrigin;maxClients;constructor(e,t={name:"http"}){super(e,t),this.port=t.port||3e3,this.host=t.host||"0.0.0.0",this.enableSSE=t.enableSSE!==!1,this.enableRPC=t.enableRPC!==!1,this.corsOrigin=t.corsOrigin||"*",this.maxClients=t.maxClients!==void 0?t.maxClients:100,this.app=D(),this.setupMiddleware()}async initialize(){this.logger.info("\u521D\u59CB\u5316 HTTP \u9002\u914D\u5668");try{this.setupRoutes(),this.setState("connecting"),this.logger.info("HTTP \u9002\u914D\u5668\u521D\u59CB\u5316\u5B8C\u6210")}catch(e){throw this.logger.error("HTTP \u9002\u914D\u5668\u521D\u59CB\u5316\u5931\u8D25",e),this.setState("error"),e}}async start(){if(this.server){this.logger.warn("HTTP \u670D\u52A1\u5668\u5DF2\u5728\u8FD0\u884C");return}return this.logger.info(`\u542F\u52A8 HTTP \u670D\u52A1\u5668\u5728 ${this.host}:${this.port}`),new Promise((e,t)=>{this.server=this.app.listen(this.port,this.host,()=>{this.setState("connected"),this.logger.info("HTTP \u9002\u914D\u5668\u542F\u52A8\u6210\u529F"),this.logger.info(`- RPC \u7AEF\u70B9: http://${this.host}:${this.port}/rpc`),this.enableSSE&&(this.logger.info(`- SSE \u7AEF\u70B9: http://${this.host}:${this.port}/sse`),this.logger.info(`- \u6D88\u606F\u7AEF\u70B9: http://${this.host}:${this.port}/messages`)),e()}),this.server?.on("error",n=>{this.logger.error("HTTP \u670D\u52A1\u5668\u9519\u8BEF",n),this.setState("error"),t(n)})})}async stop(){if(this.server)return this.logger.info("\u505C\u6B62 HTTP \u670D\u52A1\u5668"),new Promise(e=>{for(let t of this.clients.values())t.response.end();this.clients.clear(),this.server.close(()=>{this.server=null,this.setState("disconnected"),this.logger.info("HTTP \u670D\u52A1\u5668\u5DF2\u505C\u6B62"),e()})})}async sendMessage(e){this.clients.size>0&&this.broadcastToClients(e)}setupMiddleware(){this.app.use(D.json({limit:"10mb"})),this.app.use(D.urlencoded({extended:!0})),this.app.use((e,t,n)=>{t.header("Access-Control-Allow-Origin",this.corsOrigin),t.header("Access-Control-Allow-Methods","GET, POST, OPTIONS"),t.header("Access-Control-Allow-Headers","Content-Type, Accept"),t.header("Cache-Control","no-cache"),n()}),this.app.use((e,t,n)=>{this.logger.debug(`${e.method} ${e.path}`,{query:e.query,headers:e.headers}),n()})}setupRoutes(){this.enableSSE&&(this.app.get("/sse",this.handleSSE.bind(this)),this.app.post("/messages",this.handleMessages.bind(this))),this.enableRPC&&this.app.post("/rpc",this.handleRPC.bind(this)),this.app.get("/status",this.handleStatus.bind(this)),this.app.get("/health",this.handleHealth.bind(this))}handleSSE(e,t){if(this.clients.size>=this.maxClients){t.status(503).json({error:"\u670D\u52A1\u5668\u7E41\u5FD9\uFF0C\u5BA2\u6237\u7AEF\u8FDE\u63A5\u6570\u5DF2\u8FBE\u4E0A\u9650",maxClients:this.maxClients});return}let n=Date.now().toString(),i=ie();t.setHeader("Content-Type","text/event-stream"),t.setHeader("Cache-Control","no-cache, no-transform"),t.setHeader("Connection","keep-alive"),t.setHeader("X-Accel-Buffering","no");let r={id:n,sessionId:i,response:t,connectedAt:new Date};this.clients.set(i,r),this.logger.info(`SSE \u5BA2\u6237\u7AEF\u5DF2\u8FDE\u63A5: ${n} (\u4F1A\u8BDD: ${i})`),t.write(`event: endpoint
|
|
4
|
+
data: /messages?sessionId=${i}
|
|
5
|
+
|
|
6
|
+
`),e.on("close",()=>{this.clients.delete(i),this.logger.info(`SSE \u5BA2\u6237\u7AEF\u5DF2\u65AD\u5F00\u8FDE\u63A5: ${n} (\u4F1A\u8BDD: ${i})`)}),e.on("error",c=>{this.logger.error(`SSE \u5BA2\u6237\u7AEF\u8FDE\u63A5\u9519\u8BEF: ${n}`,c),this.clients.delete(i)})}async handleMessages(e,t){try{let n=e.query.sessionId,i=e.body;if(this.logger.debug(`\u6536\u5230 SSE \u6D88\u606F (\u4F1A\u8BDD: ${n}):`,i),!n||!this.clients.has(n)){t.status(400).json({jsonrpc:"2.0",error:{code:-32600,message:"\u65E0\u6548\u6216\u7F3A\u5C11 sessionId"},id:i.id});return}let r=await this.messageHandler.handleMessage(i);this.logger.debug("SSE \u6D88\u606F\u5904\u7406\u54CD\u5E94:",r);let c=this.clients.get(n);c&&this.sendToClient(c,r),t.status(202).send()}catch(n){this.logger.error("\u5904\u7406 SSE \u6D88\u606F\u65F6\u51FA\u9519",n),t.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:n.message}})}}async handleRPC(e,t){try{let n=e.body;this.logger.debug("\u6536\u5230 RPC \u6D88\u606F:",n);let i=await this.messageHandler.handleMessage(n);t.json(i)}catch(n){this.logger.error("\u5904\u7406 RPC \u6D88\u606F\u65F6\u51FA\u9519",n),t.status(500).json({jsonrpc:"2.0",error:{code:-32603,message:n.message},id:e.body?.id||null})}}handleStatus(e,t){t.json({status:"ok",mode:"mcp-server",serviceManager:"running",clients:this.clients.size,tools:0,maxClients:this.maxClients,enableSSE:this.enableSSE,enableRPC:this.enableRPC,uptime:process.uptime()})}handleHealth(e,t){t.json({status:"ok",mode:"mcp-server",timestamp:new Date().toISOString()})}sendToClient(e,t){try{let n=this.serializeMessage(t);e.response.write(`data: ${n}
|
|
7
|
+
|
|
8
|
+
`),this.logger.debug(`\u6D88\u606F\u5DF2\u53D1\u9001\u5230\u5BA2\u6237\u7AEF ${e.id}`,{sessionId:e.sessionId,messageId:t.id})}catch(n){this.logger.error(`\u5411\u5BA2\u6237\u7AEF ${e.id} \u53D1\u9001\u6D88\u606F\u5931\u8D25`,n),this.clients.delete(e.sessionId)}}broadcastToClients(e){for(let t of this.clients.values())this.sendToClient(t,e)}getStatus(){return{isRunning:this.server!==null,port:this.port,host:this.host,clientCount:this.clients.size,maxClients:this.maxClients,enableSSE:this.enableSSE,enableRPC:this.enableRPC,connectionId:this.connectionId,state:this.state}}getClients(){return Array.from(this.clients.values()).map(e=>({id:e.id,sessionId:e.sessionId,connectedAt:e.connectedAt}))}};var b=class extends d{static{s(this,"StdioAdapter")}messageBuffer="";isRunning=!1;encoding;bufferSize;constructor(e,t={name:"stdio"}){super(e,t),this.encoding=t.encoding||"utf8",this.bufferSize=t.bufferSize||1024*1024}async initialize(){this.logger.info("\u521D\u59CB\u5316 Stdio \u9002\u914D\u5668");try{process.stdin.setEncoding(this.encoding),this.setupProcessHandlers(),this.setState("connecting"),this.logger.info("Stdio \u9002\u914D\u5668\u521D\u59CB\u5316\u5B8C\u6210")}catch(e){throw this.logger.error("Stdio \u9002\u914D\u5668\u521D\u59CB\u5316\u5931\u8D25",e),this.setState("error"),e}}async start(){if(this.isRunning){this.logger.warn("Stdio \u9002\u914D\u5668\u5DF2\u5728\u8FD0\u884C");return}this.logger.info("\u542F\u52A8 Stdio \u9002\u914D\u5668");try{this.isRunning=!0,this.setupStdioHandlers(),this.setState("connected"),this.logger.info("Stdio \u9002\u914D\u5668\u542F\u52A8\u6210\u529F\uFF0C\u7B49\u5F85\u6D88\u606F...")}catch(e){throw this.logger.error("\u542F\u52A8 Stdio \u9002\u914D\u5668\u5931\u8D25",e),this.setState("error"),this.isRunning=!1,e}}async stop(){if(this.isRunning){this.logger.info("\u505C\u6B62 Stdio \u9002\u914D\u5668");try{this.isRunning=!1,this.removeStdioHandlers(),this.setState("disconnected"),this.logger.info("Stdio \u9002\u914D\u5668\u5DF2\u505C\u6B62")}catch(e){throw this.logger.error("\u505C\u6B62 Stdio \u9002\u914D\u5668\u65F6\u51FA\u9519",e),e}}}async sendMessage(e){try{let t=this.serializeMessage(e);process.stdout.write(`${t}
|
|
9
|
+
`),this.logger.debug("\u6D88\u606F\u5DF2\u53D1\u9001\u5230 stdout",{messageId:e.id,method:"method"in e?e.method:"response"})}catch(t){throw this.logger.error("\u53D1\u9001\u6D88\u606F\u5931\u8D25",t),t}}setupStdioHandlers(){process.stdin.on("data",this.handleStdinData.bind(this)),process.stdin.on("end",this.handleStdinEnd.bind(this)),process.stdin.on("error",this.handleStdinError.bind(this))}removeStdioHandlers(){process.stdin.removeListener("data",this.handleStdinData.bind(this)),process.stdin.removeListener("end",this.handleStdinEnd.bind(this)),process.stdin.removeListener("error",this.handleStdinError.bind(this))}async handleStdinData(e){try{if(this.messageBuffer+=e.toString(),this.messageBuffer.length>this.bufferSize){this.logger.warn(`\u6D88\u606F\u7F13\u51B2\u533A\u8D85\u8FC7\u9650\u5236 (${this.bufferSize} bytes)\uFF0C\u6E05\u7A7A\u7F13\u51B2\u533A`),this.messageBuffer="";return}let t=this.messageBuffer.split(`
|
|
10
|
+
`);this.messageBuffer=t.pop()||"";for(let n of t){let i=n.trim();i&&await this.processMessageLine(i)}}catch(t){this.logger.error("\u5904\u7406 stdin \u6570\u636E\u65F6\u51FA\u9519",t)}}async processMessageLine(e){try{this.logger.debug(`\u5904\u7406\u6D88\u606F\u884C: ${e.substring(0,200)}...`);let t=this.parseMessage(e);t&&await this.handleIncomingMessage(t)}catch(t){this.logger.error(`\u5904\u7406\u6D88\u606F\u884C\u5931\u8D25: ${e.substring(0,100)}...`,t);let n={jsonrpc:"2.0",error:{code:-32700,message:"\u89E3\u6790\u9519\u8BEF",data:{originalLine:e.substring(0,100)}},id:null};await this.sendMessage(n)}}handleStdinEnd(){this.logger.info("\u6807\u51C6\u8F93\u5165\u5DF2\u5173\u95ED\uFF0C\u505C\u6B62\u9002\u914D\u5668"),this.stop().catch(e=>{this.logger.error("\u505C\u6B62\u9002\u914D\u5668\u65F6\u51FA\u9519",e)})}handleStdinError(e){this.logger.error("\u6807\u51C6\u8F93\u5165\u9519\u8BEF",e),this.setState("error")}setupProcessHandlers(){let e=s(()=>{this.logger.info("\u6536\u5230\u9000\u51FA\u4FE1\u53F7\uFF0C\u6E05\u7406\u8D44\u6E90"),this.stop().finally(()=>{process.exit(0)})},"handleExit");process.on("SIGINT",e),process.on("SIGTERM",e),process.on("uncaughtException",t=>{this.logger.error("\u672A\u6355\u83B7\u7684\u5F02\u5E38",t),this.setState("error")}),process.on("unhandledRejection",(t,n)=>{this.logger.error("\u672A\u5904\u7406\u7684 Promise \u62D2\u7EDD",{reason:t,promise:n})})}getStatus(){return{isRunning:this.isRunning,bufferSize:this.messageBuffer.length,encoding:this.encoding,connectionId:this.connectionId,state:this.state}}clearBuffer(){this.messageBuffer="",this.logger.debug("\u6D88\u606F\u7F13\u51B2\u533A\u5DF2\u6E05\u7A7A")}};import L,{WebSocketServer as oe}from"ws";var M=class extends d{static{s(this,"WebSocketAdapter")}ws=null;wsServer=null;endpointUrl;mode;wsState="disconnected";reconnectOptions;reconnectState;connectionTimeout=null;compression;batchQueue=[];batchTimer=null;batchSize;batchTimeout;connections=new Map;maxConnections;constructor(e,t){super(e,t),this.endpointUrl=t.endpointUrl,this.mode=t.mode||"client",this.compression=t.compression||!1,this.batchSize=t.batchSize||10,this.batchTimeout=t.batchTimeout||100,this.maxConnections=t.maxConnections||100,this.reconnectOptions={enabled:!0,maxAttempts:5,initialInterval:1e3,maxInterval:3e4,backoffStrategy:"exponential",backoffMultiplier:1.5,timeout:1e4,jitter:!0,...t.reconnect},this.reconnectState={attempts:0,nextInterval:this.reconnectOptions.initialInterval,timer:null,lastError:null,isManualDisconnect:!1}}async initialize(){this.logger.info(`\u521D\u59CB\u5316 WebSocket \u9002\u914D\u5668 (${this.mode} \u6A21\u5F0F)`);try{this.setState("connecting"),this.wsState="connecting",this.mode==="client"?await this.initializeClient():await this.initializeServer(),this.logger.info("WebSocket \u9002\u914D\u5668\u521D\u59CB\u5316\u5B8C\u6210")}catch(e){throw this.logger.error("WebSocket \u9002\u914D\u5668\u521D\u59CB\u5316\u5931\u8D25",e),this.setState("error"),this.wsState="failed",e}}async initializeClient(){return new Promise((e,t)=>{this.connectionTimeout=setTimeout(()=>{let n=new Error(`\u8FDE\u63A5\u8D85\u65F6 (${this.reconnectOptions.timeout}ms)`);this.handleConnectionError(n),t(n)},this.reconnectOptions.timeout),this.ws=new L(this.endpointUrl),this.compression,this.ws.on("open",()=>{this.handleConnectionSuccess(),e()}),this.ws.on("message",n=>{this.handleIncomingData(n)}),this.ws.on("close",(n,i)=>{this.handleConnectionClose(n,i.toString())}),this.ws.on("error",n=>{this.handleConnectionError(n),t(n)})})}async initializeServer(){return new Promise((e,t)=>{try{let n=new URL(this.endpointUrl),i=Number.parseInt(n.port)||8080;this.wsServer=new oe({port:i,perMessageDeflate:this.compression}),this.wsServer.on("connection",(r,c)=>{this.handleNewConnection(r,c)}),this.wsServer.on("error",r=>{this.logger.error("WebSocket \u670D\u52A1\u5668\u9519\u8BEF",r),t(r)}),this.logger.info(`WebSocket \u670D\u52A1\u5668\u76D1\u542C\u7AEF\u53E3 ${i}`),e()}catch(n){t(n)}})}async start(){if(this.wsState==="connected"){this.logger.warn("WebSocket \u9002\u914D\u5668\u5DF2\u542F\u52A8");return}this.logger.info("\u542F\u52A8 WebSocket \u9002\u914D\u5668");try{this.setState("connected"),this.wsState="connected",this.logger.info("WebSocket \u9002\u914D\u5668\u542F\u52A8\u6210\u529F")}catch(e){throw this.logger.error("\u542F\u52A8 WebSocket \u9002\u914D\u5668\u5931\u8D25",e),this.setState("error"),this.wsState="failed",e}}async stop(){this.logger.info("\u505C\u6B62 WebSocket \u9002\u914D\u5668");try{this.reconnectState.isManualDisconnect=!0,this.reconnectState.timer&&(clearTimeout(this.reconnectState.timer),this.reconnectState.timer=null),this.batchTimer&&(clearTimeout(this.batchTimer),this.batchTimer=null),await this.flushBatchQueue(),this.ws&&(this.ws.close(),this.ws=null),this.wsServer&&(this.wsServer.close(),this.wsServer=null);for(let[e,t]of this.connections)t.close();this.connections.clear(),this.setState("disconnected"),this.wsState="disconnected",this.logger.info("WebSocket \u9002\u914D\u5668\u5DF2\u505C\u6B62")}catch(e){throw this.logger.error("\u505C\u6B62 WebSocket \u9002\u914D\u5668\u65F6\u51FA\u9519",e),e}}async sendMessage(e){if(this.wsState!=="connected")throw new Error(`WebSocket \u672A\u8FDE\u63A5 (\u72B6\u6001: ${this.wsState})`);return this.batchSize>1?this.addToBatchQueue(e):this.sendMessageDirect(e)}async sendMessageDirect(e){try{let t=this.serializeMessage(e);if(this.mode==="client"&&this.ws)this.ws.send(t);else if(this.mode==="server")for(let n of this.connections.values())n.readyState===L.OPEN&&n.send(t);this.logger.debug("\u6D88\u606F\u5DF2\u53D1\u9001",{messageId:e.id,method:"method"in e?e.method:"response"})}catch(t){throw this.logger.error("\u53D1\u9001\u6D88\u606F\u5931\u8D25",t),t}}async addToBatchQueue(e){return new Promise((t,n)=>{this.batchQueue.push({message:e,timestamp:Date.now(),resolve:t,reject:n}),this.batchQueue.length>=this.batchSize?this.flushBatchQueue():this.batchTimer||(this.batchTimer=setTimeout(()=>{this.flushBatchQueue()},this.batchTimeout))})}async flushBatchQueue(){if(this.batchQueue.length===0)return;this.batchTimer&&(clearTimeout(this.batchTimer),this.batchTimer=null);let e=this.batchQueue.splice(0);try{let n={jsonrpc:"2.0",method:"batch",params:{messages:e.map(i=>i.message)},id:`batch_${Date.now()}`};await this.sendMessageDirect(n);for(let i of e)i.resolve();this.logger.debug(`\u6279\u5904\u7406\u53D1\u9001 ${e.length} \u6761\u6D88\u606F`)}catch(t){for(let n of e)n.reject(t);this.logger.error("\u6279\u5904\u7406\u53D1\u9001\u5931\u8D25",t)}}async handleIncomingData(e){try{let t=e.toString(),n=this.parseMessage(t);if(n)if(n.method==="batch"&&n.params?.messages)for(let i of n.params.messages)await this.handleIncomingMessage(i);else await this.handleIncomingMessage(n)}catch(t){this.logger.error("\u5904\u7406\u63A5\u6536\u6570\u636E\u5931\u8D25",t)}}handleConnectionSuccess(){this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.setState("connected"),this.wsState="connected",this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.lastError=null,this.logger.info("WebSocket \u8FDE\u63A5\u5DF2\u5EFA\u7ACB")}handleConnectionError(e){this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.reconnectState.lastError=e,this.logger.error("WebSocket \u8FDE\u63A5\u9519\u8BEF",e),this.setState("error"),this.wsState="failed",this.cleanupConnection()}handleConnectionClose(e,t){this.setState("disconnected"),this.wsState="disconnected",this.logger.info(`WebSocket \u8FDE\u63A5\u5DF2\u5173\u95ED (\u4EE3\u7801: ${e}, \u539F\u56E0: ${t})`),!this.reconnectState.isManualDisconnect&&(this.shouldReconnect()?this.scheduleReconnect():(this.wsState="failed",this.logger.warn(`\u5DF2\u8FBE\u5230\u6700\u5927\u91CD\u8FDE\u6B21\u6570 (${this.reconnectOptions.maxAttempts})\uFF0C\u505C\u6B62\u91CD\u8FDE`)))}handleNewConnection(e,t){if(this.connections.size>=this.maxConnections){this.logger.warn("\u8FBE\u5230\u6700\u5927\u8FDE\u63A5\u6570\u9650\u5236\uFF0C\u62D2\u7EDD\u65B0\u8FDE\u63A5"),e.close(1013,"\u670D\u52A1\u5668\u7E41\u5FD9");return}let n=`${this.getConnectionId()}_${this.connections.size}`;this.connections.set(n,e),this.logger.info(`\u65B0 WebSocket \u8FDE\u63A5: ${n}`),e.on("message",i=>{this.handleIncomingData(i)}),e.on("close",()=>{this.connections.delete(n),this.logger.info(`WebSocket \u8FDE\u63A5\u5DF2\u65AD\u5F00: ${n}`)}),e.on("error",i=>{this.logger.error(`WebSocket \u8FDE\u63A5\u9519\u8BEF ${n}:`,i),this.connections.delete(n)})}cleanupConnection(){this.ws&&(this.ws.removeAllListeners(),this.ws=null)}shouldReconnect(){return this.reconnectOptions.enabled&&this.reconnectState.attempts<this.reconnectOptions.maxAttempts&&!this.reconnectState.isManualDisconnect}scheduleReconnect(){this.wsState="reconnecting",this.reconnectState.attempts++;let e=this.calculateReconnectInterval();this.reconnectOptions.jitter&&(e+=Math.random()*1e3),this.logger.info(`\u5B89\u6392\u91CD\u8FDE (\u7B2C ${this.reconnectState.attempts} \u6B21\uFF0C${e}ms \u540E)`),this.reconnectState.timer=setTimeout(async()=>{try{await this.initializeClient()}catch(t){this.logger.error("\u91CD\u8FDE\u5931\u8D25",t),this.shouldReconnect()?this.scheduleReconnect():this.wsState="failed"}},e)}calculateReconnectInterval(){let{backoffStrategy:e,initialInterval:t,maxInterval:n,backoffMultiplier:i}=this.reconnectOptions,r=this.reconnectState.attempts,c;switch(e){case"linear":c=t+r*1e3;break;case"exponential":c=t*i**r;break;default:c=t;break}return Math.min(c,n)}getStatus(){return{wsState:this.wsState,connectionState:this.state,mode:this.mode,endpointUrl:this.endpointUrl,connectionCount:this.connections.size,reconnectAttempts:this.reconnectState.attempts,batchQueueSize:this.batchQueue.length,compression:this.compression}}async forceReconnect(){if(this.mode!=="client")throw new Error("\u53EA\u6709\u5BA2\u6237\u7AEF\u6A21\u5F0F\u652F\u6301\u91CD\u8FDE");this.logger.info("\u5F3A\u5236\u91CD\u8FDE"),this.reconnectState.attempts=0,this.reconnectState.isManualDisconnect=!1,this.ws&&this.ws.close(),await this.initializeClient()}};import{EventEmitter as W}from"events";import{Client as be}from"@modelcontextprotocol/sdk/client/index.js";import{SSEClientTransport as z}from"@modelcontextprotocol/sdk/client/sse.js";import{StdioClientTransport as re}from"@modelcontextprotocol/sdk/client/stdio.js";import{StreamableHTTPClientTransport as se}from"@modelcontextprotocol/sdk/client/streamableHttp.js";import{EventSource as ae}from"eventsource";typeof global<"u"&&!global.EventSource&&(global.EventSource=ae);function ce(){return a}s(ce,"getLogger");function le(o){switch(ce().info(`[TransportFactory] \u521B\u5EFA ${o.type} transport for ${o.name}`),o.type){case"stdio":return ge(o);case"sse":return he(o);case"modelscope-sse":return pe(o);case"streamable-http":return de(o);default:throw new Error(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${o.type}`)}}s(le,"createTransport");function ge(o){if(!o.command)throw new Error("stdio transport \u9700\u8981 command \u914D\u7F6E");return new re({command:o.command,args:o.args||[]})}s(ge,"createStdioTransport");function he(o){if(!o.url)throw new Error("SSE transport \u9700\u8981 URL \u914D\u7F6E");let e=new URL(o.url),t=fe(o);return new z(e,t)}s(he,"createSSETransport");function pe(o){if(!o.url)throw new Error("ModelScope SSE transport \u9700\u8981 URL \u914D\u7F6E");if(!o.apiKey)throw new Error("ModelScope SSE transport \u9700\u8981 apiKey \u914D\u7F6E");let e=new URL(o.url),t=ue(o);return new z(e,t)}s(pe,"createModelScopeSSETransport");function de(o){if(!o.url)throw new Error("StreamableHTTP transport \u9700\u8981 URL \u914D\u7F6E");let e=new URL(o.url),t=me(o);return new se(e,t)}s(de,"createStreamableHTTPTransport");function fe(o){let e={};return o.apiKey?e.headers={Authorization:`Bearer ${o.apiKey}`,...o.headers}:o.headers&&(e.headers=o.headers),e}s(fe,"createSSEOptions");function ue(o){let e=o.apiKey;return o.customSSEOptions?o.customSSEOptions:{eventSourceInit:{fetch:s(async(t,n)=>{let i={...n?.headers,Authorization:`Bearer ${e}`};return fetch(t,{...n,headers:i})},"fetch")},requestInit:{headers:{Authorization:`Bearer ${e}`,...o.headers}}}}s(ue,"createModelScopeSSEOptions");function me(o){let e={};return o.apiKey?e.headers={Authorization:`Bearer ${o.apiKey}`,...o.headers}:o.headers&&(e.headers=o.headers),e}s(me,"createStreamableHTTPOptions");function Ce(o){if(!o.name||typeof o.name!="string")throw new Error("\u914D\u7F6E\u5FC5\u987B\u5305\u542B\u6709\u6548\u7684 name \u5B57\u6BB5");if(!o.type)throw new Error("\u914D\u7F6E\u5FC5\u987B\u5305\u542B type \u5B57\u6BB5");switch(o.type){case"stdio":if(!o.command)throw new Error("stdio \u7C7B\u578B\u9700\u8981 command \u5B57\u6BB5");break;case"sse":case"streamable-http":if(!o.url)throw new Error(`${o.type} \u7C7B\u578B\u9700\u8981 url \u5B57\u6BB5`);break;case"modelscope-sse":if(!o.url)throw new Error("modelscope-sse \u7C7B\u578B\u9700\u8981 url \u5B57\u6BB5");if(!o.apiKey)throw new Error("modelscope-sse \u7C7B\u578B\u9700\u8981 apiKey \u5B57\u6BB5\u3002\u8BF7\u5728\u914D\u7F6E\u6587\u4EF6\u4E2D\u8BBE\u7F6E modelscope.apiKey \u6216\u786E\u4FDD\u670D\u52A1\u914D\u7F6E\u5305\u542B apiKey");break;default:throw new Error(`\u4E0D\u652F\u6301\u7684\u4F20\u8F93\u7C7B\u578B: ${o.type}`)}}s(Ce,"validateConfig");function Se(){return["stdio","sse","modelscope-sse","streamable-http"]}s(Se,"getSupportedTypes");var k={create:le,validateConfig:Ce,getSupportedTypes:Se};var P=class{static{s(this,"MCPService")}config;client=null;transport=null;tools=new Map;connectionState="disconnected";reconnectOptions;reconnectState;logger;connectionTimeout=null;initialized=!1;pingOptions;pingTimer=null;pingFailureCount=0;lastPingTime=null;isPinging=!1;constructor(e,t){this.config=e,this.logger=a,this.validateConfig(),this.reconnectOptions={enabled:!0,maxAttempts:10,initialInterval:3e3,maxInterval:3e4,backoffStrategy:"exponential",backoffMultiplier:1.5,timeout:1e4,jitter:!0,...t?.reconnect,...e.reconnect},this.pingOptions={enabled:!0,interval:3e4,timeout:5e3,maxFailures:3,startDelay:5e3,...e.ping},this.reconnectState={attempts:0,nextInterval:this.reconnectOptions.initialInterval,timer:null,lastError:null,isManualDisconnect:!1}}logWithTag(e,t,...n){let i=`[MCP-${this.config.name}] ${t}`;this.logger[e](i,...n)}validateConfig(){k.validateConfig(this.config)}async connect(){if(this.connectionState==="connecting")throw new Error("\u8FDE\u63A5\u6B63\u5728\u8FDB\u884C\u4E2D\uFF0C\u8BF7\u7B49\u5F85\u8FDE\u63A5\u5B8C\u6210");return this.cleanupConnection(),this.reconnectState.isManualDisconnect=!1,this.attemptConnection()}async attemptConnection(){return this.connectionState="connecting",this.logWithTag("info",`\u6B63\u5728\u8FDE\u63A5 MCP \u670D\u52A1: ${this.config.name} (\u5C1D\u8BD5 ${this.reconnectState.attempts+1}/${this.reconnectOptions.maxAttempts})`),new Promise((e,t)=>{this.connectionTimeout=setTimeout(()=>{let n=new Error(`\u8FDE\u63A5\u8D85\u65F6 (${this.reconnectOptions.timeout}ms)`);this.handleConnectionError(n),t(n)},this.reconnectOptions.timeout);try{this.client=new be({name:`xiaozhi-${this.config.name}-client`,version:"1.0.0"},{capabilities:{tools:{}}}),this.transport=k.create(this.config),this.client.connect(this.transport).then(async()=>{this.handleConnectionSuccess(),await this.refreshTools(),e()}).catch(n=>{this.handleConnectionError(n),t(n)})}catch(n){this.handleConnectionError(n),t(n)}})}handleConnectionSuccess(){this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.connectionState="connected",this.initialized=!0,this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.lastError=null,this.resetPingState(),this.logWithTag("info",`MCP \u670D\u52A1 ${this.config.name} \u8FDE\u63A5\u5DF2\u5EFA\u7ACB`),this.startPingMonitoring()}handleConnectionError(e){this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.reconnectState.lastError=e,this.logger.error(`MCP \u670D\u52A1 ${this.config.name} \u8FDE\u63A5\u9519\u8BEF:`,e.message),this.cleanupConnection(),this.shouldReconnect()?this.scheduleReconnect():(this.connectionState="failed",this.logger.warn(`${this.config.name} \u5DF2\u8FBE\u5230\u6700\u5927\u91CD\u8FDE\u6B21\u6570 (${this.reconnectOptions.maxAttempts})\uFF0C\u505C\u6B62\u91CD\u8FDE`))}shouldReconnect(){return this.reconnectOptions.enabled&&this.reconnectState.attempts<this.reconnectOptions.maxAttempts&&!this.reconnectState.isManualDisconnect}scheduleReconnect(){this.connectionState="reconnecting",this.reconnectState.attempts++,this.calculateNextInterval(),this.logger.info(`${this.config.name} \u5C06\u5728 ${this.reconnectState.nextInterval}ms \u540E\u8FDB\u884C\u7B2C ${this.reconnectState.attempts} \u6B21\u91CD\u8FDE`),this.reconnectState.timer&&clearTimeout(this.reconnectState.timer),this.reconnectState.timer=setTimeout(async()=>{try{await this.attemptConnection()}catch{}},this.reconnectState.nextInterval)}calculateNextInterval(){let e;switch(this.reconnectOptions.backoffStrategy){case"fixed":e=this.reconnectOptions.initialInterval;break;case"linear":e=this.reconnectOptions.initialInterval+this.reconnectState.attempts*this.reconnectOptions.backoffMultiplier*1e3;break;case"exponential":e=this.reconnectOptions.initialInterval*this.reconnectOptions.backoffMultiplier**(this.reconnectState.attempts-1);break;default:e=this.reconnectOptions.initialInterval}if(e=Math.min(e,this.reconnectOptions.maxInterval),this.reconnectOptions.jitter){let t=e*.1,n=(Math.random()-.5)*2*t;e+=n}this.reconnectState.nextInterval=Math.max(e,1e3)}cleanupConnection(){if(this.stopPingMonitoring(),this.client){try{this.client.close().catch(()=>{})}catch{}this.client=null}this.transport=null,this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.initialized=!1}stopReconnect(){this.reconnectState.timer&&(clearTimeout(this.reconnectState.timer),this.reconnectState.timer=null)}async refreshTools(){if(!this.client)throw new Error("\u5BA2\u6237\u7AEF\u672A\u521D\u59CB\u5316");try{let t=(await this.client.listTools()).tools||[];this.tools.clear();for(let n of t)this.tools.set(n.name,n);this.logger.info(`${this.config.name} \u670D\u52A1\u52A0\u8F7D\u4E86 ${t.length} \u4E2A\u5DE5\u5177: ${t.map(n=>n.name).join(", ")}`)}catch(e){throw this.logger.error(`${this.config.name} \u83B7\u53D6\u5DE5\u5177\u5217\u8868\u5931\u8D25:`,e instanceof Error?e.message:String(e)),e}}async disconnect(){this.logger.info(`\u4E3B\u52A8\u65AD\u5F00 MCP \u670D\u52A1 ${this.config.name} \u8FDE\u63A5`),this.reconnectState.isManualDisconnect=!0,this.stopPingMonitoring(),this.stopReconnect(),this.cleanupConnection(),this.connectionState="disconnected"}async reconnect(){this.logger.info(`\u624B\u52A8\u91CD\u8FDE MCP \u670D\u52A1 ${this.config.name}`),this.stopReconnect(),this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.isManualDisconnect=!1,this.cleanupConnection(),await this.connect()}getTools(){return Array.from(this.tools.values())}async callTool(e,t){if(!this.client)throw new Error(`\u670D\u52A1 ${this.config.name} \u672A\u8FDE\u63A5`);if(!this.tools.has(e))throw new Error(`\u5DE5\u5177 ${e} \u5728\u670D\u52A1 ${this.config.name} \u4E2D\u4E0D\u5B58\u5728`);this.logger.info(`\u8C03\u7528 ${this.config.name} \u670D\u52A1\u7684\u5DE5\u5177 ${e}\uFF0C\u53C2\u6570:`,JSON.stringify(t));try{let n=await this.client.callTool({name:e,arguments:t||{}});return this.logger.info(`\u5DE5\u5177 ${e} \u8C03\u7528\u6210\u529F\uFF0C\u7ED3\u679C:`,`${JSON.stringify(n).substring(0,500)}...`),n}catch(n){throw this.logger.error(`\u5DE5\u5177 ${e} \u8C03\u7528\u5931\u8D25:`,n instanceof Error?n.message:String(n)),n}}getConfig(){return this.config}getStatus(){return{name:this.config.name,connected:this.connectionState==="connected",initialized:this.initialized,transportType:this.config.type,toolCount:this.tools.size,lastError:this.reconnectState.lastError?.message,reconnectAttempts:this.reconnectState.attempts,connectionState:this.connectionState,pingEnabled:this.pingOptions.enabled,lastPingTime:this.lastPingTime||void 0,pingFailureCount:this.pingFailureCount,isPinging:this.isPinging}}isConnected(){return this.connectionState==="connected"&&this.initialized}enableReconnect(){this.reconnectOptions.enabled=!0,this.logger.info(`${this.config.name} \u81EA\u52A8\u91CD\u8FDE\u5DF2\u542F\u7528`)}disableReconnect(){this.reconnectOptions.enabled=!1,this.stopReconnect(),this.logger.info(`${this.config.name} \u81EA\u52A8\u91CD\u8FDE\u5DF2\u7981\u7528`)}updateReconnectOptions(e){this.reconnectOptions={...this.reconnectOptions,...e},this.logger.info(`${this.config.name} \u91CD\u8FDE\u914D\u7F6E\u5DF2\u66F4\u65B0`,e)}getReconnectOptions(){return{...this.reconnectOptions}}resetReconnectState(){this.stopReconnect(),this.reconnectState.attempts=0,this.reconnectState.nextInterval=this.reconnectOptions.initialInterval,this.reconnectState.lastError=null,this.logger.info(`${this.config.name} \u91CD\u8FDE\u72B6\u6001\u5DF2\u91CD\u7F6E`)}startPingMonitoring(){!this.pingOptions.enabled||this.pingTimer||!this.isConnected()||(this.logger.info(`${this.config.name} \u542F\u52A8ping\u76D1\u63A7\uFF0C\u95F4\u9694: ${this.pingOptions.interval}ms`),setTimeout(()=>{this.isConnected()&&!this.pingTimer&&(this.pingTimer=setInterval(()=>{this.performPing()},this.pingOptions.interval))},this.pingOptions.startDelay))}stopPingMonitoring(){this.pingTimer&&(clearInterval(this.pingTimer),this.pingTimer=null,this.logger.debug(`${this.config.name} \u505C\u6B62ping\u76D1\u63A7`))}async performPing(){if(!this.client||this.isPinging||!this.isConnected())return;this.isPinging=!0;let e=performance.now();try{this.logger.debug(`${this.config.name} \u53D1\u9001ping\u8BF7\u6C42\uFF08\u901A\u8FC7listTools\u68C0\u6D4B\u8FDE\u63A5\uFF09`);let t=this.client.listTools(),n=new Promise((r,c)=>{setTimeout(()=>{c(new Error(`Ping\u8D85\u65F6 (${this.pingOptions.timeout}ms)`))},this.pingOptions.timeout)});await Promise.race([t,n]);let i=performance.now()-e;this.handlePingSuccess(i)}catch(t){let n=performance.now()-e;this.handlePingFailure(t,n)}finally{this.isPinging=!1}}handlePingSuccess(e){this.pingFailureCount=0,this.lastPingTime=new Date,this.logger.debug(`${this.config.name} ping\u6210\u529F\uFF0C\u5EF6\u8FDF: ${e.toFixed(2)}ms`)}handlePingFailure(e,t){if(this.pingFailureCount++,this.logger.warn(`${this.config.name} ping\u5931\u8D25 (${this.pingFailureCount}/${this.pingOptions.maxFailures})\uFF0C\u5EF6\u8FDF: ${t.toFixed(2)}ms\uFF0C\u9519\u8BEF: ${e.message}`),this.pingFailureCount>=this.pingOptions.maxFailures){this.logger.error(`${this.config.name} \u8FDE\u7EEDping\u5931\u8D25\u8FBE\u5230\u9608\u503C\uFF0C\u89E6\u53D1\u91CD\u8FDE\u673A\u5236`),this.stopPingMonitoring();let n=new Error(`Ping\u68C0\u6D4B\u5931\u8D25\uFF0C\u8FDE\u7EED\u5931\u8D25${this.pingFailureCount}\u6B21\uFF0C\u8FDE\u63A5\u53EF\u80FD\u5DF2\u65AD\u5F00`);this.handleConnectionError(n)}}resetPingState(){this.pingFailureCount=0,this.lastPingTime=null,this.isPinging=!1}enablePing(){this.pingOptions.enabled=!0,this.logger.info(`${this.config.name} ping\u76D1\u63A7\u5DF2\u542F\u7528`),this.isConnected()&&this.startPingMonitoring()}disablePing(){this.pingOptions.enabled=!1,this.stopPingMonitoring(),this.logger.info(`${this.config.name} ping\u76D1\u63A7\u5DF2\u7981\u7528`)}updatePingOptions(e){let t=this.pingOptions.enabled;this.pingOptions={...this.pingOptions,...e},this.logger.info(`${this.config.name} ping\u914D\u7F6E\u5DF2\u66F4\u65B0`,e),t!==this.pingOptions.enabled&&(this.pingOptions.enabled&&this.isConnected()?this.startPingMonitoring():this.pingOptions.enabled||this.stopPingMonitoring())}getPingOptions(){return{...this.pingOptions}}};var w=class{static{s(this,"MCPServiceManager")}services=new Map;configs={};logger;tools=new Map;constructor(e){this.logger=a,this.configs=e||{}}async startAllServices(){this.logger.info("[MCPManager] \u6B63\u5728\u542F\u52A8\u6240\u6709 MCP \u670D\u52A1...");let e=Object.entries(this.configs);if(e.length===0){this.logger.warn("[MCPManager] \u6CA1\u6709\u914D\u7F6E\u4EFB\u4F55 MCP \u670D\u52A1\uFF0C\u8BF7\u4F7F\u7528 addServiceConfig() \u6DFB\u52A0\u670D\u52A1\u914D\u7F6E");return}for(let[t]of e)await this.startService(t);this.logger.info("[MCPManager] \u6240\u6709 MCP \u670D\u52A1\u542F\u52A8\u5B8C\u6210")}async startService(e){this.logger.info(`[MCPManager] \u542F\u52A8 MCP \u670D\u52A1: ${e}`);let t=this.configs[e];if(!t)throw new Error(`\u672A\u627E\u5230\u670D\u52A1\u914D\u7F6E: ${e}`);try{this.services.has(e)&&await this.stopService(e);let n=new P(t);await n.connect(),this.services.set(e,n),await this.refreshToolsCache();let i=n.getTools();this.logger.info(`[MCPManager] ${e} \u670D\u52A1\u542F\u52A8\u6210\u529F\uFF0C\u52A0\u8F7D\u4E86 ${i.length} \u4E2A\u5DE5\u5177:`,i.map(r=>r.name).join(", "))}catch(n){throw this.logger.error(`[MCPManager] \u542F\u52A8 ${e} \u670D\u52A1\u5931\u8D25:`,n.message),n}}async stopService(e){this.logger.info(`[MCPManager] \u505C\u6B62 MCP \u670D\u52A1: ${e}`);let t=this.services.get(e);if(!t){this.logger.warn(`[MCPManager] \u670D\u52A1 ${e} \u4E0D\u5B58\u5728\u6216\u672A\u542F\u52A8`);return}try{await t.disconnect(),this.services.delete(e),await this.refreshToolsCache(),this.logger.info(`[MCPManager] ${e} \u670D\u52A1\u5DF2\u505C\u6B62`)}catch(n){throw this.logger.error(`[MCPManager] \u505C\u6B62 ${e} \u670D\u52A1\u5931\u8D25:`,n.message),n}}async refreshToolsCache(){this.tools.clear();for(let[e,t]of this.services)if(t.isConnected()){let n=t.getTools();for(let i of n){let r=`${e}__${i.name}`;this.tools.set(r,{serviceName:e,originalName:i.name,tool:i})}}}getAllTools(){let e=[];for(let[t,n]of this.tools)e.push({name:t,description:n.tool.description||"",inputSchema:n.tool.inputSchema,serviceName:n.serviceName,originalName:n.originalName});return e}async callTool(e,t){this.logger.info(`[MCPManager] \u8C03\u7528\u5DE5\u5177: ${e}\uFF0C\u53C2\u6570:`,t);let n=this.tools.get(e);if(!n)throw new Error(`\u672A\u627E\u5230\u5DE5\u5177: ${e}`);let i=this.services.get(n.serviceName);if(!i)throw new Error(`\u670D\u52A1 ${n.serviceName} \u4E0D\u53EF\u7528`);if(!i.isConnected())throw new Error(`\u670D\u52A1 ${n.serviceName} \u672A\u8FDE\u63A5`);try{let r=await i.callTool(n.originalName,t||{});return this.logger.info(`[MCPManager] \u5DE5\u5177 ${e} \u8C03\u7528\u6210\u529F\uFF0C\u7ED3\u679C:`,r),r}catch(r){throw this.logger.error(`[MCPManager] \u5DE5\u5177 ${e} \u8C03\u7528\u5931\u8D25:`,r.message),r}}async stopAllServices(){this.logger.info("[MCPManager] \u6B63\u5728\u505C\u6B62\u6240\u6709 MCP \u670D\u52A1...");for(let[e,t]of this.services)try{await t.disconnect(),this.logger.info(`[MCPManager] ${e} \u670D\u52A1\u5DF2\u505C\u6B62`)}catch(n){this.logger.error(`[MCPManager] \u505C\u6B62 ${e} \u670D\u52A1\u5931\u8D25:`,n.message)}this.services.clear(),this.tools.clear(),this.logger.info("[MCPManager] \u6240\u6709 MCP \u670D\u52A1\u5DF2\u505C\u6B62")}getStatus(){let e={services:{},totalTools:this.tools.size,availableTools:Array.from(this.tools.keys())};for(let[t,n]of this.services){let i=n.getStatus();e.services[t]={connected:i.connected,clientName:`xiaozhi-${t}-client`}}return e}getService(e){return this.services.get(e)}getAllServices(){return new Map(this.services)}enhanceServiceConfig(e){let t={...e};try{if(e.type==="modelscope-sse"){let n=C.getModelScopeApiKey();if(n)t.apiKey=n,this.logger.info(`[MCPManager] \u4E3A ${e.name} \u670D\u52A1\u6DFB\u52A0 ModelScope API Key`);else throw this.logger.warn(`[MCPManager] ${e.name} \u670D\u52A1\u9700\u8981 ModelScope API Key\uFF0C\u4F46\u672A\u5728\u914D\u7F6E\u4E2D\u627E\u5230`),new Error(`ModelScope SSE \u670D\u52A1 ${e.name} \u9700\u8981 API Key\uFF0C\u8BF7\u5728\u914D\u7F6E\u6587\u4EF6\u4E2D\u8BBE\u7F6E modelscope.apiKey`)}return t}catch(n){throw this.logger.error(`[MCPManager] \u914D\u7F6E\u589E\u5F3A\u5931\u8D25: ${e.name}`,n),n}}addServiceConfig(e,t){let n,i;if(typeof e=="string"&&t)i=e,n=t;else if(typeof e=="object")i=e.name,n=e;else throw new Error("Invalid arguments for addServiceConfig");let r=this.enhanceServiceConfig(n);this.configs[i]=r,this.logger.info(`[MCPManager] \u5DF2\u6DFB\u52A0\u670D\u52A1\u914D\u7F6E: ${i}`)}updateServiceConfig(e,t){let n=this.enhanceServiceConfig(t);this.configs[e]=n,this.logger.info(`[MCPManager] \u5DF2\u66F4\u65B0\u5E76\u589E\u5F3A\u670D\u52A1\u914D\u7F6E: ${e}`)}removeServiceConfig(e){delete this.configs[e],this.logger.info(`[MCPManager] \u5DF2\u79FB\u9664\u670D\u52A1\u914D\u7F6E: ${e}`)}};var y=class{static{s(this,"MCPMessageHandler")}logger;serviceManager;constructor(e){this.serviceManager=e,this.logger=a}async handleMessage(e){this.logger.debug(`\u5904\u7406 MCP \u6D88\u606F: ${e.method}`,e);try{switch(e.method){case"initialize":return await this.handleInitialize(e.params,e.id);case"tools/list":return await this.handleToolsList(e.id);case"tools/call":return await this.handleToolCall(e.params,e.id);case"ping":return await this.handlePing(e.id);default:throw new Error(`\u672A\u77E5\u7684\u65B9\u6CD5: ${e.method}`)}}catch(t){return this.logger.error(`\u5904\u7406\u6D88\u606F\u65F6\u51FA\u9519: ${e.method}`,t),this.createErrorResponse(t,e.id)}}async handleInitialize(e,t){return this.logger.info("\u5904\u7406 initialize \u8BF7\u6C42",e),{jsonrpc:"2.0",result:{serverInfo:{name:"xiaozhi-mcp-server",version:"1.0.0"},capabilities:{tools:{},logging:{}},protocolVersion:"2024-11-05"},id:t||null}}async handleToolsList(e){this.logger.info("\u5904\u7406 tools/list \u8BF7\u6C42");try{let n=this.serviceManager.getAllTools().map(i=>({name:i.name,description:i.description,inputSchema:i.inputSchema}));return this.logger.info(`\u8FD4\u56DE ${n.length} \u4E2A\u5DE5\u5177`),{jsonrpc:"2.0",result:{tools:n},id:e||null}}catch(t){throw this.logger.error("\u83B7\u53D6\u5DE5\u5177\u5217\u8868\u5931\u8D25",t),t}}async handleToolCall(e,t){this.logger.info(`\u5904\u7406 tools/call \u8BF7\u6C42: ${e.name}`,e);try{if(!e.name)throw new Error("\u5DE5\u5177\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");let n=await this.serviceManager.callTool(e.name,e.arguments||{});return this.logger.info(`\u5DE5\u5177 ${e.name} \u8C03\u7528\u6210\u529F`),{jsonrpc:"2.0",result:{content:n.content,isError:n.isError||!1},id:t||null}}catch(n){throw this.logger.error(`\u5DE5\u5177\u8C03\u7528\u5931\u8D25: ${e.name}`,n),n}}async handlePing(e){return this.logger.debug("\u5904\u7406 ping \u8BF7\u6C42"),{jsonrpc:"2.0",result:{status:"ok",timestamp:new Date().toISOString()},id:e||null}}createErrorResponse(e,t){let n=-32603;return e.message.includes("\u672A\u627E\u5230\u5DE5\u5177")||e.message.includes("\u672A\u77E5\u7684\u65B9\u6CD5")?n=-32601:(e.message.includes("\u53C2\u6570")||e.message.includes("\u4E0D\u80FD\u4E3A\u7A7A"))&&(n=-32602),{jsonrpc:"2.0",error:{code:n,message:e.message,data:{stack:e.stack}},id:t||null}}getServiceManager(){return this.serviceManager}};var H=class{static{s(this,"ToolRegistry")}serviceManager;logger;constructor(e){this.serviceManager=e,this.logger=a}async initialize(){this.logger.info("\u521D\u59CB\u5316\u5DE5\u5177\u6CE8\u518C\u8868")}getAllTools(){return this.serviceManager.getAllTools().map(e=>({name:e.name,description:e.description,inputSchema:e.inputSchema,serviceName:e.serviceName,originalName:e.originalName}))}findTool(e){return this.getAllTools().find(n=>n.name===e)||null}hasTool(e){return this.findTool(e)!==null}},F=class extends W{static{s(this,"ConnectionManager")}connections=new Map;logger;constructor(){super(),this.logger=a}async initialize(){this.logger.info("\u521D\u59CB\u5316\u8FDE\u63A5\u7BA1\u7406\u5668")}registerConnection(e,t,n){let i={id:e,transportName:t,state:n,connectedAt:new Date,lastActivity:new Date};this.connections.set(e,i),this.emit("connectionRegistered",i),this.logger.debug(`\u8FDE\u63A5\u5DF2\u6CE8\u518C: ${e} (${t})`)}updateConnectionState(e,t){let n=this.connections.get(e);n&&(n.state=t,n.lastActivity=new Date,this.emit("connectionStateChanged",n),this.logger.debug(`\u8FDE\u63A5\u72B6\u6001\u66F4\u65B0: ${e} -> ${t}`))}removeConnection(e){let t=this.connections.get(e);t&&(this.connections.delete(e),this.emit("connectionRemoved",t),this.logger.debug(`\u8FDE\u63A5\u5DF2\u79FB\u9664: ${e}`))}getAllConnections(){return Array.from(this.connections.values())}getActiveConnectionCount(){return Array.from(this.connections.values()).filter(e=>e.state==="connected").length}async closeAllConnections(){this.logger.info("\u5173\u95ED\u6240\u6709\u8FDE\u63A5"),this.connections.clear(),this.emit("allConnectionsClosed")}},T=class extends W{static{s(this,"UnifiedMCPServer")}serviceManager;messageHandler;transportAdapters=new Map;toolRegistry;connectionManager;isRunning=!1;logger;config;constructor(e={}){super(),this.config={name:"UnifiedMCPServer",enableLogging:!0,logLevel:"info",maxConnections:100,connectionTimeout:3e4,...e},this.logger=a,this.serviceManager=new w,this.messageHandler=new y(this.serviceManager),this.toolRegistry=new H(this.serviceManager),this.connectionManager=new F,this.setupEventListeners()}setupEventListeners(){this.connectionManager.on("connectionRegistered",e=>{this.emit("connectionRegistered",e)}),this.connectionManager.on("connectionStateChanged",e=>{this.emit("connectionStateChanged",e)}),this.connectionManager.on("connectionRemoved",e=>{this.emit("connectionRemoved",e)})}async initialize(){this.logger.info("\u521D\u59CB\u5316\u7EDF\u4E00 MCP \u670D\u52A1\u5668");try{await this.serviceManager.startAllServices(),await this.toolRegistry.initialize(),await this.connectionManager.initialize(),this.logger.info("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u521D\u59CB\u5316\u5B8C\u6210"),this.emit("initialized")}catch(e){throw this.logger.error("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u521D\u59CB\u5316\u5931\u8D25",e),e}}async registerTransport(e,t){if(this.transportAdapters.has(e))throw new Error(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u5DF2\u5B58\u5728`);this.logger.info(`\u6CE8\u518C\u4F20\u8F93\u9002\u914D\u5668: ${e}`);try{await t.initialize(),this.transportAdapters.set(e,t),this.connectionManager.registerConnection(t.getConnectionId(),e,t.getState()),this.logger.info(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u6CE8\u518C\u6210\u529F`),this.emit("transportRegistered",{name:e,adapter:t})}catch(n){throw this.logger.error(`\u6CE8\u518C\u4F20\u8F93\u9002\u914D\u5668 ${e} \u5931\u8D25`,n),n}}async start(){if(this.isRunning)throw new Error("\u670D\u52A1\u5668\u5DF2\u5728\u8FD0\u884C");this.logger.info("\u542F\u52A8\u7EDF\u4E00 MCP \u670D\u52A1\u5668");try{for(let[e,t]of this.transportAdapters)try{await t.start(),this.connectionManager.updateConnectionState(t.getConnectionId(),t.getState()),this.logger.info(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u542F\u52A8\u6210\u529F`)}catch(n){throw this.logger.error(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u542F\u52A8\u5931\u8D25`,n),n}this.isRunning=!0,this.logger.info("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u542F\u52A8\u6210\u529F"),this.emit("started")}catch(e){throw this.logger.error("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u542F\u52A8\u5931\u8D25",e),e}}async stop(){if(this.isRunning){this.logger.info("\u505C\u6B62\u7EDF\u4E00 MCP \u670D\u52A1\u5668");try{for(let[e,t]of this.transportAdapters)try{await t.stop(),this.connectionManager.updateConnectionState(t.getConnectionId(),t.getState()),this.logger.info(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u505C\u6B62\u6210\u529F`)}catch(n){this.logger.error(`\u4F20\u8F93\u9002\u914D\u5668 ${e} \u505C\u6B62\u5931\u8D25`,n)}await this.connectionManager.closeAllConnections(),await this.serviceManager.stopAllServices(),this.isRunning=!1,this.logger.info("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u505C\u6B62\u6210\u529F"),this.emit("stopped")}catch(e){throw this.logger.error("\u7EDF\u4E00 MCP \u670D\u52A1\u5668\u505C\u6B62\u5931\u8D25",e),e}}}getServiceManager(){return this.serviceManager}getToolRegistry(){return this.toolRegistry}getConnectionManager(){return this.connectionManager}getMessageHandler(){return this.messageHandler}getStatus(){return{isRunning:this.isRunning,transportCount:this.transportAdapters.size,activeConnections:this.connectionManager.getActiveConnectionCount(),toolCount:this.toolRegistry.getAllTools().length,config:this.config}}getTransportAdapters(){return new Map(this.transportAdapters)}isServerRunning(){return this.isRunning}};async function K(o={}){a.info("[ServerFactory] \u5F00\u59CB\u521B\u5EFA MCP \u670D\u52A1\u5668",o);try{let e=await Me(o);a.info(`[ServerFactory] \u786E\u5B9A\u670D\u52A1\u5668\u6A21\u5F0F: ${e}`);let t=new T(o.serverConfig);return await t.initialize(),await we(t,e,o),a.info("[ServerFactory] MCP \u670D\u52A1\u5668\u521B\u5EFA\u6210\u529F"),t}catch(e){throw a.error("[ServerFactory] \u521B\u5EFA MCP \u670D\u52A1\u5668\u5931\u8D25",e),e}}s(K,"createServer");async function Me(o){if(o.mode&&o.mode!=="auto")return o.mode;let e=await Pe(o.autoDetect);return a.info("\u73AF\u5883\u68C0\u6D4B\u7ED3\u679C",e),e.suggestedMode}s(Me,"determineServerMode");async function Pe(o={}){let{checkStdin:e=!0,checkEnvironment:t=!0,defaultMode:n="http"}=o,i={hasStdin:!1,isInteractive:!1,hasPort:!1,suggestedMode:n,reasons:[]};e&&(i.hasStdin=!process.stdin.isTTY,i.isInteractive=process.stdin.isTTY||!1,i.hasStdin&&i.reasons.push("\u68C0\u6D4B\u5230\u6807\u51C6\u8F93\u5165\u6D41"),i.isInteractive&&i.reasons.push("\u68C0\u6D4B\u5230\u4EA4\u4E92\u5F0F\u7EC8\u7AEF"));let r=!1;if(t){let c=process.env.MCP_SERVER_MODE,h=process.env.PORT||process.env.MCP_PORT;c==="stdio"?(i.suggestedMode="stdio",i.reasons.push("\u73AF\u5883\u53D8\u91CF MCP_SERVER_MODE=stdio"),r=!0):c==="http"?(i.suggestedMode="http",i.reasons.push("\u73AF\u5883\u53D8\u91CF MCP_SERVER_MODE=http"),r=!0):c==="websocket"?(i.suggestedMode="websocket",i.reasons.push("\u73AF\u5883\u53D8\u91CF MCP_SERVER_MODE=websocket"),r=!0):c==="hybrid"&&(i.suggestedMode="hybrid",i.reasons.push("\u73AF\u5883\u53D8\u91CF MCP_SERVER_MODE=hybrid"),r=!0),h&&(i.hasPort=!0,i.reasons.push(`\u68C0\u6D4B\u5230\u7AEF\u53E3\u914D\u7F6E: ${h}`))}return!r&&i.suggestedMode===n&&(i.hasStdin&&!i.isInteractive?(i.suggestedMode="stdio",i.reasons.push("\u63A8\u65AD\uFF1A\u975E\u4EA4\u4E92\u5F0F\u73AF\u5883\uFF0C\u9002\u5408 Stdio \u6A21\u5F0F")):(i.isInteractive||i.hasPort)&&(i.suggestedMode="http",i.reasons.push("\u63A8\u65AD\uFF1A\u4EA4\u4E92\u5F0F\u73AF\u5883\u6216\u6709\u7AEF\u53E3\u914D\u7F6E\uFF0C\u9002\u5408 HTTP \u6A21\u5F0F"))),i}s(Pe,"detectEnvironment");async function we(o,e,t){let n=o.getMessageHandler();switch(e){case"stdio":await U(o,n,t.stdioConfig);break;case"http":await _(o,n,t.httpConfig);break;case"websocket":await B(o,n,t.websocketConfig);break;case"hybrid":await U(o,n,t.stdioConfig),await _(o,n,t.httpConfig),t.websocketConfig&&await B(o,n,t.websocketConfig);break;default:throw new Error(`\u4E0D\u652F\u6301\u7684\u670D\u52A1\u5668\u6A21\u5F0F: ${e}`)}}s(we,"registerTransportsForMode");async function U(o,e,t={name:"stdio"}){let n=new b(e,t);await o.registerTransport("stdio",n),a.info("Stdio \u4F20\u8F93\u9002\u914D\u5668\u6CE8\u518C\u6210\u529F")}s(U,"registerStdioTransport");async function _(o,e,t={name:"http"}){let n={port:3e3,host:"0.0.0.0",...t};process.env.PORT?n.port=Number.parseInt(process.env.PORT,10):process.env.MCP_PORT&&(n.port=Number.parseInt(process.env.MCP_PORT,10));let i=new v(e,n);await o.registerTransport("http",i),a.info(`HTTP \u4F20\u8F93\u9002\u914D\u5668\u6CE8\u518C\u6210\u529F (\u7AEF\u53E3: ${n.port})`)}s(_,"registerHTTPTransport");async function B(o,e,t={name:"websocket",endpointUrl:"ws://localhost:8080"}){let n={mode:"client",compression:!0,batchSize:10,batchTimeout:100,maxConnections:100,...t};process.env.WEBSOCKET_URL?n.endpointUrl=process.env.WEBSOCKET_URL:process.env.MCP_WEBSOCKET_URL&&(n.endpointUrl=process.env.MCP_WEBSOCKET_URL);let i=new M(e,n);await o.registerTransport("websocket",i),a.info(`WebSocket \u4F20\u8F93\u9002\u914D\u5668\u6CE8\u518C\u6210\u529F (\u7AEF\u70B9: ${n.endpointUrl})`)}s(B,"registerWebSocketTransport");var Gt=ye(Te(import.meta.url)),J=p.env.XIAOZHI_CONFIG_DIR||p.cwd();a.initLogFile(J);a.enableFileLogging(!0);a.info(`\u65E5\u5FD7\u6587\u4EF6\u5DF2\u521D\u59CB\u5316: ${J}/xiaozhi.log`);async function Ee(){try{a.info("\u542F\u52A8 MCP \u670D\u52A1\u5668\u4EE3\u7406"),await Re();let o=await K({mode:"stdio",stdioConfig:{name:"mcp-proxy",encoding:"utf8"}});await o.start(),a.info("MCP \u670D\u52A1\u5668\u4EE3\u7406\u542F\u52A8\u6210\u529F"),p.on("SIGINT",async()=>{a.info("\u6536\u5230 SIGINT \u4FE1\u53F7\uFF0C\u6B63\u5728\u5173\u95ED\u670D\u52A1\u5668"),await o.stop(),p.exit(0)}),p.on("SIGTERM",async()=>{a.info("\u6536\u5230 SIGTERM \u4FE1\u53F7\uFF0C\u6B63\u5728\u5173\u95ED\u670D\u52A1\u5668"),await o.stop(),p.exit(0)})}catch(o){a.error("\u542F\u52A8 MCP \u670D\u52A1\u5668\u4EE3\u7406\u5931\u8D25:",o),p.exit(1)}}s(Ee,"main");async function Re(){try{if(a.info("\u52A0\u8F7D MCP \u670D\u52A1\u5668\u914D\u7F6E"),!C.configExists()){a.warn("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u5C06\u4F7F\u7528\u9ED8\u8BA4\u914D\u7F6E");return}let o=C.getConfig();a.info(`\u5DF2\u52A0\u8F7D\u914D\u7F6E\uFF0C\u5305\u542B ${Object.keys(o.mcpServers||{}).length} \u4E2A MCP \u670D\u52A1\u5668`)}catch(o){throw a.error("\u52A0\u8F7D\u914D\u7F6E\u5931\u8D25:",o),o}}s(Re,"loadConfiguration");import.meta.url===`file://${p.argv[1]}`&&Ee().catch(o=>{a.error("MCP \u670D\u52A1\u5668\u4EE3\u7406\u542F\u52A8\u5931\u8D25:",o),p.exit(1)});export{Ee as main};
|
|
9
11
|
//# sourceMappingURL=mcpServerProxy.js.map
|