尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

基于MCP协议构建AI文档生成引擎:从聊天到自动化交付

基于MCP协议构建AI文档生成引擎:从聊天到自动化交付 你是否曾有过这样的体验面对一个功能强大的AI聊天助手比如Claude或ChatGPT你明明知道它能帮你写代码、分析问题但当你需要它生成一份结构严谨、格式统一、可直接交付的技术文档时对话却变得异常低效你不得不反复描述格式要求手动复制粘贴内容甚至需要自己动手调整Markdown或HTML。这背后是一个普遍存在的效率断层AI擅长内容创作却不擅长结构化输出和工程化交付。我们与AI的交互大多停留在“一问一答”的聊天层面而真正的生产力场景往往需要将零散的对话成果转化为可直接使用的、标准化的文档资产。今天要探讨的正是如何弥合这一断层。本文的核心观点是通过引入“模型上下文协议”Model Context Protocol, MCP这一新兴标准我们可以将你熟悉的AI聊天界面系统性地升级为一个自动化、可编程的文档生成引擎。这不是简单地让AI“写文档”而是构建一套从对话到成品的完整工作流。对于开发者、技术写作者和项目管理者而言这意味着你可以将重复的文档编写任务如API说明、配置指南、会议纪要自动化。确保团队产出的文档风格、模板高度统一。将AI的“思考过程”和使用的参考资料如代码、数据库Schema直接固化到生成的文档中提升可追溯性。接下来我们将从MCP协议的核心原理讲起一步步拆解如何利用Claude Desktop等工具搭建你的私人文档生成流水线并提供可直接复用的代码示例和配置方案。1. 从“聊天机器人”到“文档引擎”MCP如何改变游戏规则在深入技术细节之前我们必须先理解问题的本质。传统的AI聊天生成文档存在几个核心痛点上下文碎片化每次对话都是独立的难以继承之前的格式约定、术语表或品牌规范。输出不可控AI可能突然改变标题层级、遗漏关键章节或使用不一致的术语。过程不可复用成功生成一次完美文档的“咒语”Prompt和流程难以保存并应用于下一次任务。缺乏“执行力”AI只能“说”不能“做”。它无法主动读取你本地的项目文件、查询数据库的最新Schema或调用代码格式化工具。MCP的出现正是为了解决“执行力”和“结构化交互”的问题。你可以把它理解为AI的“手脚”和“感官”扩展协议。它定义了一套标准让AI助手客户端能够安全、可控地调用外部工具服务器端。在文档生成的场景下MCP能带来什么改变赋予AI“视力”通过MCP服务器AI可以直接读取你指定的本地文件目录、Git仓库或远程API文档获取最新、最准确的原始材料。赋予AI“工具手”AI可以调用你预先编写好的文档模板引擎、图表生成工具甚至是直接执行pandoc命令将Markdown转换为PDF。标准化交互流程MCP将复杂的文档生成需求拆解为一系列可预测的“工具调用”。例如“读取api_spec.yaml” - “根据template.md.j2模板渲染” - “调用prettier格式化输出”。这个过程可以被记录、复现和优化。简而言之MCP让文档生成从一次性的、依赖“运气”的对话变成了一个可编程、可调试、可集成的自动化流程。你的角色也从“提示词工程师”变成了“流程设计师”。2. 核心概念拆解MCP、资源与工具要搭建这套引擎需要理解三个核心概念1. 模型上下文协议 (Model Context Protocol, MCP)MCP是一个开放协议用于在AI应用程序如Claude Desktop、Cursor和外部数据源/工具之间建立安全、高效的通信。它采用客户端-服务器架构通过JSON-RPC over stdio或SSE进行通信。其核心价值在于标准化使得任何兼容MCP的AI应用都能使用任何兼容MCP的服务。2. 资源 (Resources)资源是MCP服务器向AI客户端“暴露”的只读数据。在文档生成上下文中资源可以是一个本地文件file:///path/to/your/spec.md一个数据库查询的虚拟视图sqlite:///db.sqlite?tableusers一个远程API的端点描述http://api.example.com/openapi.json AI客户端可以“读取”这些资源将其内容作为生成文档的上下文。这解决了信息输入的问题。3. 工具 (Tools)工具是MCP服务器向AI客户端提供的可执行函数。这是实现自动化的关键。在文档生成中工具可以是render_document(template, data): 使用模板引擎渲染文档。convert_format(input_file, output_format): 转换文档格式如MD转HTML。write_to_file(content, path): 将内容写入指定文件。 AI客户端可以“调用”这些工具并获取执行结果。这解决了输出和行动的问题。一个生动的类比把AI助手想象成一个坐在办公室里的专家。在没有MCP时你只能通过电话聊天框向他口述问题他凭记忆和推理回答。有了MCP之后你给了他办公室的钥匙MCP服务器他可以走到文件柜前资源直接查阅项目档案。使用办公室里的打印机、扫描仪和装订机工具来处理材料。最终交给你一份装订好的、格式完美的报告生成的文档。3. 环境准备从Claude Desktop开始理论讲完我们开始动手。我们将以Claude Desktop作为AI客户端因为它对MCP的支持非常友好且免费。整个环境搭建围绕配置Claude Desktop来连接我们自定义的MCP服务器。前置条件操作系统macOS, Windows, 或 Linux。本文以macOS/Linux命令行示例为主Windows用户可在WSL或PowerShell中操作。Node.js环境用于运行和开发MCP服务器。建议安装Node.js 18或更高版本以及npm或yarn包管理器。Claude Desktop应用从 Claude官网 下载并安装。核心步骤编辑Claude Desktop的配置文件Claude Desktop通过一个配置文件来加载MCP服务器。配置文件的位置因系统而异macOS:~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:%APPDATA%\Claude\claude_desktop_config.jsonLinux:~/.config/Claude/claude_desktop_config.json如果该文件或目录不存在你需要手动创建。4. 构建你的第一个MCP服务器一个简单的文档阅读器让我们先构建一个最简单的MCP服务器它的功能是向Claude暴露一个本地目录下的文件作为“资源”。这样AI在生成文档时就能直接引用这些文件的内容。步骤1初始化项目并安装依赖创建一个新的项目目录并初始化Node.js项目。mkdir mcp-document-server cd mcp-document-server npm init -y安装必要的MCP开发包。这里我们使用modelcontextprotocol/sdk来简化服务器开发。npm install modelcontextprotocol/sdk步骤2创建服务器主文件创建文件server.js并写入以下代码// server.js const { Server } require(modelcontextprotocol/sdk/server/index.js); const { StdioServerTransport } require(modelcontextprotocol/sdk/server/stdio.js); const { ListResourcesRequestSchema, GetResourceRequestSchema, ListToolsRequestSchema, CallToolRequestSchema, } require(modelcontextprotocol/sdk/types.js); const fs require(fs).promises; const path require(path); // 1. 创建MCP服务器实例 const server new Server( { name: document-assistant, version: 0.1.0, }, { capabilities: { resources: {}, // 声明服务器提供资源功能 tools: {}, // 声明服务器提供工具功能后续扩展 }, } ); // 2. 定义文档根目录请根据你的实际情况修改 const DOCS_ROOT path.resolve(process.env.HOME, Projects/my-docs); // 3. 处理“列出资源”请求 server.setRequestHandler(ListResourcesRequestSchema, async () { // 这里我们简单返回一个固定的资源列表。 // 更复杂的实现可以动态扫描DOCS_ROOT目录。 return { resources: [ { uri: file:///api-spec, name: API接口规范, description: 项目的OpenAPI/Swagger规范文件, mimeType: application/json, }, { uri: file:///user-guide, name: 用户指南草稿, description: 正在编写的用户指南Markdown文件, mimeType: text/markdown, }, ], }; }); // 4. 处理“获取资源内容”请求 server.setRequestHandler(GetResourceRequestSchema, async (request) { const { uri } request.params; let filePath; let content; // 根据URI映射到本地文件 // 注意这是一个简化的映射生产环境需要更安全的路由逻辑 if (uri file:///api-spec) { filePath path.join(DOCS_ROOT, api, openapi.json); content await fs.readFile(filePath, utf-8); } else if (uri file:///user-guide) { filePath path.join(DOCS_ROOT, guides, getting-started.md); content await fs.readFile(filePath, utf-8); } else { throw new Error(Resource not found: ${uri}); } return { contents: [ { uri: uri, mimeType: request.params.uri file:///api-spec ? application/json : text/markdown, text: content, }, ], }; }); // 5. 启动服务器使用标准输入输出进行通信 async function main() { const transport new StdioServerTransport(); await server.connect(transport); console.error(MCP Document Server is running on stdio...); } main().catch((error) { console.error(Server error:, error); process.exit(1); });代码解释服务器定义了两个资源file:///api-spec和file:///user-guide。当Claude请求资源列表时服务器返回这两个资源的描述。当Claude请求某个资源的具体内容时服务器根据URI映射读取本地对应的文件如~/Projects/my-docs/api/openapi.json并返回内容。通信通过标准输入输出stdio进行这是Claude Desktop调用本地服务器的标准方式。步骤3创建示例文档文件为了让服务器有内容可读创建示例文件。mkdir -p ~/Projects/my-docs/api mkdir -p ~/Projects/my-docs/guides创建OpenAPI规范示例~/Projects/my-docs/api/openapi.json{ openapi: 3.0.0, info: { title: 示例用户API, version: 1.0.0 }, paths: { /users: { get: { summary: 获取用户列表, responses: { 200: { description: 成功, content: { application/json: { schema: { type: array, items: { $ref: #/components/schemas/User } } } } } } } } }, components: { schemas: { User: { type: object, properties: { id: { type: integer, format: int64 }, name: { type: string }, email: { type: string, format: email } } } } } }创建用户指南示例~/Projects/my-docs/guides/getting-started.md# 用户指南快速开始 欢迎使用我们的产品。本指南将帮助您完成首次设置。 ## 第一步安装 运行以下命令进行安装 bash npm install our-awesome-package第二步配置在项目根目录创建.env文件并添加您的API密钥API_KEYyour_api_key_here第三步运行示例参考examples/目录下的代码开始使用。## 5. 连接Claude Desktop让AI看见你的文档 现在我们需要告诉Claude Desktop如何使用我们刚刚编写的MCP服务器。 **步骤1创建Claude Desktop配置文件** 按照第3节中的路径创建或编辑配置文件。以下是配置内容 json // claude_desktop_config.json { mcpServers: { document-assistant: { command: node, args: [ /ABSOLUTE/PATH/TO/YOUR/mcp-document-server/server.js ], env: { DOCS_ROOT: /ABSOLUTE/PATH/TO/YOUR/Projects/my-docs } } } }重要提示将/ABSOLUTE/PATH/TO/YOUR/mcp-document-server/server.js替换为你实际的项目路径。将/ABSOLUTE/PATH/TO/YOUR/Projects/my-docs替换为你实际的文档根目录路径。Windows用户注意使用反斜杠\或双反斜杠\\或者最好使用正斜杠/并确保路径是绝对路径。步骤2重启Claude Desktop保存配置文件后完全退出并重新启动Claude Desktop应用。步骤3验证连接启动Claude Desktop后打开一个新的对话。如果配置成功你应该能在输入框附近或设置里看到MCP服务器已连接的提示不同版本UI可能不同。更直接的验证方法是在对话中尝试让Claude使用你的资源。你可以输入如下提示“请查看我提供的file:///api-spec资源为我总结一下这个API提供了哪些端点endpoints”如果一切正常Claude会调用MCP服务器读取openapi.json文件并基于其内容回答你的问题。这表明你的AI聊天窗口已经成功“看见”了你的本地文档。6. 升级引擎添加文档生成工具仅能读取文档还不够我们的目标是生成文档。现在我们来扩展MCP服务器为其添加一个核心工具generate_doc。这个工具将接受一个文档类型参数基于模板和资源内容生成一份完整的草稿。步骤1扩展服务器代码修改server.js添加工具处理逻辑。以下是完整的更新后server.js代码// server.js - 完整版包含工具 const { Server } require(modelcontextprotocol/sdk/server/index.js); const { StdioServerTransport } require(modelcontextprotocol/sdk/server/stdio.js); const { ListResourcesRequestSchema, GetResourceRequestSchema, ListToolsRequestSchema, CallToolRequestSchema, } require(modelcontextprotocol/sdk/types.js); const fs require(fs).promises; const path require(path); const server new Server( { name: document-assistant, version: 0.2.0, // 更新版本号 }, { capabilities: { resources: {}, tools: {}, }, } ); const DOCS_ROOT path.resolve(process.env.HOME, Projects/my-docs); const TEMPLATES_DIR path.join(__dirname, templates); // --- 资源处理部分保持不变--- server.setRequestHandler(ListResourcesRequestSchema, async () { return { resources: [ { uri: file:///api-spec, name: API接口规范, description: 项目的OpenAPI/Swagger规范文件, mimeType: application/json, }, { uri: file:///user-guide, name: 用户指南草稿, description: 正在编写的用户指南Markdown文件, mimeType: text/markdown, }, ], }; }); server.setRequestHandler(GetResourceRequestSchema, async (request) { const { uri } request.params; let filePath; let content; if (uri file:///api-spec) { filePath path.join(DOCS_ROOT, api, openapi.json); content await fs.readFile(filePath, utf-8); } else if (uri file:///user-guide) { filePath path.join(DOCS_ROOT, guides, getting-started.md); content await fs.readFile(filePath, utf-8); } else { throw new Error(Resource not found: ${uri}); } return { contents: [ { uri: uri, mimeType: uri file:///api-spec ? application/json : text/markdown, text: content, }, ], }; }); // --- 新增工具处理部分 --- server.setRequestHandler(ListToolsRequestSchema, async () { return { tools: [ { name: generate_doc, description: 根据指定的文档类型和上下文生成一份技术文档草稿。, inputSchema: { type: object, properties: { docType: { type: string, description: 文档类型例如api_reference, user_guide, design_doc, enum: [api_reference, user_guide, design_doc] }, title: { type: string, description: 文档的主标题, }, additionalInstructions: { type: string, description: 对文档风格、重点的额外要求可选, } }, required: [docType, title], }, }, ], }; }); server.setRequestHandler(CallToolRequestSchema, async (request) { const { name, arguments: args } request.params; if (name generate_doc) { const { docType, title, additionalInstructions } args; // 1. 根据文档类型选择模板和资源 let templateName, resourceUri; switch (docType) { case api_reference: templateName api_reference.md.j2; resourceUri file:///api-spec; break; case user_guide: templateName user_guide.md.j2; resourceUri file:///user-guide; break; default: templateName default.md.j2; resourceUri null; } // 2. 读取模板文件这里使用简单的字符串替换生产环境可使用Jinja2、EJS等 const templatePath path.join(TEMPLATES_DIR, templateName); let templateContent; try { templateContent await fs.readFile(templatePath, utf-8); } catch (error) { templateContent # ${title}\n\n**文档类型**: ${docType}\n\n## 内容\n\n[此处应基于相关资源生成内容。]\n\n; } // 3. 获取相关资源内容 let resourceContent ; if (resourceUri) { try { // 简化处理直接复用GetResource的逻辑获取内容 // 实际应调用内部函数或重构代码 const res await server._handleRequest({ jsonrpc: 2.0, method: resources/get, params: { uri: resourceUri }, id: temp }); resourceContent res.result.contents[0].text; } catch (e) { resourceContent *未能读取资源: ${resourceUri}*; } } // 4. 生成文档草稿这里是极简的模板渲染 const generatedDoc templateContent .replace({{TITLE}}, title) .replace({{DOC_TYPE}}, docType) .replace({{ADDITIONAL_INSTRUCTIONS}}, additionalInstructions || 无) .replace({{RESOURCE_CONTENT}}, resourceContent.substring(0, 1000)); // 限制长度 // 5. 返回结果 return { content: [ { type: text, text: 已根据您的要求生成“${title}”的草稿。\n\n **使用的模板**: ${templateName}\n **参考的资源**: ${resourceUri || 无}\n\n **生成的文档内容如下**:\n\n ---\n generatedDoc \n---\n\n *提示以上为系统生成的草稿请根据需要进行修改和润色。* }, ], }; } throw new Error(Tool not found: ${name}); }); // --- 启动服务器 --- async function main() { // 确保模板目录存在 await fs.mkdir(TEMPLATES_DIR, { recursive: true }); // 创建默认模板文件如果不存在 const defaultTemplatePath path.join(TEMPLATES_DIR, default.md.j2); try { await fs.access(defaultTemplatePath); } catch { await fs.writeFile(defaultTemplatePath, # {{TITLE}}\n\n 文档类型: {{DOC_TYPE}}\n 额外要求: {{ADDITIONAL_INSTRUCTIONS}}\n\n## 概述\n\n本文档基于资源内容生成。\n\n## 资源内容摘要\n\n{{RESOURCE_CONTENT}}\n\n## 详细说明\n\n[请在此处展开详细内容...]\n); } const transport new StdioServerTransport(); await server.connect(transport); console.error(MCP Document Server (with tools) is running...); } main().catch((error) { console.error(Server error:, error); process.exit(1); });步骤2创建模板目录和文件在项目根目录创建templates文件夹并添加模板文件。创建templates/api_reference.md.j2:# {{TITLE}} - API参考 生成时间: {{CURRENT_DATE}} 基于资源: file:///api-spec ## 概述 本文档描述了 {{TITLE}} 的API接口。 ## 接口列表 以下是自动从OpenAPI规范中提取的接口 {{RESOURCE_CONTENT}} ## 使用示例 此处应由AI根据接口规范补充具体调用示例 --- *本文件为自动生成草稿。*创建templates/user_guide.md.j2:# {{TITLE}} 用户指南 | 版本: 草稿 ## 前言 {{ADDITIONAL_INSTRUCTIONS}} ## 核心步骤 以下是基础操作指南 {{RESOURCE_CONTENT}} ## 常见问题 此处应由AI根据内容补充FAQ --- *基于现有指南草稿生成。*步骤3重启服务器并测试工具确保你的claude_desktop_config.json配置指向新的server.js。重启Claude Desktop。在新的对话中你现在可以这样使用“请使用generate_doc工具帮我生成一份API参考文档标题是‘用户服务API V1.0’文档类型选api_reference。”Claude会识别到这个工具并弹出参数填写框或直接在后台调用。调用成功后你将获得一份结合了模板和openapi.json资源内容的结构化文档草稿。7. 运行效果与进阶验证完成上述步骤后你的Claude AI已经从一个单纯的聊天机器人转变为一个具备初步文档生成能力的引擎。你可以通过以下方式验证和探索基础验证资源读取让Claude“总结file:///user-guide资源的主要内容”。它能直接读取并分析你的Markdown文件。工具调用使用generate_doc工具生成不同格式的文档。观察输出是否融合了模板框架和资源内容。进阶验证手动模拟工具调用为了更深入地理解MCP的通信过程你可以编写一个简单的测试客户端。创建test_client.js// test_client.js - 用于模拟AI客户端测试MCP服务器 const { spawn } require(child_process); const path require(path); const serverPath path.join(__dirname, server.js); const serverProcess spawn(node, [serverPath], { stdio: [pipe, pipe, inherit] // 继承stderr以便查看日志 }); let buffer ; serverProcess.stdout.on(data, (data) { buffer data.toString(); // 简单尝试解析JSON RPC消息实际协议更复杂此处仅为演示 if (buffer.includes(\n)) { const lines buffer.split(\n); for (const line of lines) { if (line.trim()) { try { const msg JSON.parse(line); console.log(Received from server:, JSON.stringify(msg, null, 2)); } catch (e) { // 忽略非JSON行 } } } buffer ; } }); // 发送一个模拟的“列出工具”请求 const listToolsRequest { jsonrpc: 2.0, id: 1, method: tools/list, params: {} }; serverProcess.stdin.write(JSON.stringify(listToolsRequest) \n); // 稍后发送一个“调用工具”请求 setTimeout(() { const callToolRequest { jsonrpc: 2.0, id: 2, method: tools/call, params: { name: generate_doc, arguments: { docType: api_reference, title: 测试API文档 } } }; serverProcess.stdin.write(JSON.stringify(callToolRequest) \n); }, 500); // 5秒后退出测试 setTimeout(() { serverProcess.kill(); process.exit(0); }, 5000);运行node test_client.js观察服务器返回的原始JSON-RPC消息这能帮助你理解Claude与服务器之间的实际数据交换。8. 常见问题与排查思路在搭建和使用过程中你可能会遇到以下问题问题现象可能原因排查方式解决方案Claude Desktop启动后无MCP服务器提示1. 配置文件路径错误。2. 配置文件格式错误JSON语法。3. Claude Desktop未读取新配置。1. 检查配置文件路径是否正确。2. 使用JSONLint验证配置文件。3. 完全退出并重启Claude Desktop。1. 确保使用绝对路径。2. 修正JSON语法。3. 重启应用有时需要重启两次。服务器启动失败报错Cannot find moduleNode.js依赖未安装或服务器脚本路径错误。1. 在服务器目录运行npm list。2. 检查claude_desktop_config.json中的command和args。1. 在服务器目录执行npm install。2. 确保args中的JS文件路径绝对正确。Claude无法识别资源或工具1. MCP服务器未成功连接。2. 服务器代码中资源/工具定义有误。3. Claude版本过旧。1. 查看Claude Desktop日志位置因系统而异。2. 使用test_client.js测试服务器响应。3. 更新Claude Desktop到最新版。1. 根据日志修复配置或代码。2. 确保ListResourcesRequestSchema和ListToolsRequestSchema处理器正确返回数据。工具调用后无响应或报错1. 工具处理函数 (CallToolRequestSchema) 有bug。2. 参数格式不符合inputSchema定义。1. 在服务器代码中添加console.error打印错误。2. 检查Claude调用工具时传入的参数。1. 修复工具函数内的逻辑错误如文件读取。2. 确保inputSchema定义与调用参数匹配。生成的文档内容不符合预期1. 模板文件 (*.md.j2) 不存在或路径错误。2. 资源内容读取失败。3. 模板渲染逻辑过于简单。1. 检查TEMPLATES_DIR常量定义的路径。2. 检查资源URI映射逻辑。3. 在工具函数中打印中间变量。1. 创建缺失的模板文件。2. 修正资源读取路径。3. 引入成熟的模板引擎如ejs、handlebars。关键排查命令检查Claude日志(macOS示例):tail -f ~/Library/Logs/Claude/claude_desktop.log验证Node.js路径:which node验证配置文件:cat ~/Library/Application\ Support/Claude/claude_desktop_config.json | python -m json.tool9. 最佳实践与工程化建议将原型转化为稳定、可协作的生产力工具需要考虑以下方面1. 安全第一最小权限原则MCP服务器的权限应被严格限制。不要暴露整个硬盘根目录。通过环境变量或配置文件严格限定DOCS_ROOT的范围。输入验证与清理工具函数必须对所有输入参数进行验证和清理防止路径遍历攻击如../../../etc/passwd。沙箱考虑对于执行任意命令或代码的工具应考虑在沙箱环境如Docker容器中运行。2. 提升服务器能力使用模板引擎替换简单的字符串替换使用EJS、Handlebars或Jinja2(通过Node.js绑定) 来实现条件判断、循环等复杂模板逻辑。动态资源发现实现ListResourcesRequestSchema处理器使其能动态扫描DOCS_ROOT目录自动将文件树暴露为资源而不是硬编码。更多实用工具format_document: 调用prettier或markdownlint格式化生成的文档。export_document: 调用pandoc将Markdown导出为PDF、Word或HTML。sync_to_wiki: 将最终文档推送到Confluence、GitBook等知识库。3. 优化Claude交互体验编写清晰的工具描述description和inputSchema中的description字段要尽可能清晰这决定了Claude如何理解和使用你的工具。提供示例对话在团队内部可以共享一些高效的Prompt示例例如“请参考file:///design-spec和file:///api-spec使用generate_doc工具为我们即将开发的‘支付模块’创建一份设计文档草稿。”版本化管理配置将claude_desktop_config.json和MCP服务器代码纳入Git版本控制方便团队统一环境。4. 扩展到其他AI客户端MCP是开放协议。除了Claude Desktop你也可以配置其他支持MCP的客户端如Cursor IDE在Cursor中AI可以直接调用MCP工具辅助编码和撰写代码文档。其他兼容MCP的AI应用随着生态发展会有更多应用加入。你的MCP服务器可以一次开发多处使用。通过以上步骤你不仅搭建了一个文档生成引擎的雏形更掌握了一套将AI深度集成到个人与团队工作流的方法论。这套系统的价值不在于替代人工撰写文档而在于将人类从重复、机械的信息整合和格式调整中解放出来让我们能更专注于创造性的思考、架构设计和内容精炼。
返回列表