UNPKG

@thinking-models/mcp-server

Version:

A Model Context Protocol (MCP) server for thinking models

1,299 lines 118 kB
#!/usr/bin/env node import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; import fs from "fs/promises"; import path from "path"; import { watch } from "fs"; import { fileURLToPath } from "url"; import { log } from "./utils.js"; import { calculateKeywordRelevance, calculateQueryMatch } from "./similarity_engine.js"; import { getModelRecommendations, RecommendationMode } from "./recommendations.js"; import { createReasoningPath, addReasoningStep, setReasoningConclusion, formatReasoningPath, visualizeReasoningPath } from "./reasoning_process.js"; import { loadLearningSystemState, recordUserFeedback, detectKnowledgeGap, getModelUsageStats, getKnowledgeGaps, getModelFeedbackHistory, analyzeModelUsage, adjustModelRecommendations } from "./learning_capability.js"; // 兼容ESM的__dirname(修正Windows路径问题) const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); /** * 从package.json文件中获取版本号 * @returns {Promise<string>} 版本号 */ async function getPackageVersion() { try { const packageJsonPath = path.resolve(__dirname, '..', 'package.json'); const packageJsonContent = await fs.readFile(packageJsonPath, 'utf-8'); const packageJson = JSON.parse(packageJsonContent); return packageJson.version || '未知版本'; } catch (error) { log(`无法获取package.json版本信息: ${error instanceof Error ? error.message : String(error)}`); return '未知版本'; } } // 支持的语言及对应文件目录 const SUPPORTED_LANGUAGES = { zh: "thinking_models_db/zh", // 指向中文模型目录 en: "thinking_models_db/en" // 指向英文模型目录 }; // 模型数据缓存 const MODELS = { zh: [], en: [] }; // 加载模型数据 async function loadModels(lang) { const langsToLoad = lang ? [lang] : Object.keys(SUPPORTED_LANGUAGES); for (const l of langsToLoad) { const langDir = path.resolve(__dirname, "..", SUPPORTED_LANGUAGES[l]); MODELS[l] = []; // 清空旧数据以便重新加载 try { log(`开始加载语言 '${l}' 从目录 ${langDir} ...`); const files = await fs.readdir(langDir); let loadedCount = 0; let totalSizeKb = 0; for (const file of files) { if (path.extname(file).toLowerCase() === ".json") { const filePath = path.join(langDir, file); try { const content = await fs.readFile(filePath, "utf-8"); const model = JSON.parse(content); // 假设每个文件是一个模型对象 MODELS[l].push(model); loadedCount++; totalSizeKb += (await fs.stat(filePath)).size / 1024; } catch (e) { log(`加载或解析模型文件 ${filePath} 失败: ${e.message}`); } } } log(`语言 '${l}' 加载完成,共 ${loadedCount} 个模型, 总大小: ${totalSizeKb.toFixed(2)}KB`); } catch (e) { log(`加载语言 '${l}' 的模型目录 ${langDir} 失败: ${e.message}`); MODELS[l] = []; // 确保出错时数据为空 } } } // 创建 MCP Server 实例 const packageVersion = await getPackageVersion(); log(`启动思维模型MCP服务器,版本: ${packageVersion}`); const server = new McpServer({ name: "thinking_models", version: packageVersion, capabilities: { resources: {}, tools: {}, }, }); // 初始加载所有语言的模型 await loadModels(); // 加载学习系统状态 try { await loadLearningSystemState(); log("学习系统状态已加载"); } catch (err) { log(`加载学习系统状态失败: ${err.message}`); } // 监控模型文件变化 for (const [lang, dirPath] of Object.entries(SUPPORTED_LANGUAGES)) { const langDir = path.resolve(__dirname, "..", dirPath); try { // 确保目录存在 await fs.access(langDir); watch(langDir, { recursive: false }, async (eventType, filename) => { if (filename && path.extname(filename).toLowerCase() === ".json") { log(`${langDir}/${filename} 发生变化,重新加载语言 '${lang}'...`); await loadModels(lang); } }); log(`正在监控目录: ${langDir}`); } catch (e) { log(`模型目录 ${langDir} 不存在或无法访问,跳过监控`); } } // 扩展的 list-models 工具实现 - 合并 list-models 和 get-models-by-category server.tool("list-models", "获取指定语言的思维模型列表,支持按分类过滤", { lang: z.enum(["zh", "en"]).default("zh").describe("语言代码('zh' 或 'en'),默认为 'zh'"), category: z.string().optional().describe("主分类名称(可选)"), subcategory: z.string().optional().describe("子分类名称(可选,需同时提供主分类)"), limit: z.number().optional().default(100).describe("返回结果数量限制,默认为100") }, async ({ lang, category, subcategory, limit }) => { try { if (subcategory && !category) { return { content: [{ type: "text", text: JSON.stringify({ error: "提供子分类时必须同时提供主分类" }, null, 2) }] }; } let models = [...MODELS[lang]]; let filterDesc = ""; // 根据分类过滤 if (category) { filterDesc = `分类 '${category}'`; models = models.filter(m => m.category === category); // 根据子分类进一步过滤 if (subcategory) { filterDesc += ` 和子分类 '${subcategory}'`; models = models.filter(m => m.subcategories?.includes(subcategory)); } } // 映射到简要信息 const result = models .slice(0, limit) .map(m => ({ id: m.id, name: m.name, definition: m.definition || "", purpose: m.purpose || "", category: m.category || "", subcategories: m.subcategories || [] })); log(`获取模型列表${filterDesc ? `(按${filterDesc}过滤)` : ""},找到 ${models.length} 个模型,返回 ${result.length} 个结果`); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; } catch (e) { log(`获取模型列表时出错: ${e.message}`); return { content: [{ type: "text", text: JSON.stringify({ error: "服务异常", message: e.message }, null, 2) }] }; } }); // 注册工具: search_models // 重构 search-models 工具实现,专注于文本搜索功能 server.tool("search-models", "在指定语言的思维模型中根据关键词进行文本搜索", { query: z.string().describe("搜索关键词"), lang: z.enum(["zh", "en"]).default("zh").describe("语言代码('zh' 或 'en'),默认为 'zh'"), limit: z.number().optional().default(10).describe("返回结果数量限制,默认为10") }, async ({ query, lang, limit }) => { try { log(`开始在 ${lang} 语言中搜索关键词: "${query}"`); if (!query || query.trim() === "") { return { content: [{ type: "text", text: JSON.stringify({ error: "搜索关键词不能为空" }, null, 2) }] }; } const results = []; // 对每个模型应用我们的查询匹配算法 for (const model of MODELS[lang]) { const { score, reasons } = calculateQueryMatch(model, query); if (score > 0) { results.push({ id: model.id, name: model.name, definition: model.definition || "", purpose: model.purpose || "", match_score: score, match_reasons: reasons }); } } // 限制返回结果数量 const limitedResults = results.slice(0, limit); log(`搜索完成,找到 ${results.length} 个匹配的模型,返回 ${limitedResults.length} 个结果`); return { content: [{ type: "text", text: JSON.stringify(limitedResults, null, 2) }] }; } catch (e) { log(`搜索模型时出错: ${e.message}`); return { content: [{ type: "text", text: JSON.stringify({ error: "服务异常", message: e.message }, null, 2) }] }; } }); // 新增 recommend-models-for-problem 工具实现,专门处理问题推荐 server.tool("recommend-models-for-problem", "基于问题关键词推荐适合解决特定问题的思维模型", { problem_keywords: z.array(z.string()).min(1).describe("问题关键词数组"), problem_context: z.string().optional().describe("问题的完整上下文描述"), lang: z.enum(["zh", "en"]).default("zh").describe("语言代码('zh' 或 'en'),默认为 'zh'"), limit: z.number().optional().default(10).describe("返回结果数量限制,默认为10"), use_learning_adjustment: z.boolean().optional().default(true).describe("是否使用学习系统调整推荐结果") }, async ({ problem_keywords, problem_context, lang, limit, use_learning_adjustment }) => { try { log(`开始在 ${lang} 语言中基于问题关键词推荐模型`); if (!problem_keywords || problem_keywords.length === 0) { return { content: [{ type: "text", text: JSON.stringify({ error: "问题关键词不能为空" }, null, 2) }] }; } const results = []; // 对每个模型计算与问题关键词的相关度 for (const model of MODELS[lang]) { const { score, reasons } = calculateKeywordRelevance(model, problem_keywords); if (score > 0) { results.push({ id: model.id, name: model.name, definition: model.definition || "", purpose: model.purpose || "", match_score: score, match_reasons: reasons }); } } // 调整推荐结果(如果启用了学习调整) let adjustedResults = [...results]; if (use_learning_adjustment && problem_context) { // 转换为学习调整所需的格式 const simpleResults = results.map(r => ({ id: r.id, score: r.match_score })); // 获取学习调整结果 const adjusted = adjustModelRecommendations(simpleResults, problem_context); // 合并调整后的分数和原始结果 adjustedResults = results.map(r => { const adjustedItem = adjusted.find(a => a.id === r.id); if (adjustedItem && adjustedItem.adjustment_reason) { return { ...r, match_score: adjustedItem.score, adjustment_reason: adjustedItem.adjustment_reason }; } return r; }); } // 按评分排序 adjustedResults.sort((a, b) => b.match_score - a.match_score); // 限制返回结果数量 const limitedResults = adjustedResults.slice(0, limit); log(`推荐完成,找到 ${results.length} 个适合的模型,返回 ${limitedResults.length} 个结果`); return { content: [{ type: "text", text: JSON.stringify({ models: limitedResults, learning_adjusted: use_learning_adjustment && problem_context ? true : false, total_models_matched: results.length }, null, 2) }] }; } catch (e) { log(`推荐模型时出错: ${e.message}`); return { content: [{ type: "text", text: JSON.stringify({ error: "服务异常", message: e.message }, null, 2) }] }; } }); // 统一的 get-model-info 工具实现 - 合并 get-model-detail、get-model-teaching、get-model-warnings 和 get-model-visualizations server.tool("get-model-info", "获取思维模型的详细信息或特定字段", { model_id: z.string().describe("思维模型的唯一id"), fields: z.array(z.enum(["all", "basic", "detail", "teaching", "warnings", "visualizations"])).optional().default(["basic"]).describe("需要返回的字段,如 'all'(全部), 'basic'(基本信息), 'detail'(详细信息), 'teaching'(教学内容), 'warnings'(注意事项), 'visualizations'(可视化)"), lang: z.enum(["zh", "en"]).default("zh").describe("语言代码('zh' 或 'en'),默认为 'zh'"), }, async ({ model_id, fields, lang }) => { try { log(`获取模型 ID: ${model_id} 的信息,请求的字段: ${fields.join(', ')}`); const model = MODELS[lang].find(m => m.id === model_id); if (!model) { log(`未找到模型 ID: ${model_id}`); return { content: [{ type: "text", text: JSON.stringify({ error: "未找到该模型" }, null, 2) }] }; } const includeAll = fields.includes("all"); const result = {}; // 基本信息(默认始终包含) if (includeAll || fields.includes("basic")) { result.id = model.id; result.name = model.name; result.category = model.category; result.subcategories = model.subcategories || []; result.tags = model.tags || []; } // 详细信息 if (includeAll || fields.includes("detail")) { result.detail = { definition: model.definition || "", purpose: model.purpose || "", use_cases: model.use_cases || [], }; } // 教学内容 if (includeAll || fields.includes("teaching")) { result.teaching = model.popular_science_teaching || []; } // 使用注意事项(包含局限性和常见误区) if (includeAll || fields.includes("warnings")) { result.warnings = { limitations: model.limitations || [], common_pitfalls: model.common_pitfalls || [] }; } // 可视化数据 if (includeAll || fields.includes("visualizations")) { result.visualizations = model.visualizations || []; } // 能解决的问题 if (includeAll) { result.common_problems_solved = model.common_problems_solved || []; } log(`成功返回模型信息,包含字段: ${Object.keys(result).join(', ')}`); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; } catch (e) { log(`获取模型信息时出错: ${e.message}`); return { content: [{ type: "text", text: JSON.stringify({ error: "服务异常", message: e.message }, null, 2) }] }; } }); // 修改 get-categories 工具实现 server.tool("get-categories", "获取所有思维模型的分类信息", { lang: z.enum(["zh", "en"]).default("zh").describe("语言代码('zh' 或 'en'),默认为 'zh'"), }, async ({ lang }) => { try { const categories = {}; for (const model of MODELS[lang]) { const category = model.category || "未分类"; if (!categories[category]) { categories[category] = new Set(); } const subcats = model.subcategories || []; subcats.forEach(subcat => categories[category].add(subcat)); } // 将 Set 转换为数组以便 JSON 序列化 const result = Object.fromEntries(Object.entries(categories).map(([cat, subcats]) => [cat, Array.from(subcats).sort()])); log(`成功获取分类信息:${Object.keys(result).length} 个主分类`); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; } catch (e) { log(`获取分类信息时出错: ${e.message}`); return { content: [{ type: "text", text: "{}" }] }; } }); // 重构 get-related-models 工具实现,专注于基于模型相似性的推荐 server.tool("get-related-models", "获取与特定思维模型相关的模型推荐", { model_id: z.string().describe("思维模型的唯一id"), lang: z.enum(["zh", "en"]).default("zh").describe("语言代码('zh' 或 'en'),默认为 'zh'"), use_enhanced_similarity: z.boolean().optional().default(true).describe("是否使用增强的相似度评估(如果为false则使用基础算法)"), limit: z.number().optional().default(5).describe("返回结果数量限制,默认为5") }, async ({ model_id, lang, use_enhanced_similarity, limit }) => { try { // 查找源模型 const source_model = MODELS[lang].find(m => m.id === model_id); if (!source_model) { log(`未找到模型 ID: ${model_id}`); return { content: [{ type: "text", text: JSON.stringify({ error: "未找到指定模型" }, null, 2) }] }; } // 过滤出候选模型(不包括源模型自身) const candidateModels = MODELS[lang].filter(m => m.id !== model_id); // 根据参数确定使用哪种推荐模式 const mode = use_enhanced_similarity && candidateModels.length <= 50 ? RecommendationMode.ENHANCED : RecommendationMode.BASIC; log(`使用${mode}模式为「${source_model.name}」生成相关思维模型推荐`); // 使用统一的推荐系统获取推荐结果 const recommendations = await getModelRecommendations(source_model, candidateModels, lang, mode, limit); log(`成功生成${recommendations.length}个相关模型推荐`); return { content: [{ type: "text", text: JSON.stringify(recommendations, null, 2) }] }; } catch (e) { log(`获取相关模型推荐时出错: ${e.message}`); return { content: [{ type: "text", text: JSON.stringify({ error: "服务异常", message: e.message }, null, 2) }] }; } }); // 添加推理过程透明化工具 server.tool("explain-reasoning-process", "解释模型的推理过程和应用的思维模式", { problemDescription: z.string().describe("问题或情境描述"), reasoningSteps: z.array(z.object({ description: z.string().describe("推理步骤描述"), modelIds: z.array(z.string()).optional().describe("使用的思维模型ID"), evidence: z.array(z.string()).optional().describe("支持证据"), confidence: z.number().optional().default(0.8).describe("置信度(0-1)") })).describe("推理步骤详情"), conclusion: z.string().describe("推理结论"), lang: z.enum(["zh", "en"]).default("zh").describe("语言代码") }, async ({ problemDescription, reasoningSteps, conclusion, lang }) => { try { log(`开始构建推理路径,问题: "${problemDescription.substring(0, 50)}...",${reasoningSteps.length} 个步骤`); // 1. 创建初始推理路径 let path = createReasoningPath(problemDescription); // 2. 添加每个推理步骤 for (const step of reasoningSteps) { path = addReasoningStep(path, step.description, step.evidence || [], step.confidence || 0.8, step.modelIds || []); } // 3. 添加结论 path = setReasoningConclusion(path, conclusion); // 4. 获取所有模型信息用于格式化 const modelsMap = {}; const modelIds = new Set(); // 收集使用到的所有模型ID reasoningSteps.forEach(step => { if (step.modelIds) { step.modelIds.forEach(id => modelIds.add(id)); } }); // 获取模型详细信息 for (const modelId of modelIds) { const model = MODELS[lang].find(m => m.id === modelId); if (model) { modelsMap[modelId] = model; } } // 5. 格式化输出结果 const formattedPath = formatReasoningPath(path, modelsMap); // 6. 创建可视化数据 const visualData = visualizeReasoningPath(path); log(`成功构建推理路径,包含 ${path.steps.length} 个步骤,使用了 ${modelIds.size} 个思维模型`); return { content: [{ type: "text", text: JSON.stringify({ formatted_text: formattedPath, visualization_data: visualData, path_data: path }, null, 2) }] }; } catch (e) { log(`解释推理过程时出错: ${e.message}`); return { content: [{ type: "text", text: JSON.stringify({ error: "处理推理过程时出错", message: e.message }, null, 2) }] }; } }); // 交互式推理工具 server.tool("interactive-reasoning", "交互式推理过程,允许动态获取额外信息", { initialContext: z.string().describe("初始问题或情境描述"), reasoningStage: z.enum(["information_gathering", "hypothesis_generation", "hypothesis_testing", "conclusion"]).describe("当前推理阶段"), currentPathId: z.string().optional().describe("当前推理路径ID(如果在现有推理中)"), requiredInformation: z.array(z.string()).optional().describe("需要获取的额外信息"), lang: z.enum(["zh", "en"]).default("zh").describe("语言代码") }, async ({ initialContext, reasoningStage, currentPathId, requiredInformation, lang }) => { try { // 根据推理阶段生成指导性问题或建议 let suggestedActions = []; let relevantModels = []; // 根据不同阶段提供不同类型的指导 switch (reasoningStage) { case "information_gathering": // 推荐5个适合信息收集阶段的思维模型 relevantModels = MODELS[lang].filter(m => (m.tags || []).some(tag => ["信息收集", "数据分析", "问题定义", "information gathering", "data analysis"].includes(tag.toLowerCase()))).slice(0, 5); suggestedActions = [ "明确问题的关键信息维度", "确定数据收集的范围和边界", "识别潜在的信息盲点", "考虑可能的信息偏差", "确定信息的可靠性评估标准" ]; break; case "hypothesis_generation": // 推荐适合假设生成阶段的思维模型 relevantModels = MODELS[lang].filter(m => (m.tags || []).some(tag => ["创造性思维", "假设生成", "发散思考", "creative thinking", "hypothesis generation"].includes(tag.toLowerCase()))).slice(0, 5); suggestedActions = [ "考虑多个可能的解释", "应用反向思考质疑常规观点", "寻找现有理论的限制", "尝试结合不同领域的视角", "考虑极端情况以扩展思考范围" ]; break; case "hypothesis_testing": // 推荐适合假设测试阶段的思维模型 relevantModels = MODELS[lang].filter(m => (m.tags || []).some(tag => ["批判性思维", "验证", "评估", "critical thinking", "validation"].includes(tag.toLowerCase()))).slice(0, 5); suggestedActions = [ "设计可证伪的测试", "寻找反面证据", "评估假设的内部一致性", "考虑替代假设的解释力", "检验预测与观察结果的匹配度" ]; break; case "conclusion": // 推荐适合结论形成阶段的思维模型 relevantModels = MODELS[lang].filter(m => (m.tags || []).some(tag => ["决策制定", "综合分析", "结论形成", "decision making", "synthesis"].includes(tag.toLowerCase()))).slice(0, 5); suggestedActions = [ "评估结论的可靠性和局限性", "考虑结论的实际应用价值", "识别需要进一步验证的环节", "提出后续行动建议", "明确结论的适用条件和边界" ]; break; } // 格式化推荐模型信息 const recommendedModels = relevantModels.map(model => ({ id: model.id, name: model.name, definition: model.definition || "", purpose: model.purpose || "", why_useful: `在${reasoningStage === "information_gathering" ? "信息收集" : reasoningStage === "hypothesis_generation" ? "假设生成" : reasoningStage === "hypothesis_testing" ? "假设验证" : "结论形成"}阶段特别有用` })); log(`为推理阶段 ${reasoningStage} 生成了交互式指导`); return { content: [{ type: "text", text: JSON.stringify({ reasoning_stage: reasoningStage, suggested_actions: suggestedActions, recommended_models: recommendedModels, required_information: requiredInformation || [] }, null, 2) }] }; } catch (e) { log(`交互式推理工具出错: ${e.message}`); return { content: [{ type: "text", text: JSON.stringify({ error: "交互式推理过程失败", message: e.message }, null, 2) }] }; } }); // 假设生成与验证工具 server.tool("generate-validate-hypotheses", "为问题生成多个假设并提供验证方法", { problem: z.string().describe("要解决的问题"), context: z.string().describe("问题相关的背景信息"), lang: z.enum(["zh", "en"]).default("zh").describe("语言代码") }, async ({ problem, context, lang }) => { try { log(`开始为问题生成假设: "${problem.substring(0, 50)}..."`); // 查找与问题相关的思维模型 const relevantModels = []; for (const model of MODELS[lang]) { const { score } = calculateQueryMatch(model, problem + " " + context); if (score > 0) { relevantModels.push({ id: model.id, name: model.name, definition: model.definition || "", score: score }); } } // 按相关性排序并取前3个 const topModels = relevantModels .sort((a, b) => b.score - a.score) .slice(0, 3); // 基于思维模型生成假设 const hypotheses = [ { statement: `基于${topModels[0]?.name || '系统分析'}的假设:问题可能源于...`, supporting_evidence: ["背景信息中的关键点A", "领域内常见的模式B"], testing_methods: [ "收集特定数据进行验证", "对比不同场景下的结果", "设计一个小规模实验" ], confidence: 0.75, related_model: topModels[0]?.id || "" }, { statement: `替代假设:从${topModels[1]?.name || '反向思考'}角度看,问题可能是...`, supporting_evidence: ["背景中被忽视的因素X", "相关研究中的特例Y"], testing_methods: [ "分析极端情况", "寻找反例", "验证关键假设条件" ], confidence: 0.65, related_model: topModels[1]?.id || "" }, { statement: `综合假设:结合${topModels[2]?.name || '系统思维'},可能的解释是...`, supporting_evidence: ["综合因素1和因素2", "系统层面的观察"], testing_methods: [ "建立关键指标并测量", "进行对照实验", "寻求专家评估" ], confidence: 0.7, related_model: topModels[2]?.id || "" } ]; log(`成功生成假设并提供验证方法`); return { content: [{ type: "text", text: JSON.stringify({ problem: problem, hypotheses: hypotheses, relevant_models: topModels }, null, 2) }] }; } catch (e) { log(`生成假设时出错: ${e.message}`); return { content: [{ type: "text", text: JSON.stringify({ error: "生成假设验证过程失败", message: e.message }, null, 2) }] }; } }); // 修改 count-models 工具实现 server.tool("count-models", "统计当前思维模型的总数", { lang: z.enum(["zh", "en"]).default("zh").describe("语言代码('zh' 或 'en'),默认为 'zh'"), }, async ({ lang }) => { try { const count = MODELS[lang].length; log(`当前语言 '${lang}' 下共有 ${count} 个思维模型`); return { content: [{ type: "text", text: count.toString() }] }; } catch (e) { log(`统计思维模型总数时出错: ${e.message}`); return { content: [{ type: "text", text: "0" }] }; } }); // 添加用户反馈收集工具 server.tool("record-user-feedback", "记录用户对思维模型使用体验的反馈", { modelIds: z.array(z.string()).describe("相关思维模型的ID数组"), context: z.string().describe("应用模型的上下文或问题描述"), feedbackType: z.enum(["helpful", "not_helpful", "incorrect", "insightful", "confusing"]).describe("反馈类型"), comment: z.string().optional().describe("反馈详细说明或评论"), applicationResult: z.string().optional().describe("模型应用结果描述"), suggestedImprovements: z.array(z.string()).optional().describe("建议的改进点"), lang: z.enum(["zh", "en"]).default("zh").describe("语言代码") }, async ({ modelIds, context, feedbackType, comment, applicationResult, suggestedImprovements, lang }) => { try { log(`接收到用户反馈,类型:${feedbackType}, 相关模型:${modelIds.join(", ")}`); // 转换反馈类型为内部枚举类型 const internalFeedbackType = feedbackType === "helpful" ? "helpful" : feedbackType === "not_helpful" ? "not_helpful" : feedbackType === "incorrect" ? "incorrect" : feedbackType === "insightful" ? "insightful" : "confusing"; // 记录用户反馈 const feedback = recordUserFeedback(modelIds, context, internalFeedbackType, comment, applicationResult, suggestedImprovements); // 检查并记录潜在的知识缺口 if (internalFeedbackType === "not_helpful" || internalFeedbackType === "incorrect" || internalFeedbackType === "confusing") { const matchedModels = modelIds.map(id => MODELS[lang].find(m => m.id === id)).filter(Boolean); detectKnowledgeGap(context, matchedModels); } log(`用户反馈已记录,ID: ${feedback.feedbackId}`); return { content: [{ type: "text", text: JSON.stringify({ success: true, message: "反馈已成功记录", feedbackId: feedback.feedbackId }, null, 2) }] }; } catch (e) { log(`记录用户反馈时出错: ${e.message}`); return { content: [{ type: "text", text: JSON.stringify({ error: "记录用户反馈失败", message: e.message }, null, 2) }] }; } }); // 添加知识缺口识别工具 server.tool("detect-knowledge-gap", "检测用户查询中的知识缺口", { query: z.string().describe("用户查询或问题"), lang: z.enum(["zh", "en"]).default("zh").describe("语言代码"), matchThreshold: z.number().optional().default(0.5).describe("匹配阈值,低于此值视为知识缺口") }, async ({ query, lang, matchThreshold }) => { try { log(`分析查询中潜在的知识缺口: "${query.substring(0, 50)}..."`); // 先执行标准搜索,找出最匹配的模型 const matchedModels = []; for (const model of MODELS[lang]) { const { score } = calculateQueryMatch(model, query); if (score > 0) { matchedModels.push(model); } } // 检测知识缺口 const gap = detectKnowledgeGap(query, matchedModels, matchThreshold); if (gap) { log(`发现知识缺口: ${gap.description}`); // 查找可能相关的模型 const possibleRelatedModels = MODELS[lang] .map(model => { const { score } = calculateQueryMatch(model, gap.description); return { model, score }; }) .filter(item => item.score > 0) .sort((a, b) => b.score - a.score) .slice(0, 3) .map(item => ({ id: item.model.id, name: item.model.name, relevance: item.score })); return { content: [{ type: "text", text: JSON.stringify({ has_knowledge_gap: true, gap_id: gap.gapId, description: gap.description, detection_count: gap.detectionCount, possible_tags: gap.possibleTags, suggested_models: possibleRelatedModels, recommendations: [ "考虑添加新的思维模型", "扩展现有模型的标签和关键词", "收集更多用户反馈" ] }, null, 2) }] }; } else { log(`未发现知识缺口`); return { content: [{ type: "text", text: JSON.stringify({ has_knowledge_gap: false, matched_models_count: matchedModels.length }, null, 2) }] }; } } catch (e) { log(`检测知识缺口时出错: ${e.message}`); return { content: [{ type: "text", text: JSON.stringify({ error: "检测知识缺口失败", message: e.message }, null, 2) }] }; } }); // 获取模型使用统计工具 server.tool("get-model-usage-stats", "获取思维模型的使用统计数据", { modelId: z.string().describe("思维模型的唯一ID"), lang: z.enum(["zh", "en"]).default("zh").describe("语言代码") }, async ({ modelId, lang }) => { try { log(`获取模型 ${modelId} 的使用统计`); // 检查模型是否存在 const model = MODELS[lang].find(m => m.id === modelId); if (!model) { return { content: [{ type: "text", text: JSON.stringify({ error: "未找到指定模型" }, null, 2) }] }; } // 获取使用统计 const stats = getModelUsageStats(modelId); // 获取反馈历史 const feedbackHistory = getModelFeedbackHistory(modelId); if (!stats) { return { content: [{ type: "text", text: JSON.stringify({ modelId, modelName: model.name, message: "该模型暂无使用数据" }, null, 2) }] }; } // 从反馈中提取关键洞察 const insights = []; if (stats.averageHelpfulness > 0.7 && stats.usageCount >= 5) { insights.push("该模型获得了很高的正面评价"); } else if (stats.averageHelpfulness < 0.3 && stats.usageCount >= 5) { insights.push("该模型获得的负面评价较多,可能需要改进"); } if (stats.commonContexts.length > 0) { insights.push("该模型在特定上下文中被频繁使用"); } return { content: [{ type: "text", text: JSON.stringify({ modelId, modelName: model.name, usage_count: stats.usageCount, positive_feedback_ratio: stats.averageHelpfulness, positive_count: stats.positiveCount, negative_count: stats.negativeCount, common_contexts: stats.commonContexts, feedback_count: feedbackHistory.length, insights }, null, 2) }] }; } catch (e) { log(`获取模型使用统计时出错: ${e.message}`); return { content: [{ type: "text", text: JSON.stringify({ error: "获取使用统计失败", message: e.message }, null, 2) }] }; } }); // 学习系统总体分析工具 server.tool("analyze-learning-system", "分析思维模型学习系统的总体状况", { lang: z.enum(["zh", "en"]).default("zh").describe("语言代码") }, async ({ lang }) => { try { log(`分析学习系统整体状况`); // 获取系统分析数据 const analysis = analyzeModelUsage(); // 获取知识缺口 const knowledgeGaps = getKnowledgeGaps(5); // 获取前5个知识缺口 // 为知识缺口添加可能相关的模型 const gapsWithSuggestions = knowledgeGaps.map(gap => { // 找出可能相关的模型 const suggestedModels = MODELS[lang] .map(model => { const { score } = calculateQueryMatch(model, gap.description); return { id: model.id, name: model.name, score }; }) .filter(item => item.score > 0.3) // 只保留相关度较高的 .sort((a, b) => b.score - a.score) .slice(0, 3); return { ...gap, suggested_models: suggestedModels }; }); return { content: [{ type: "text", text: JSON.stringify({ system_stats: analysis, top_knowledge_gaps: gapsWithSuggestions, recommendations: [ "持续收集用户反馈以改进模型推荐", "考虑添加新模型以填补知识缺口", "关注用户体验不佳的模型并考虑改进" ] }, null, 2) }] }; } catch (e) { log(`分析学习系统时出错: ${e.message}`); return { content: [{ type: "text", text: JSON.stringify({ error: "分析学习系统失败", message: e.message }, null, 2) }] }; } }); // 添加获取服务器版本信息的工具 server.tool("get-server-version", "获取思维模型MCP服务器的版本和状态信息", {}, async () => { try { const version = await getPackageVersion(); const serverStartupTime = new Date().toISOString(); // 收集模型统计信息 const modelStats = Object.entries(MODELS).reduce((stats, [lang, models]) => { stats[lang] = models.length; return stats; }, {}); return { content: [{ type: "text", text: JSON.stringify({ version, server_name: "thinking_models", startup_time: serverStartupTime, model_stats: modelStats, supported_languages: Object.keys(SUPPORTED_LANGUAGES), server_status: "running" }, null, 2) }] }; } catch (e) { log(`获取服务器版本信息时出错: ${e.message}`); return { content: [{ type: "text", text: JSON.stringify({ error: "获取服务器信息失败", message: e.message }, null, 2) }] }; } }); // 添加创建新思维模型的工具 server.tool("create-thinking-model", "创建新的思维模型并添加到系统中,用于填补知识缺口", { id: z.string().describe("模型的唯一标识符,请使用小写字母和下划线,例如:digital_marketing_funnel"), name: z.string().describe("模型的名称,例如:数字营销漏斗模型"), author: z.string().optional().describe("模型作者(可选)"), source: z.string().optional().describe("模型来源(可选)"), definition: z.string().describe("模型的简明定义"), purpose: z.string().describe("模型的主要目的和使用场景"), interaction: z.string().optional().describe("使用该模型与用户交互的方式指南(可选)"), constraints: z.array(z.string()).optional().describe("使用此模型的约束条件(可选)"), prompt: z.string().optional().describe("详细的提示词/角色扮演指南(可选)"), example: z.string().optional().describe("模型使用的简短示例(可选)"), category: z.string().describe("模型的主要分类,如:营销分析、决策制定、系统思考等"), subcategories: z.array(z.string()).optional().describe("模型的子分类列表(可选)"), tags: z.array(z.string()).optional().describe("模型的相关标签(可选)"), use_cases: z.array(z.string()).optional().describe("模型的使用案例(可选)"), common_problems_solved: z.array(z.object({ problem_description: z.string(), keywords: z.array(z.string()), guiding_questions: z.array(z.string()).optional() })).optional().describe("模型解决的常见问题(可选)"), popular_science_teaching: z.array(z.object({ concept_name: z.string(), explanation: z.string() })).optional().describe("模型的通俗科学教学(可选)"), limitations: z.array(z.object({ limitation_name: z.string(), description: z.string() })).optional().describe("模型的局限性(可选)"), common_pitfalls: z.array(z.object({ pitfall_name: z.string(), description: z.string() })).optional().describe("使用模型的常见陷阱(可选)"), lang: z.enum(["zh", "en"]).default("zh").describe("模型的语言('zh' 或 'en'),默认为 'zh'"), // 可视化数据需要细分为具体类型 flowchart_visualizations: z.array(z.object({ title: z.string(), description: z.string().optional(), dsl: z.string() })).optional().describe("流程图可视化(可选)"), bar_chart_visualizations: z.array(z.object({ title: z.string(), description: z.string().optional(), labels: z.array(z.string()), datasets: z.array(z.object({ label: z.string(), data: z.array(z.number()), backgroundColor: z.union([z.string(), z.array(z.string())]).optional() })) })).optional().describe("柱状图可视化(可选)"), table_visualizations: z.array(z.object({ title: z.string(), description: z.string().optional(), headers: z.array(z.string()), rows: z.array(z.array(z.union([z.string(), z.number(), z.boolean()]))) })).optional().describe("表格可视化(可选)"), list_visualizations: z.array(z.object({ title: z.string(), description: z.string().optional(), items: z.array(z.object({ text: z.string(), subItems: z.array(z.object({ text: z.string() })).optional() })) })).optional().describe("列表可视化(可选)"), comparison_table_visualizations: z.array(z.object({ title: z.string(), description: z.string().optional(), criteria: z.array(z.string()), items: z.array(z.object({ name: z.string(), values: z.array(z.union([z.string(), z.number(), z.boolean()])) })) })).optional().describe("比较表可视化(可选)") }, async (model) => { try { log(`开始创建新思维模型,收到参数: id=${model.id}, name=${model.name}, category=${model.category}, lang=${model.lang}`); const { lang, flowchart_visualizations, bar_chart_visualizations, table_visualizations, list_visualizations, comparison_table_visualizations, ...basicModelData } = model; log(`解构参数完成,基础模型数据包含字段: ${Object.keys(basicModelData).join(', ')}`); // 验证ID格式 if (!/^[a-z0-9_]+$/.test(basicModelData.id)) { log(`模型ID格式验证失败: "${basicModelData.id}" 不符合要求的格式(仅小写字母、数字和下划线)`); return { content: [{ type: "text", text: JSON.stringify({ error: "模型ID格式无效,请使用小写字母、数字和下划线" }, null, 2) }] }; } log(`模型ID格式验证通过: ${basicModelData.id}`); // 检查ID是否已存在 if (MODELS[lang].some(m => m.id === basicModelData.id)) { log(`模型ID冲突检查失败: 模型ID "${basicModelData.id}" 已存在于 ${lang} 语言中`); return { content: [{ type: "text", text: JSON.stringify({ error: `模型ID '${basicModelData.id}' 已存在,请使用其他ID` }, null, 2) }] }; } log(`模型ID冲突检查通过: ${basicModelData.id} 在 ${lang} 语言中不存在`); // 处理可视化数据 const visualizations = []; log(`开始处理可视化数据...`); // 处理流程图可视化 if (flowchart_visualizations) { flowchart_visualizations.forEach(viz => { visualizations.push({ title: viz.title, type: "flowchart_dsl", data: { dsl: viz.dsl }, description: viz.description }); }); } // 处理柱状图可视化 if (bar_chart_visualizations) { bar_chart_visualizations.forEach(viz => { visualizations.push({ title: viz.title, type: "bar_chart_data", data: { labels: viz.labels, datasets: viz.datasets }, description: viz.description }); }); } // 处理表格可视化 if (table_visualizations) { table_visualizations.forEach(viz => { visualizations.push({ title: viz.title, type: "table_data", data: { headers: viz.headers, rows: viz.rows }, description: viz.description }); }); } // 处理列表可视化 if (list_visualizations) { list_visualizations.forEach(viz => { visualizations.push({ title: viz.title, type: "list_items", data: { items: viz.items }, description: viz.description }); }); } // 处理比较表可视化 if (comparison_table_visualizations) { comparison_table_visualizations.forEach(viz => { visualizations.push({ title: viz.title, type: "comparison_table", data: { criteria: viz.criteria, items: viz.items }, description: viz.description }); }); } // 创建完整的模型对象 const newModel = { ...basicModelData, visualizations: visualizations.length > 0 ? visualizations : undefined }; log(`已创建完整模型对象,可视化数量: ${visualizations.length}`); // 确定保存路径 const modelLangDir = path.resolve(__dirname, "..", SUPPORTED_LANGUAGES[lang]); const modelFilePath = path.join(modelLangDir, `${basicModelData.id}.json`); log(`模型将保存到路径: ${modelFilePath}`); // 确保目录存在 try { await fs.access(modelLangDir); } catch { await fs.mkdir(modelLangDir, { recursive: true }); log(`创建模型目录: ${modelLangDir}`); } // 保存模型到文件 await fs.writeFile(modelFilePath, JSON.stringify(newModel, null, 2), 'utf-8'); log(`新模型 ${basicModelData.id} 已保存到 ${modelFilePath}`); // 将新模型添加到内存中 MODELS[lang].push(newModel); // 检查该模型是否可能填补了现有的知识缺口 let potentiallyFilledGaps = []; try { // 确保加载了最新状态 await loadLearningSystemState(); // 获取知识缺口 const knowledgeGaps = getKnowledgeGaps(100); // 获取最多100个知识缺口进行检查 if (knowledgeGaps && knowledgeGaps.length > 0) { // 检查新模型是否可能填补任何知识缺口 potentiallyFilledGaps = knowledgeGaps .filter(gap => { // 使用查询匹配算法检查模型与知识缺口的相关性 const { score } = calculateQueryMatch(newModel, gap.description); return score > 0.6; // 相关性阈值 }) .map(gap => ({ gapId: gap.gapId, description: gap.description, relevanceScore: calculateQueryMatch(newModel, gap.description).score })); } } catch (error) { log(`检查知识缺口填补时出错: ${error instanceof Error ? error.message : String(error)}`); } return { content: [{ type: "text", text: JSON.stringify({ success: true, message: `新思维模型 '${newModel.name}' (ID: ${newModel.id}) 已成功创建`, model_id: newModel.id, file_path: modelFilePath, potentially_filled_knowledge_gaps: potentiallyFilledGaps }, null, 2) }] }; } catch (e) { log(`创建思维模型时出错: ${e.message}`); return { content: [{ type: "text", text: JSON.stringify({ error: "创建思维模型失败", message: e.message }, null, 2) }] }; } }); // 添加更新思维模型的工具 server.tool("update-thinking-model", "更新现有思维模型的内容", { model_id: z.string().describe("要更新的模型ID"), lang: z.enum(["zh", "en"]).default("zh").describe("模型的语言('zh' 或 'en'),默认为 'zh'"), // 可更新的字段 name: z.string().optional().describe("模型的名称(可选)"), author: z.string().optional().describe("模型作者(可选)"), source: z.string().optional().describe("模型来源(可选)"), definition: z.string().optional().describe("模型的简明定义(可选)"), purpose: z.string().optional().describe("模型的主要目的和使用场景(可选)"), interaction: z.string().optional().describe("使用该模型与用户交互的方式指南(可选)"), constraints: z.array(z.string()).optional().describe("使用此模型的约束条件(可选)"), prompt: z.string().optional().describe("详细的提示词/角色扮演指南(可选)"), example: z.string().optional().describe("模型使用的简短示例(可选)"), category: z.string().optional().describe("模型的主要分类(可选)"), subcategories: z.array(z.string()).optional().describe("模型的子分类列表(可选)"), tags: z.array(z.string()).optional().describe("模型的相关标签(可选)"), use_cases: z.array(z.string()).optional().describe("模型的使用案例(可选)"), common_problems_solved: z.array(z.object({ problem_description: z.string(), keywords: z.array(z.string()), guiding_questions: z.array(z.string()).optional() })).optional().describe("模型解决的常见问题(可选)"), popular_science_teaching: z.array(z.object({ concept_name: z.string(), explanation: z.string() })).optional().describe("模型的通俗科学教学(可选)"), limitations: z.array(z.object({ limitation_name: z.string(), description: z.string() })).optional().describe("模型的局限性(可选)"), common_pitfalls: z.array(z.object({ pitfall_name: z.string(), description: z.string() })).optional().describe("使用模型的常见陷阱(可选)"), // 可视化数据需要细分为具体类型 flowchart_visualizations: z.array(z.object({ title: z.string(), description: z.string().optional(), dsl: z.string() })).optional().describe("流程图可视化(可选)"), bar_chart_visualizations: z.array(z.object({ title: z.string(), description: z.string().optional(), labels: z.array(z.string()), datasets: z.array(z.object({ label: z.string(), data: z.array(z.number()), backgroundColor: z.union([z.string(), z.array(z.string())]).optional() })) })).optional().describe("柱状图可视化(可选)"), table_visualizations: z.array(z.object({ title: z.string(), description: z.string().optional(), headers: z.array(z.string()), rows: z.array(z.array(z.union([z.string(), z.number(), z.boolean()]))) })).optional().describe("表格可视化(可选)"), list_visualizations: z.array(z.object({ title: z.string(), description: z.string().optional(), items: z.array(z.object({ text: z.string(), subItems: z.array(z