@thinking-models/mcp-server
Version:
A Model Context Protocol (MCP) server for thinking models
1,299 lines • 118 kB
JavaScript
#!/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