grafana-mcp-analyzer
Version:
让AI助手直接分析你的Grafana监控数据 - A Model Context Protocol server for Grafana data analysis
10 lines (6 loc) • 25.3 kB
JavaScript
import{McpServer as j,ResourceTemplate as B}from"@modelcontextprotocol/sdk/server/mcp.js";import{z as p}from"zod";import S from"path";import T from"os";import{executeQuery as L,extractData as U,checkHealth as F}from"../datasources/grafana-client.js";import{buildAnalysisGuidance as b,generateDataOverview as G}from"../services/monitoring-analyzer.js";import{chunkAndSave as P,loadChunks as W,getMaxChunkSize as J}from"../services/chunk-manager.js";import{generateRequestId as Q,storeRequestMetadata as I,getResponseData as x,safeStoreAnalysis as K,getAnalysis as H}from"../services/data-store.js";import{findValidCache as A,createCache as V,listCache as X,getCacheStats as Y,cleanupExpiredCache as Z,smartCleanupCache as N,clearAllCache as q,deleteCacheByQueryName as ee,checkAndInitializeCache as O}from"../services/data-cache-manager.js";function R(){const h=process.env.FORCE_RESOURCES_SUPPORT;return h==="true"}async function te(h,l){const w=S.join(process.env.DATA_STORE_ROOT||S.join(T.homedir(),".grafana-mcp-analyzer","data-store"),h),o=S.join(w,"data"),c=await import("fs/promises");await c.mkdir(o,{recursive:!0});const y=JSON.stringify(l,null,2),v=Buffer.byteLength(y,"utf8"),z=S.join(o,"full.json");return await c.writeFile(z,y),{type:"full",size:v,chunks:1,resourceUri:`monitoring-data://${h}/data`}}async function ae(h,l){const w=l.data||l,o=JSON.stringify(w),c=Buffer.byteLength(o,"utf8"),y=J();if(console.error(`\u6570\u636E\u5927\u5C0F: ${Math.round(c/1024)}KB, \u4F7F\u7528\u4E25\u683C${Math.round(y/1024)}KB\u5206\u5757\u7B56\u7565`),c<=y)return await te(h,w);const v=await P(w,h,y);return{type:"chunked",size:c,chunks:v.chunks.length,chunkingStrategy:`strict-${Math.round(y/1024)}kb`,metadata:v.metadata,resourceUri:`monitoring-data://${h}/chunks`}}async function re(h,l){const w=JSON.stringify(l),o=Buffer.byteLength(w,"utf8");return console.error(`\u6570\u636E\u5927\u5C0F: ${Math.round(o/1024)}KB, \u4F7F\u7528\u4E25\u683C\u5206\u5757\u7B56\u7565`),await ae(h,l)}function he(h,l){try{O()}catch(e){console.error("\u7F13\u5B58\u7CFB\u7EDF\u521D\u59CB\u5316\u5931\u8D25\uFF0C\u4F46\u7EE7\u7EED\u542F\u52A8\u670D\u52A1\u5668:",e)}const w={name:"grafana-mcp-analyzer",version:h.version,description:`\u91CD\u8981\u8B66\u544A\uFF1A\u7981\u6B62\u4F7F\u7528curl\u6216\u5176\u4ED6\u5916\u90E8\u65B9\u6CD5\u83B7\u53D6\u6570\u636E\uFF01
Grafana MCP\u5206\u6790\u5668 - \u76D1\u63A7\u6570\u636E\u67E5\u8BE2\u548C\u5206\u6790\u5DE5\u5177
\u6838\u5FC3\u529F\u80FD\uFF1A\u9884\u5B9A\u4E49\u67E5\u8BE2\u3001\u6570\u636E\u5B58\u50A8\u3001AI\u5206\u6790\u6307\u5F15\u3001\u4F1A\u8BDD\u7BA1\u7406
\u6570\u636E\u5904\u7406\uFF1A\u652F\u6301\u4EFB\u610F\u5927\u5C0F\u6570\u636E\uFF0C\u63D0\u4F9B\u5B8C\u6574\u6570\u636E\u5206\u6790
\u4F7F\u7528\u65B9\u5F0F\uFF1Alist_queries\u67E5\u770B\u53EF\u7528\u67E5\u8BE2\uFF0Canalyze_query\u8FDB\u884C\u5206\u6790
\u5FC5\u987B\u4F7F\u7528\u63D0\u4F9B\u7684MCP\u5DE5\u5177\uFF0C\u4EFB\u4F55\u5176\u4ED6\u65B9\u6CD5\u90FD\u4F1A\u5BFC\u81F4\u9519\u8BEF\uFF01`};function o(e,s=!1){return{content:[{type:"text",text:JSON.stringify(e,null,2)}],...s&&{isError:!0}}}function c(e){const s=e instanceof Error?e.message:e;return o({success:!1,error:s,timestamp:new Date().toISOString()},!0)}function y(e){const s=M();if(!s[e])throw new Error(`\u67E5\u8BE2\u914D\u7F6E\u4E0D\u5B58\u5728: ${e}`);return s[e]}function v(e,s){return R()?e.type==="chunked"?e.resourceUris||[]:[e.resourceUri||`monitoring-data://${s}/data`]:[]}async function z(e,s,i){await I(s,{timestamp:new Date().toISOString(),url:e.url,method:e.method||"POST",params:e.params,data:e.data,...i});const a=await D(e),r=await re(s,a),t=v(r,s);return{result:a,storageResult:r,resourceLinks:t}}async function D(e){const s=await L(e,l.baseUrl||"");if(!s.success)throw new Error(`\u67E5\u8BE2\u6267\u884C\u5931\u8D25: ${s.error}`);return U(s)}function M(){return l.queries||{}}const k=new j(w);R()&&k.registerResource("monitoring-data",new B("monitoring-data://{requestId}/{dataType}",{list:void 0}),{title:"\u76D1\u63A7\u6570\u636E",description:"Grafana\u76D1\u63A7\u6570\u636E\u8D44\u6E90\u67E5\u770B\u5668"},async(e,{requestId:s,dataType:i})=>{try{const a=Array.isArray(s)?s[0]:s,r=Array.isArray(i)?i[0]:i;let t;return r==="analysis"?t=await H(a):r?.startsWith("chunk-")?t=await x(a,r):t=await x(a),typeof t=="string"?{contents:[{uri:e.href,text:t,mimeType:"text/plain"}]}:{contents:[{uri:e.href,text:JSON.stringify(t,null,2),mimeType:"application/json"}]}}catch(a){return console.error(`[MCP Resource] \u8D44\u6E90\u8BBF\u95EE\u5931\u8D25: ${a.message}`),{contents:[{uri:e.href,text:`\u9519\u8BEF: ${a.message}`,mimeType:"text/plain"}]}}}),k.registerTool("manage_cache",{title:"\u7F13\u5B58\u7BA1\u7406",description:"\u7BA1\u7406\u6570\u636E\u7F13\u5B58\uFF0C\u652F\u6301\u67E5\u770B\u7F13\u5B58\u72B6\u6001\u3001\u6E05\u7406\u8FC7\u671F\u7F13\u5B58\u3001\u667A\u80FD\u6E05\u7406\u3001\u521D\u59CB\u5316\u7F13\u5B58\u7CFB\u7EDF\u7B49\u64CD\u4F5C",inputSchema:{action:p.enum(["list","stats","cleanup","smart_cleanup","clear","delete","init"]).describe("\u64CD\u4F5C\u7C7B\u578B\uFF1Alist(\u5217\u51FA\u7F13\u5B58)/stats(\u7EDF\u8BA1\u4FE1\u606F)/cleanup(\u6E05\u7406\u8FC7\u671F)/smart_cleanup(\u667A\u80FD\u6E05\u7406)/clear(\u6E05\u7A7A\u6240\u6709)/delete(\u5220\u9664\u6307\u5B9A\u67E5\u8BE2\u7F13\u5B58)/init(\u521D\u59CB\u5316\u7F13\u5B58\u7CFB\u7EDF)"),limit:p.number().optional().describe("\u5217\u51FA\u7F13\u5B58\u65F6\u7684\u6570\u91CF\u9650\u5236").default(10),maxEntries:p.number().optional().describe("\u667A\u80FD\u6E05\u7406\u65F6\u7684\u6700\u5927\u7F13\u5B58\u6761\u76EE\u6570").default(50),maxTotalSize:p.number().optional().describe("\u667A\u80FD\u6E05\u7406\u65F6\u7684\u6700\u5927\u603B\u5927\u5C0F(MB)").default(100),queryName:p.string().optional().describe("\u8981\u5220\u9664\u7684\u67E5\u8BE2\u540D\u79F0\uFF08\u4EC5\u5728action\u4E3Adelete\u65F6\u4F7F\u7528\uFF09")}},async({action:e,limit:s,maxEntries:i,maxTotalSize:a,queryName:r})=>{try{switch(e){case"init":return O(),o({action:"init",message:"\u7F13\u5B58\u7CFB\u7EDF\u521D\u59CB\u5316\u5B8C\u6210",status:"success"});case"list":const t=await X(s);return o({action:"list",caches:t,count:t.length,message:`\u627E\u5230 ${t.length} \u4E2A\u6709\u6548\u7F13\u5B58`});case"stats":const d=await Y();return o({action:"stats",stats:d,message:`\u7F13\u5B58\u7EDF\u8BA1\uFF1A${d.validEntries}/${d.totalEntries} \u4E2A\u6709\u6548\u6761\u76EE\uFF0C\u603B\u5927\u5C0F ${Math.round(d.totalSize/1024)}KB\uFF0C\u5E73\u5747\u8BBF\u95EE\u6B21\u6570 ${d.averageAccessCount}`});case"cleanup":const u=await Z();return o({action:"cleanup",cleanedCount:u,message:`\u6E05\u7406\u4E86 ${u} \u4E2A\u8FC7\u671F\u7F13\u5B58`});case"smart_cleanup":const n=await N(i,a*1024*1024);return o({action:"smart_cleanup",...n,message:`\u667A\u80FD\u6E05\u7406\u5B8C\u6210\uFF1A${n.deletedCount} \u4E2A\u7F13\u5B58\u88AB\u5220\u9664\uFF0C\u91CA\u653E ${(n.freedSize/1024/1024).toFixed(2)}MB\uFF0C\u539F\u56E0\uFF1A${n.reason}`});case"clear":const f=await q();return o({action:"clear",...f,message:`\u6E05\u7A7A\u6240\u6709\u7F13\u5B58\u5B8C\u6210\uFF1A${f.deletedCount} \u4E2A\u7F13\u5B58\u88AB\u5220\u9664\uFF0C\u91CA\u653E ${(f.freedSize/1024/1024).toFixed(2)}MB`});case"delete":if(!r)return c("\u5220\u9664\u7F13\u5B58\u65F6\u5FC5\u987B\u6307\u5B9AqueryName\u53C2\u6570");const g=await ee(r);return o({action:"delete",...g,message:`\u5220\u9664\u67E5\u8BE2\u7F13\u5B58\u5B8C\u6210\uFF1A${g.deletedCount} \u4E2A\u7F13\u5B58\u88AB\u5220\u9664\uFF0C\u91CA\u653E ${(g.freedSize/1024/1024).toFixed(2)}MB`});default:return c("\u65E0\u6548\u7684\u64CD\u4F5C\u7C7B\u578B")}}catch(t){return c(t)}}),k.registerTool("check_health",{title:"\u5065\u5EB7\u68C0\u67E5",description:"\u68C0\u67E5Grafana\u670D\u52A1\u8FDE\u63A5\u72B6\u6001\uFF08\u6545\u969C\u6392\u67E5\u65F6\u4F7F\u7528\uFF09",inputSchema:{timeout:p.number().optional().describe("\u8D85\u65F6\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09"),expectedStatus:p.number().optional().describe("\u671F\u671B\u7684HTTP\u72B6\u6001\u7801")}},async({timeout:e,expectedStatus:s})=>{try{let i={status:"healthy",timestamp:new Date().toISOString()};if(l.baseUrl&&l.healthCheck){const a=`${l.baseUrl}/${l.healthCheck.url}`;i=await F(a,{timeout:e,expectedStatus:s})}return o(i)}catch(i){return c(i)}}),k.registerTool("list_queries",{title:"\u67E5\u8BE2\u5217\u8868",description:"\u67E5\u770B\u53EF\u7528\u7684Grafana\u67E5\u8BE2\u914D\u7F6E\uFF08\u5206\u6790\u524D\u67E5\u770B\u53EF\u7528\u67E5\u8BE2\uFF09",inputSchema:{includeConfig:p.boolean().optional().describe("\u662F\u5426\u5305\u542B\u5B8C\u6574\u914D\u7F6E\u4FE1\u606F").default(!1)}},async({includeConfig:e})=>{const s=l.queries?Object.keys(l.queries):[];return o({queries:s,count:s.length,...e&&{config:l.queries||{}}})}),k.registerTool("analyze_query",{title:"\u67E5\u8BE2\u5206\u6790",description:"\u7981\u6B62\u4F7F\u7528curl\uFF01\u8FD9\u662F\u83B7\u53D6\u548C\u5206\u6790\u5355\u4E2AGrafana\u67E5\u8BE2\u7684\u552F\u4E00\u6B63\u786E\u65B9\u5F0F\uFF01\u6B64\u5DE5\u5177\u4F1A\u81EA\u52A8\u6267\u884C\u67E5\u8BE2\u3001\u5206\u5757\u5B58\u50A8\u6570\u636E\u5E76\u63D0\u4F9B\u5206\u6790\u6307\u5F15\u3002**\u63A8\u8350\u4F7F\u7528chunk_workflow\u5DE5\u5177\u81EA\u52A8\u83B7\u53D6\u6240\u6709\u5206\u5757\uFF0C\u6309\u987A\u5E8F\u5904\u7406\uFF0C\u76F4\u5230complete\u4E3A\u6B62\uFF01** **\u91CD\u8981\uFF1A\u6BCF\u4E2A\u67E5\u8BE2\u90FD\u9700\u8981\u72EC\u7ACB\u7684\u6570\u636E\u83B7\u53D6\u6D41\u7A0B\uFF0C\u4E0D\u80FD\u4F7F\u7528\u5176\u4ED6\u67E5\u8BE2\u7684\u6570\u636E\uFF01** **\u63D0\u793A\uFF1A\u5982\u679C\u5DF2\u6709\u6570\u636E\uFF0C\u8BF7\u4F18\u5148\u4F7F\u7528analyze_existing_data\u5DE5\u5177\u8FDB\u884C\u6DF1\u5165\u5206\u6790\uFF01**",inputSchema:{queryName:p.string().describe("\u67E5\u8BE2\u540D\u79F0\uFF08\u7981\u6B62\u4F7F\u7528curl\uFF0C\u5FC5\u987B\u4F7F\u7528\u6B64\u5DE5\u5177\uFF09"),prompt:p.string().describe("\u5206\u6790\u9700\u6C42\u63CF\u8FF0"),sessionId:p.string().optional().describe("\u4F1A\u8BDDID")}},async({queryName:e,prompt:s,sessionId:i})=>{try{const a=y(e),r=await A(e,a,i);let t,d,u,n,f=!1;if(r)t=r.requestId,d=await x(t),u={type:r.metadata.storageType,size:r.dataSize,chunks:r.chunks},n=[`monitoring-data://${t}/data`],f=!0;else{t=Q();const _=await z(a,t,{queryName:e,prompt:s,sessionId:i});d=_.result,u=_.storageResult,n=_.resourceLinks,await V(e,a,t,u.size,u.chunks||1,{prompt:s,sessionId:i,dataType:d.type||"unknown",storageType:u.type})}const g=R();let m;g?m={type:"raw_data_available",hasData:!0,timestamp:new Date().toISOString(),status:"success",message:"\u5B8C\u6574\u6570\u636E\u53EF\u901A\u8FC7ResourceLinks\u83B7\u53D6"}:(m=G(d),m.message="\u6570\u636E\u5DF2\u667A\u80FD\u5904\u7406\uFF0C\u5305\u542B\u6982\u89C8\u548C\u6458\u8981\u4FE1\u606F",m.processingStrategy="smart_summary");const $=b(s,t,m,u,a,g);return await K(t,{prompt:s,timestamp:new Date().toISOString(),queryName:e,dataOverview:m,resourceLinks:n,status:"ready_for_analysis",type:"query_metadata"}),o({success:!0,requestId:t,queryName:e,dataSize:u.size,storageType:u.type,resourceLinks:n,message:$,analysisMode:g?"resources-based":"tool-based",dataReady:!0,analysisInstructions:g?"\u8BF7\u6309\u7167message\u4E2D\u7684\u6307\u5F15\uFF0C\u901A\u8FC7resourceLinks\u83B7\u53D6\u5B9E\u9645\u6570\u636E\u5E76\u8FDB\u884C\u4E00\u6B21\u6027\u5B8C\u6574\u5206\u6790":"\u8BF7\u6309\u7167message\u4E2D\u7684\u6307\u5F15\uFF0C\u4F7F\u7528chunk_workflow\u5DE5\u5177\u83B7\u53D6\u6570\u636E\u5E76\u8FDB\u884C\u4E00\u6B21\u6027\u5B8C\u6574\u5206\u6790\u3002\u6570\u636E\u5DF2\u5B8C\u6574\uFF0C\u65E0\u9700\u91CD\u590D\u6267\u884Canalyze_query",querySpecific:!0,dataSource:e,warning:"\u8FD9\u662F\u67E5\u8BE2'"+e+"'\u7684\u4E13\u7528\u6570\u636E\uFF0C\u4E0D\u80FD\u7528\u4E8E\u5176\u4ED6\u67E5\u8BE2\u7684\u5206\u6790\uFF01",cacheInfo:f?{hit:!0,cacheId:r.id,accessCount:r.accessCount,created:r.created,message:`\u4F7F\u7528\u7F13\u5B58\u6570\u636E (\u5DF2\u8BBF\u95EE${r.accessCount}\u6B21\uFF0C\u521B\u5EFA\u4E8E${new Date(r.created).toLocaleString()})`}:{hit:!1,message:"\u{1F195} \u6267\u884C\u65B0\u67E5\u8BE2\u5E76\u521B\u5EFA\u7F13\u5B58"}})}catch(a){return c(a)}}),k.registerTool("analyze_existing_data",{title:"\u5DF2\u6709\u6570\u636E\u5206\u6790",description:'**\u63A8\u8350\u4F7F\u7528\u6B64\u5DE5\u5177\uFF01** \u5F53\u7528\u6237\u57FA\u4E8E\u5DF2\u6709\u6570\u636E\u8FDB\u884C\u6DF1\u5165\u5206\u6790\u65F6\u4F7F\u7528\u6B64\u5DE5\u5177\u3002\u6B64\u5DE5\u5177\u4E0D\u4F1A\u91CD\u65B0\u83B7\u53D6\u6570\u636E\uFF0C\u800C\u662F\u57FA\u4E8E\u5DF2\u83B7\u53D6\u7684\u6570\u636E\u8FDB\u884C\u6DF1\u5165\u5206\u6790\u3002\u9002\u7528\u4E8E\u7528\u6237\u8BF4"\u8FD9\u4E2A..."\u3001"\u90A3\u4E2A..."\u3001"\u518D\u8BE6\u7EC6\u5206\u6790..."\u7B49\u57FA\u4E8E\u4E0A\u4E0B\u6587\u7684\u5206\u6790\u9700\u6C42\u3002**\u91CD\u8981\uFF1A\u5FC5\u987B\u4F7F\u7528\u6B63\u786E\u7684queryName\uFF0C\u4E0D\u80FD\u4F7F\u7528\u5176\u4ED6\u67E5\u8BE2\u7684\u6570\u636E\uFF01\u8C03\u7528\u6B64\u5DE5\u5177\u540E\uFF0C\u8BF7\u76F4\u63A5\u57FA\u4E8E\u8FD4\u56DE\u7684\u5206\u6790\u6307\u5F15\u8FDB\u884C\u5206\u6790\uFF0C\u4E0D\u8981\u518D\u6B21\u8C03\u7528\u4EFB\u4F55\u5DE5\u5177\uFF01**',inputSchema:{queryName:p.string().describe("\u67E5\u8BE2\u540D\u79F0\uFF08\u5FC5\u987B\u662F\u5DF2\u83B7\u53D6\u6570\u636E\u7684\u67E5\u8BE2\uFF0C\u4E0D\u80FD\u4F7F\u7528\u5176\u4ED6\u67E5\u8BE2\u7684\u6570\u636E\uFF01\uFF09"),analysisRequest:p.string().describe("\u5177\u4F53\u7684\u5206\u6790\u9700\u6C42\uFF08\u5982\uFF1A\u652F\u6491\u4F4D\u548C\u963B\u529B\u4F4D\u3001\u4EF7\u683C\u8D8B\u52BF\u3001\u6210\u4EA4\u91CF\u5206\u6790\u7B49\uFF09"),sessionId:p.string().optional().describe("\u4F1A\u8BDDID")}},async({queryName:e,analysisRequest:s,sessionId:i})=>{try{if(!e||typeof e!="string")return c(`\u67E5\u8BE2\u540D\u79F0\u65E0\u6548: ${e}\u3002\u8BF7\u63D0\u4F9B\u6B63\u786E\u7684\u67E5\u8BE2\u540D\u79F0\u3002`);const a=y(e),r=await A(e,a,i);if(!r)return c(`\u672A\u627E\u5230\u67E5\u8BE2 '${e}' \u7684\u7F13\u5B58\u6570\u636E\u3002\u8BF7\u5148\u4F7F\u7528 analyze_query \u5DE5\u5177\u83B7\u53D6\u6570\u636E\u3002`);if(r.queryName!==e)return c(`\u7F13\u5B58\u6570\u636E\u4E0D\u5339\u914D\uFF1A\u8BF7\u6C42\u67E5\u8BE2 '${e}'\uFF0C\u4F46\u7F13\u5B58\u6570\u636E\u5C5E\u4E8E '${r.queryName}'\u3002\u8BF7\u4F7F\u7528\u6B63\u786E\u7684\u67E5\u8BE2\u540D\u79F0\u3002`);const t=r.requestId,d=await x(t),u={type:"cached_data",hasData:!0,timestamp:new Date().toISOString(),status:"success",message:"\u4F7F\u7528\u7F13\u5B58\u6570\u636E\u8FDB\u884C\u6DF1\u5165\u5206\u6790",dataType:d.type||"unknown",recordCount:d.recordCount||0,totalSize:r.dataSize,chunks:r.chunks},n=b(s,t,u,{type:r.metadata.storageType,size:r.dataSize,chunks:r.chunks},a,R());return o({success:!0,requestId:t,queryName:e,dataSize:r.dataSize,storageType:r.metadata.storageType,message:n,analysisMode:"existing_data_analysis",dataReady:!0,analysisInstructions:"\u57FA\u4E8E\u5DF2\u6709\u7F13\u5B58\u6570\u636E\u8FDB\u884C\u6DF1\u5165\u5206\u6790\uFF01\u8BF7\u76F4\u63A5\u57FA\u4E8Emessage\u4E2D\u7684\u5206\u6790\u6307\u5F15\u8FDB\u884C\u8BE6\u7EC6\u5206\u6790\uFF0C\u65E0\u9700\u518D\u6B21\u8C03\u7528\u5DE5\u5177\u3002",querySpecific:!0,dataSource:e,warning:`\u8FD9\u662F\u57FA\u4E8E\u67E5\u8BE2 '${e}' \u5DF2\u6709\u6570\u636E\u7684\u6DF1\u5165\u5206\u6790\uFF0C\u8BF7\u4E25\u683C\u6309\u7167\u7528\u6237\u7684\u5177\u4F53\u5206\u6790\u9700\u6C42\u6267\u884C\uFF01**\u91CD\u8981\uFF1A\u786E\u4FDD\u4F7F\u7528\u6B63\u786E\u7684\u67E5\u8BE2\u540D\u79F0\uFF0C\u4E0D\u8981\u6DF7\u6DC6\u4E0D\u540C\u67E5\u8BE2\u7684\u6570\u636E\uFF01**`,cacheInfo:{hit:!0,cacheId:r.id,accessCount:r.accessCount+1,created:r.created,message:`\u4F7F\u7528\u7F13\u5B58\u6570\u636E\u8FDB\u884C\u6DF1\u5165\u5206\u6790 (\u5DF2\u8BBF\u95EE${r.accessCount+1}\u6B21)`},userRequest:s,contextAware:!0})}catch(a){return c(a)}});async function C(e,s){try{const i=process.env.DATA_STORE_ROOT||S.join(T.homedir(),".grafana-mcp-analyzer","data-store"),a=S.join(i,e),r=await import("fs/promises");await r.mkdir(a,{recursive:!0});const t={...s,lastUpdated:new Date().toISOString(),version:"1.0"};await r.writeFile(S.join(a,"workflow-state.json"),JSON.stringify(t,null,2))}catch(i){console.error(`[Workflow] \u4FDD\u5B58\u72B6\u6001\u5931\u8D25: ${i}`)}}async function E(e){try{const s=process.env.DATA_STORE_ROOT||S.join(T.homedir(),".grafana-mcp-analyzer","data-store"),i=S.join(s,e,"workflow-state.json"),r=await(await import("fs/promises")).readFile(i,"utf8");return JSON.parse(r)}catch{return null}}return k.registerTool("chunk_workflow",{title:"\u5206\u5757\u6570\u636E\u5DE5\u4F5C\u6D41",description:"**\u5FC5\u987B\u4F7F\u7528\u6B64\u5DE5\u5177\uFF01** \u8FD9\u662F\u7BA1\u7406\u5206\u5757\u6570\u636E\u83B7\u53D6\u5DE5\u4F5C\u6D41\u7684\u81EA\u52A8\u5316\u65B9\u5F0F\uFF01\u6B64\u5DE5\u5177\u4F1A\u81EA\u52A8\u7BA1\u7406\u5206\u5757\u83B7\u53D6\u6D41\u7A0B\uFF0C\u786E\u4FDD\u6570\u636E\u5B8C\u6574\u6027\u3002\u5FC5\u987B\u5148\u4F7F\u7528analyze_query\u5DE5\u5177\u5B58\u50A8\u6570\u636E\u3002**\u91CD\u8981\uFF1A\u5FC5\u987B\u8FDE\u7EED\u8C03\u7528next\u52A8\u4F5C\u76F4\u5230\u83B7\u53D6\u6240\u6709\u5206\u5757\uFF01\u4E0D\u80FD\u4E2D\u9014\u505C\u6B62\uFF01** \u652F\u6301\u81EA\u52A8\u6062\u590D\u548C\u8FDE\u7EED\u6267\u884C\uFF0CAI\u5FC5\u987B\u81EA\u52A8\u8FDE\u7EED\u8C03\u7528next\u52A8\u4F5C\u76F4\u5230\u5B8C\u6210\u3002**\u8B66\u544A\uFF1A\u83B7\u53D6\u5B8C\u6240\u6709\u5206\u5757\u540E\uFF0C\u5FC5\u987B\u7ACB\u5373\u8FDB\u884C\u5B8C\u6574\u5206\u6790\u5E76\u8F93\u51FA\u8BE6\u7EC6\u62A5\u544A\uFF01** **\u9632\u91CD\u590D\uFF1A\u6B64\u5DE5\u5177\u4F1A\u81EA\u52A8\u68C0\u6D4B\u91CD\u590D\u6267\u884C\u5E76\u963B\u6B62\uFF01**",inputSchema:{requestId:p.string().describe("\u8BF7\u6C42ID\uFF08\u5FC5\u987B\u5148\u4F7F\u7528analyze_query\u5DE5\u5177\u83B7\u53D6\uFF09"),action:p.enum(["start","next","status","complete"]).describe("\u5DE5\u4F5C\u6D41\u52A8\u4F5C\uFF1Astart(\u5F00\u59CB)/next(\u4E0B\u4E00\u4E2A\u5206\u5757)/status(\u72B6\u6001)/complete(\u5B8C\u6210)")}},async({requestId:e,action:s})=>{try{const i=await W(e),a=i.chunks.length,r=i.metadata.chunkingStrategy!=="full";let t=await E(e);t||(t={currentStep:0,retrievedChunks:[],status:"idle",totalChunks:0,lastAction:null,lastActionTime:null,executionCount:0});const d=Date.now(),u=t.lastActionTime?d-t.lastActionTime:0;if(t.lastAction===s&&u<1e3)return o({success:!1,requestId:e,message:`\u68C0\u6D4B\u5230\u91CD\u590D\u6267\u884C\uFF1A${s} \u52A8\u4F5C\u5728 ${u}ms \u524D\u521A\u6267\u884C\u8FC7`,workflow:{step:t.currentStep,totalSteps:a+1,status:t.status,retrievedChunks:t.retrievedChunks,lastAction:t.lastAction,timeSinceLastAction:u},instruction:"\u8BF7\u7B49\u5F851\u79D2\u540E\u518D\u6267\u884C\u76F8\u540C\u52A8\u4F5C\uFF0C\u6216\u6267\u884C\u5176\u4ED6\u52A8\u4F5C\u7EE7\u7EED\u5DE5\u4F5C\u6D41\u3002",duplicateAction:!0,retryAfter:1e3-u});switch(t.executionCount=(t.executionCount||0)+1,t.lastAction=s,t.lastActionTime=d,s){case"start":return t={currentStep:1,retrievedChunks:[],status:"running",totalChunks:a},await C(e,t),o({success:!0,requestId:e,message:r?`\u{1F680} \u5DE5\u4F5C\u6D41\u5DF2\u542F\u52A8\uFF01\u5171${a}\u4E2A\u5206\u5757\u9700\u8981\u83B7\u53D6\u3002`:"\u{1F680} \u5DE5\u4F5C\u6D41\u5DF2\u542F\u52A8\uFF01\u6570\u636E\u5DF2\u5B8C\u6574\u5B58\u50A8\uFF0C\u65E0\u9700\u5206\u5757\u3002",workflow:{step:1,totalSteps:a+1,action:r?"get_metadata":"get_full_data",nextAction:r?"get_chunk_1":"get_full_data"},instruction:r?"\u8BF7\u8C03\u7528\u6B64\u5DE5\u5177\u6267\u884C'next'\u52A8\u4F5C\u83B7\u53D6\u7B2C\u4E00\u4E2A\u5206\u5757\u3002":"\u8BF7\u8C03\u7528\u6B64\u5DE5\u5177\u6267\u884C'next'\u52A8\u4F5C\u83B7\u53D6\u5B8C\u6574\u6570\u636E\u3002"});case"next":t.status!=="running"&&(t={currentStep:1,retrievedChunks:[],status:"running",totalChunks:a},await C(e,t)),t.currentStep===0&&(t.currentStep=1,await C(e,t));const n=t.currentStep;if(n>a)return t.status="completed",await C(e,t),o({success:!0,requestId:e,message:`\u2705 \u5DE5\u4F5C\u6D41\u5B8C\u6210\uFF01\u5DF2\u83B7\u53D6\u6240\u6709${a}\u4E2A\u5206\u5757\u3002`,workflow:{step:a+1,totalSteps:a+1,status:"completed",retrievedChunks:t.retrievedChunks},instruction:`\u{1F6A8} **\u5FC5\u987B\u7ACB\u5373\u5206\u6790\uFF01** \u6240\u6709\u6570\u636E\u5DF2\u83B7\u53D6\u5B8C\u6210\uFF01\u73B0\u5728\u5FC5\u987B\u57FA\u4E8E\u83B7\u53D6\u5230\u7684${a}\u4E2A\u5206\u5757\u6570\u636E\u8FDB\u884C\u5B8C\u6574\u5206\u6790\u3002\u8BF7\u7ACB\u5373\u5F00\u59CB\u5206\u6790\u5E76\u8F93\u51FA\u8BE6\u7EC6\u62A5\u544A\uFF01**\u{1F6A8} \u91CD\u8981\uFF1A\u4E0D\u80FD\u505C\u6B62\uFF0C\u5FC5\u987B\u7ACB\u5373\u5F00\u59CB\u5206\u6790\uFF01\u8BF7\u4E25\u683C\u6309\u7167\u7528\u6237\u7684\u5177\u4F53\u5206\u6790\u9700\u6C42\u6267\u884C\uFF0C\u4E0D\u8981\u504F\u79BB\u7528\u6237\u7684\u8981\u6C42\uFF01**`,analysisRequired:!0,dataReady:!0,totalChunksRetrieved:a,dataSource:e.split("-")[2]||"unknown",warning:"\u26A0\uFE0F \u8FD9\u662F\u7279\u5B9A\u67E5\u8BE2\u7684\u5B8C\u6574\u6570\u636E\uFF0C\u5206\u6790\u65F6\u5FC5\u987B\u57FA\u4E8E\u6B64\u67E5\u8BE2\u7684\u6570\u636E\u7279\u5F81\uFF01"});const f=i.chunks.find(g=>g.index===n);if(!f){const m=i.chunks.map($=>$.index).sort(($,_)=>$-_).find($=>$>=n);return m?(t.currentStep=m,await C(e,t),o({success:!0,requestId:e,message:`\u{1F504} \u81EA\u52A8\u6062\u590D\uFF1A\u5206\u5757${n}\u4E0D\u5B58\u5728\uFF0C\u81EA\u52A8\u8DF3\u8F6C\u5230\u5206\u5757${m}`,workflow:{step:m,totalSteps:a+1,status:"recovered",retrievedChunks:t.retrievedChunks},instruction:`\u8BF7\u7EE7\u7EED\u8C03\u7528\u6B64\u5DE5\u5177\u6267\u884C'next'\u52A8\u4F5C\u83B7\u53D6\u5206\u5757${m}\u3002`,autoContinue:!0,nextStep:"next",recovery:!0})):c(`\u5206\u5757${n}\u4E0D\u5B58\u5728\uFF0C\u4E14\u6CA1\u6709\u53EF\u7528\u7684\u540E\u7EED\u5206\u5757`)}return t.retrievedChunks.push(n),t.currentStep=n+1,await C(e,t),o({success:!0,requestId:e,message:r?`\u{1F4E6} \u5206\u5757${n}/${a}\u83B7\u53D6\u6210\u529F\uFF01`:"\u{1F4E6} \u5B8C\u6574\u6570\u636E\u83B7\u53D6\u6210\u529F\uFF01",workflow:{step:n+1,totalSteps:a+1,progress:r?`${n}/${a}`:"1/1",retrievedChunks:t.retrievedChunks,nextAction:n<a?"get_chunk_"+(n+1):"complete"},chunk:{index:f.index,type:f.type,contentType:f.contentType,size:f.size,content:f.content},instruction:n<a&&r?`\u{1F6A8} **\u5FC5\u987B\u7EE7\u7EED\u6267\u884C\uFF01** \u8BF7\u7ACB\u5373\u8C03\u7528\u6B64\u5DE5\u5177\u6267\u884C'next'\u52A8\u4F5C\u83B7\u53D6\u4E0B\u4E00\u4E2A\u5206\u5757\u3002\u8FD8\u6709${a-n}\u4E2A\u5206\u5757\u9700\u8981\u83B7\u53D6\u3002**\u91CD\u8981\uFF1A\u4E0D\u80FD\u505C\u6B62\uFF0C\u5FC5\u987B\u83B7\u53D6\u6240\u6709\u5206\u5757\uFF01**`:"\u8BF7\u8C03\u7528\u6B64\u5DE5\u5177\u6267\u884C'complete'\u52A8\u4F5C\u5B8C\u6210\u5DE5\u4F5C\u6D41\u3002",autoContinue:n<a&&r,nextStep:n<a?"next":"complete",remainingChunks:a-n,progress:`${n}/${a}`,dataSource:e.split("-")[2]||"unknown",warning:"\u26A0\uFE0F \u8FD9\u662F\u7279\u5B9A\u67E5\u8BE2\u7684\u6570\u636E\u5206\u5757\uFF0C\u4E0D\u80FD\u4E0E\u5176\u4ED6\u67E5\u8BE2\u6570\u636E\u6DF7\u6DC6\uFF01",forceContinue:n<a&&r,criticalMessage:n<a?`\u{1F6A8} \u8B66\u544A\uFF1A\u8FD8\u6709${a-n}\u4E2A\u5206\u5757\u672A\u83B7\u53D6\uFF01\u5FC5\u987B\u7EE7\u7EED\u6267\u884C\uFF01`:null});case"status":return o({success:!0,requestId:e,message:`\u{1F4CA} \u5DE5\u4F5C\u6D41\u72B6\u6001\uFF1A${t.status}`,workflow:{step:t.currentStep,totalSteps:a+1,progress:t.retrievedChunks.length>0?`${t.retrievedChunks.length}/${a}`:"0/0",retrievedChunks:t.retrievedChunks,status:t.status}});case"complete":return t.status="completed",await C(e,t),o({success:!0,requestId:e,message:`\u2705 \u5DE5\u4F5C\u6D41\u5DF2\u5B8C\u6210\uFF01\u5171\u83B7\u53D6\u4E86${t.retrievedChunks.length}\u4E2A\u5206\u5757\u3002`,workflow:{step:a+1,totalSteps:a+1,status:"completed",retrievedChunks:t.retrievedChunks},instruction:`\u{1F6A8} **\u5FC5\u987B\u7ACB\u5373\u5206\u6790\uFF01** \u6240\u6709\u6570\u636E\u5DF2\u83B7\u53D6\u5B8C\u6210\uFF01\u73B0\u5728\u5FC5\u987B\u57FA\u4E8E\u83B7\u53D6\u5230\u7684${t.retrievedChunks.length}\u4E2A\u5206\u5757\u6570\u636E\u8FDB\u884C\u5B8C\u6574\u5206\u6790\u3002\u8BF7\u7ACB\u5373\u5F00\u59CB\u5206\u6790\u5E76\u8F93\u51FA\u8BE6\u7EC6\u62A5\u544A\uFF01**\u{1F6A8} \u91CD\u8981\uFF1A\u4E0D\u80FD\u505C\u6B62\uFF0C\u5FC5\u987B\u7ACB\u5373\u5F00\u59CB\u5206\u6790\uFF01\u8BF7\u4E25\u683C\u6309\u7167\u7528\u6237\u7684\u5177\u4F53\u5206\u6790\u9700\u6C42\u6267\u884C\uFF0C\u4E0D\u8981\u504F\u79BB\u7528\u6237\u7684\u8981\u6C42\uFF01**`,analysisRequired:!0,dataReady:!0,totalChunksRetrieved:t.retrievedChunks.length,dataSource:e.split("-")[2]||"unknown",warning:"\u26A0\uFE0F \u8FD9\u662F\u7279\u5B9A\u67E5\u8BE2\u7684\u5B8C\u6574\u6570\u636E\uFF0C\u5206\u6790\u65F6\u5FC5\u987B\u57FA\u4E8E\u6B64\u67E5\u8BE2\u7684\u6570\u636E\u7279\u5F81\uFF01"});default:return c("\u65E0\u6548\u7684\u5DE5\u4F5C\u6D41\u52A8\u4F5C")}}catch(i){console.error(`[Chunk Workflow Tool] \u5DE5\u4F5C\u6D41\u6267\u884C\u5931\u8D25: ${i.message}`);const a={success:!1,requestId:e,error:i.message,timestamp:new Date().toISOString(),instruction:"\u5DE5\u4F5C\u6D41\u6267\u884C\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u8BF7\u6C42ID\u662F\u5426\u6B63\u786E\uFF0C\u6216\u91CD\u65B0\u6267\u884Canalyze_query\u5DE5\u5177\u83B7\u53D6\u65B0\u7684\u8BF7\u6C42ID\u3002",recovery:{suggestion:"\u91CD\u65B0\u6267\u884Canalyze_query\u5DE5\u5177",retryAction:"analyze_query"}};return o(a,!0)}}),k}export{he as createMcpServer};