import { FastMCP } from "fastmcp";
import { prisma } from "../lib/prisma.js";
import { z } from "zod";
export function createMCPServer() {
const mcp = new FastMCP({
name: "YYSK Knowledge Base",
version: "1.0.0",
ping: {
enabled: true,
intervalMs: 10000, // 延长至 10 秒,减少频繁握手
},
roots: {
enabled: false, // 如果不需要读取客户端的根目录,禁用它可以减少初始化错误
}
});
// 搜索工具
mcp.addTool({
name: "search_knowledge",
description: "在公司 Wiki、规章制度和通知中搜索相关信息。支持模糊搜索和类型过滤。",
parameters: z.object({
query: z.string().describe("搜索关键词"),
type: z.enum(["wiki", "rule", "notification"]).optional().describe("内容类型过滤器"),
}),
execute: async ({ query, type }) => {
try {
const results = await prisma.document.findMany({
where: {
AND: [
type ? { type } : {},
{
OR: [
{ title: { contains: query } },
{ content: { contains: query } }
]
}
]
},
take: 10
});
if (results.length === 0) return "未找到匹配的内容。建议尝试更简短的关键词。";
return results.map((r: any) =>
`[ID: ${r.id}] ${r.title} (${r.type === 'wiki' ? 'Wiki' : r.type === 'rule' ? '规章制度' : '内部通知'})\n摘要: ${r.content.substring(0, 150)}...`
).join("\n---\n");
} catch (error) {
return `搜索失败: ${(error as Error).message}`;
}
}
});
// 详情查看工具
mcp.addTool({
name: "get_content_detail",
description: "根据 ID 获取文档内容的完整原文。建议在搜索结果中找到感兴趣的 ID 后使用此工具。",
parameters: z.object({
id: z.number().describe("文档 ID"),
}),
execute: async ({ id }) => {
try {
const result = await prisma.document.findUnique({
where: { id }
});
if (!result) return "错误:未找到指定 ID 的文档。";
return `
# ${result.title}
内容类型: ${result.type}
最后更新: ${result.updatedAt?.toLocaleString('zh-CN') || "未知"}
---
${result.content}
---
标签: ${result.tags || "无"}
`;
} catch (error) {
return `获取详情失败: ${(error as Error).message}`;
}
}
});
return mcp;
}