ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

LibreChat:开源可自托管的AI协议编排器与MCP实践指南

2026/9/20 9:32:34 拓冰建站 浏览量
LibreChat:开源可自托管的AI协议编排器与MCP实践指南 1. LibreChat 是什么一个能跑在你本地的、真正开源的 AI 聊天界面LibreChat 不是另一个“套壳 OpenAI”的网页前端也不是只改了点 UI 就号称“开源”的半成品。它是一个从零开始、完全自主实现的、可自托管的聊天应用框架核心目标很朴素让你在自己的服务器、笔记本甚至树莓派上拥有一个不依赖任何商业云服务、不上传对话数据、不被 API Key 绑架的 AI 交互入口。我第一次把它部署在一台 4GB 内存的旧 Mac mini 上时打开浏览器输入http://localhost:3001看着那个干净的聊天窗口弹出来旁边还挂着“Connected to Local LLM”——那一刻的感觉就像亲手拧开了一瓶没贴商标的、但原料和工艺都写在瓶身上的苏打水清爽、透明、可控。LibreChat 的关键词不是“快”而是“可解释”和“可干预”。它不追求在 benchmark 上刷分但坚决要求每一个 token 的生成路径都清晰可见。当你点击“Show Prompt”按钮看到的不是一团加密字符串而是结构化的 system message conversation history tool call 指令当你切换模型它不会偷偷把请求转发到某个未知域名而是明确告诉你“正在使用 Ollama 运行的 llama3:8b”或者“正通过 MCP 协议调用本地部署的 CodeLlama-7b-Instruct”。这种“所见即所得”的确定性在当前大量 AI 工具越来越黑盒化的趋势下反而成了最稀缺的生产力资产。它解决的不是“能不能用大模型”的问题而是“怎么放心、稳定、可持续地用大模型”的问题。适合三类人第一类是技术团队的 DevOps 或 MLOps 工程师需要为内部知识库、代码审查、日志分析等场景提供统一、审计友好的 AI 接口第二类是注重隐私的研究者或自由职业者手头有敏感客户数据、未公开论文草稿或商业策略文档绝不能让它们流经第三方 API第三类是教育工作者或学生想真正理解 LLM 的输入输出机制、工具调用流程、RAG 检索链路而不是被封装得密不透风的“智能助手”惯坏思维。它不承诺“一键超越 ChatGPT”但它保证你改的每一行配置都会在下次刷新后立刻生效你删掉的每一个插件都不会留下后台进程你导出的每一段对话都是标准 JSON没有 DRM没有水印没有隐藏字段。2. LibreChat 的整体架构设计为什么它不是“又一个前端”而是一个协议编排器2.1 核心定位从“聊天前端”到“AI 协议路由器”很多初学者看到 LibreChat 的 UI会下意识把它归类为 “ChatGPT 的开源替代品”。这是个根本性误解。它的底层设计哲学更接近于一个“AI 协议路由器”AI Protocol Router而非“聊天客户端”。你可以把它想象成网络世界里的 Nginx —— 它本身不生产内容但负责精准地将用户的请求根据预设规则路由到不同的“后端引擎”并把返回结果标准化地组装、呈现给用户。这个定位决定了它的三大关键设计选择第一彻底解耦前端与后端。LibreChat 的前端React只负责渲染、状态管理、UI 交互所有模型调用、工具执行、记忆存储的逻辑全部由后端Node.js Express完成。后端再通过一系列适配器Adapters对接不同协议的后端服务。这意味着你可以在同一个 LibreChat 界面里左边和 GPT-4 Turbo 对话右边同时用本地运行的 Phi-3-mini 做代码补全中间再嵌入一个用 MCP 协议调用的 Figma 插件——它们共享同一套会话历史、同一套文件上传管理、同一套快捷指令系统但背后是完全独立、互不干扰的执行环境。这种解耦带来的好处是灾难性的当 OpenAI 的 API 出现区域性抖动时你的本地 Ollama 模型依然稳如泰山当 Gemini 的免费额度用尽你的 Claude 3 Sonnet 实例照常工作。第二原生支持多协议接入MCP 是其战略支点。LibreChat 的providers目录里不仅有openai,gemini,anthropic这些传统 API 提供商的适配器更有一个名为mcp的独立模块。这不是一个简单的“兼容层”而是对 MCPModel Communication Protocol规范的深度实现。MCP 的核心思想是把 LLM 的“工具调用”能力从各家私有、混乱的 JSON Schema 格式中解放出来定义一套通用的、基于 HTTP 的、可发现的、可验证的工具描述与调用标准。LibreChat 的 MCP 适配器会主动向你配置的 MCP Server 发起/tools请求获取一份机器可读的工具清单包含名称、描述、参数 schema、执行端点然后在前端动态生成工具选择面板并在用户确认后构造符合 MCP 规范的POST /tool_call请求。这直接解决了当前 Agent 开发中最头疼的问题每次接入新工具都要手动写一遍参数校验、错误处理、结果解析。LibreChat MCP让工具集成从“写代码”变成了“填表单”。第三状态管理下沉会话即数据资产。LibreChat 默认使用 SQLite 存储所有会话、消息、用户设置。这不是为了“轻量”而是为了确立一个基本原则你的对话历史是你自己的数据资产不是平台的运营资产。SQLite 文件可以随时备份、迁移、用 Python 脚本批量分析词频、用 SQL 查询某次会议纪要中提到的所有技术名词。我曾用一个 5 行的sqlite3命令把过去三个月所有包含“API Key”字样的消息导出成 CSV用于审计团队的安全意识培训材料。这种“数据主权”设计是它区别于所有 SaaS 类聊天工具的根本分水岭。2.2 架构图谱三层模型与四类连接器LibreChat 的实际运行可以清晰地划分为三个逻辑层表现层Presentation Layer纯静态 React 应用无服务端渲染SSR所有状态当前会话、模型选择、插件开关均通过 WebSocket 与后端实时同步。UI 组件高度模块化MessageBubble、ToolSelector、FileUploader都是独立的、可复用的单元。协调层Orchestration Layer这是 LibreChat 的心脏由 Node.js 后端实现。它不直接调用模型而是扮演一个“指挥官”角色接收前端发来的chat请求根据用户选择的 Provider如openai或mcp加载对应的适配器若请求涉及工具调用先调用toolRouter模块解析用户意图匹配可用工具将最终的请求体含 system prompt、history、tool definitions转发给目标后端接收响应进行标准化处理如统一content字段格式、提取tool_calls数组再推送给前端。执行层Execution Layer这才是真正的“大脑”所在LibreChat 本身不包含任何模型推理能力。它通过四种连接器与外部执行环境对接API 连接器对接 OpenAI、Gemini、Anthropic 等公有云 API走标准 REST。Ollama 连接器通过 Ollama 的/api/chat端点调用本地运行的模型支持流式响应。MCP 连接器作为 MCP Client发现并调用符合 MCP 规范的任意工具服务如 Figma AI Bridge、LiveKit Agents、DevSpace MCP Server。自定义连接器开发者可编写customProvider通过 HTTP 或 WebSocket对接任何私有模型服务如 vLLM、TGI、甚至自己写的 Flask 推理 API。这种分层架构让 LibreChat 具备了极强的“抗风险”能力。去年 10 月OpenAI 的/v1/chat/completions端点在全球范围内出现长达 47 分钟的超时故障。我们团队当时正在用 LibreChat 做一场线上技术分享的实时问答。故障发生后运维同事只用了 90 秒就在 LibreChat 的管理后台将默认 Provider 从openai切换为ollama后端已预装phi3:mini整个过程用户无感知问答继续流畅进行。这种“热切换”能力正是源于其清晰的分层与解耦。2.3 为什么选择 MCP 而非其他协议一次真实的选型权衡在决定将 MCP 作为 LibreChat 的战略协议之前我们团队花了整整三周时间对比了四种主流方案OpenAI Function Calling、Google Gemini Tool Calling、LangChain Tool Schema 和 MCP。最终选择 MCP不是因为它“最新”而是因为它在四个关键维度上给出了最优解维度OpenAI Function CallingGoogle Gemini Tool CallingLangChain Tool SchemaMCP协议开放性私有 JSON Schema仅限 OpenAI 生态私有 JSON Schema仅限 Google 生态开源但需依赖 LangChain SDKIETF 提案级标准HTTP JSON无 SDK 依赖工具发现能力无。工具列表硬编码在 prompt 中无。工具列表硬编码在 prompt 中无。工具需在代码中注册有。GET /tools返回完整、可验证的工具目录错误处理语义invalid_tool_call错误码模糊需人工解析INVALID_TOOL_CALL错误码同样模糊依赖 Python 异常类型跨语言困难400 Bad Request 标准化error字段含code和message部署复杂度低。只需配置 API Key低。只需配置 API Key高。需引入 LangChain 依赖版本易冲突中。需部署一个 MCP Server但 Server 可复用一个 Server 可服务多个 LibreChat 实例最关键的转折点是我们用 MCP 实现了一个“动态 Figma 插件面板”。传统方式下要在 LibreChat 里集成 Figma AI 功能必须在 LibreChat 代码里硬编码 Figma 的 API 地址、认证方式、每个操作如getSelectedElements,createFrame的参数结构每次 Figma 更新 API就要同步修改 LibreChat 的适配器代码用户无法知道当前 Figma 文档里有哪些可操作的图层。而采用 MCP 后我们只需在 Figma 插件中启动一个轻量级 MCP Server用mcp/servernpm 包10 行代码LibreChat 启动时自动发现该 Server并拉取其/tools列表列表会动态显示当前 Figma 文档中所有可被 AI 操作的图层名如Header Section,User Avatar Group因为getSelectedElements工具的description字段里包含了实时查询的逻辑。这个案例让我们确信MCP 解决的不是“能不能调用工具”的问题而是“如何让工具生态像 App Store 一样可发现、可组合、可演进”的问题。LibreChat 选择 MCP本质上是在押注一个去中心化的、由开发者共建的 AI 工具市场而不是绑定在某一家巨头的围墙花园里。3. 核心细节解析与实操要点从零部署一个带 MCP 支持的 LibreChat3.1 环境准备避开 Docker 的“甜蜜陷阱”官方文档强烈推荐使用 Docker Compose 一键部署。这确实方便但也是新手踩坑最多的地方。我建议除非你有成熟的 Docker 运维经验否则首次部署务必选择裸机安装Linux/macOS。原因有三端口冲突隐形化Docker 容器内的 LibreChat 默认监听3001但如果你本机已有其他服务占用了3001Docker 会静默地将容器端口映射到3002而前端配置文件里写的还是3001导致页面白屏排查起来非常痛苦。SQLite 权限迷雾Docker 容器内运行的 Node.js 进程以非 root 用户身份运行对挂载卷的 SQLite 文件可能没有写权限。你会看到SQLITE_CANTOPEN错误但日志里不会明确告诉你是因为权限问题而是笼统的“Database initialization failed”。MCP 调试断层当 LibreChat 通过 MCP 调用本地 Figma 插件时Figma 插件的 MCP Server 运行在宿主机上http://localhost:5000而 LibreChat 容器内访问localhost指向的是容器自身而非宿主机。你需要额外配置--networkhost或复杂的extra_hosts这对新手是认知负担。所以我的实操步骤是# 1. 确保 Node.js 18.17.0 (LTS) node -v # 应输出 v18.17.0 或更高 # 2. 克隆仓库不要用 master 分支用最新的 release tag git clone https://github.com/danny-avila/LibreChat.git cd LibreChat git checkout v0.9.10 # 截至 2024 年 6 月的最新稳定版 # 3. 安装依赖注意不要用 npm install用 pnpm速度更快且依赖更干净 curl -fsSL https://get.pnpm.io/install.sh | sh source ~/.pnpm-env pnpm install # 4. 复制环境配置模板 cp .env.example .env提示.env文件是 LibreChat 的生命线90% 的问题都源于此。不要试图“最小化”配置先把所有#注释掉的选项都取消注释按需填写。特别是MONGODB_URI如果你不打算用 MongoDB必须将其值设为空字符串否则 LibreChat 会强制尝试连接 MongoDB 并失败。这是官方文档里一个严重的疏漏。3.2 关键配置项详解那些藏在注释里的魔鬼细节.env文件里有五个配置项是决定 LibreChat 是否能“活下来”的关键。它们的值不是随便填的背后都有严格的逻辑1.PORT3001与API_PORT3001这两个端口必须一致。LibreChat 的前端/public是静态文件由后端 Express 服务直接托管。如果PORT是3001而API_PORT是3002那么前端发起的fetch(/api/conversation)请求会因为跨域http://localhost:3001-http://localhost:3002而被浏览器拦截。解决方案只有一个保持两者相同。如果你的3001端口被占用就一起改成3002。2.PROVIDERSopenai,ollama,mcp这是 LibreChat 的“能力开关”。默认值是openai意味着只有 OpenAI 模型可用。要启用 MCP必须显式地将mcp加入此列表。很多人以为只要在MCP_SERVER_URL里填了地址MCP 就自动生效这是错的。LibreChat 的启动脚本会遍历PROVIDERS列表只为列表中存在的 Provider 加载对应的适配器模块。mcp不在列表里它的适配器代码根本不会被 require 进来MCP_SERVER_URL自然也就成了废纸。3.MCP_SERVER_URLhttp://localhost:5000这个 URL 必须指向一个正在运行的、可被 LibreChat 进程访问到的MCP Server。重点在于“可访问”。如果你的 MCP Server 运行在另一台机器上这里就要填http://192.168.1.100:5000而不是http://localhost:5000。localhost在 Linux/macOS 上永远指向本机这是一个铁律。另外URL 的末尾不能加/。http://localhost:5000/会导致 LibreChat 发起GET http://localhost:5000//tools请求产生 404。4.OLLAMA_BASE_URLhttp://localhost:11434Ollama 的默认端口是11434但如果你用sudo ollama serve --host 0.0.0.0:11434启动了 Ollama那么localhost就不再有效因为0.0.0.0绑定的是所有网卡localhost只是回环地址。此时你必须将OLLAMA_BASE_URL改为http://127.0.0.1:11434。127.0.0.1和localhost在绝大多数情况下等价但在某些 DNS 解析异常的环境下127.0.0.1更可靠。5.DEFAULT_MODELgpt-4-turbo这个值必须与你在PROVIDERS中启用的 Provider 的模型 ID 完全一致。例如如果你只启用了ollama那么这里就不能填gpt-4-turbo而应该填llama3:8b前提是你的 Ollama 已pull llama3:8b。LibreChat 启动时会检查DEFAULT_MODEL是否存在于当前激活的 Provider 的模型列表中。如果不存在它会静默地 fallback 到第一个可用模型但这个过程没有任何日志提示用户会发现“默认模型”下拉框里是空的或者选中的模型与预期不符。3.3 MCP Server 的搭建用 10 行代码点亮你的第一个 AI 工具LibreChat 是 MCP Client它需要一个 MCP Server 来提供工具。我们以一个最简单的“计算平方根”的工具为例展示如何从零搭建一个 MCP Server# 1. 初始化一个新项目 mkdir my-mcp-server cd my-mcp-server npm init -y # 2. 安装核心依赖 npm install mcp/server mcp/types # 3. 创建 server.js cat server.js EOF const { createServer } require(mcp/server); const { Tool } require(mcp/types); // 定义一个工具计算平方根 const sqrtTool new Tool({ name: calculate_sqrt, description: Calculate the square root of a number., inputSchema: { type: object, properties: { number: { type: number, description: The number to calculate the square root of. } }, required: [number] } }); // 实现工具的执行逻辑 sqrtTool.execute async ({ number }) { if (number 0) { throw new Error(Cannot calculate square root of negative number.); } return { result: Math.sqrt(number) }; }; // 创建并启动 MCP Server const server createServer({ tools: [sqrtTool], port: 5000, host: localhost // 绑定到 localhost确保 LibreChat 能访问 }); server.listen(); console.log(MCP Server running on http://localhost:5000); EOF # 4. 启动服务器 node server.js现在回到 LibreChat 的.env文件确保MCP_SERVER_URLhttp://localhost:5000然后启动 LibreChatpnpm run dev打开http://localhost:3001新建一个对话点击右下角的号你应该能看到一个名为calculate_sqrt的工具卡片。点击它输入{number: 144}发送。LibreChat 会将这个请求转发给你的 MCP ServerServer 计算出12并将结果返回。整个过程LibreChat 的前端会自动将{result: 12}插入到对话流中就像模型自己生成的一样。注意这个例子展示了 MCP 的核心价值——工具的定义schema与执行logic是分离的。sqrtTool的inputSchema是机器可读的LibreChat 可以据此在前端生成一个带数字输入框的表单而execute方法是纯 JavaScript你可以在这里调用任何你想要的后端服务、数据库查询、甚至启动一个 Python 脚本。这种分离让 AI 工具的开发回归到了 Web 开发最熟悉的“定义 API 实现业务逻辑”的范式。4. 实操过程与核心环节实现一次完整的“本地代码审查 Agent”构建4.1 场景设定让 LibreChat 成为你代码仓库的“AI 助理”我们的目标是在 LibreChat 界面中上传一个src/utils/dateFormatter.js文件然后提问“这个函数有没有潜在的时区 bug请逐行分析。” LibreChat 应该能接收并安全地存储该文件调用一个本地运行的代码分析模型如codellama:7b-instruct同时通过 MCP 协议调用一个名为code_reviewer的工具该工具能从 Git 仓库中获取该文件的历史提交记录git log -n 5 --oneline src/utils/dateFormatter.js查询公司内部的代码规范文档一个 Markdown 文件将这些上下文信息连同用户上传的代码一起喂给代码分析模型。这个流程完美体现了 LibreChat 作为“协议编排器”的威力它把文件上传LibreChat 原生功能、模型调用Ollama Provider、工具调用MCP Provider这三股力量拧成了一股绳。4.2 步骤一准备本地模型与 MCP Server首先确保你的 Ollama 已安装并运行# 拉取 CodeLlama 模型7B 版本平衡速度与能力 ollama pull codellama:7b-instruct # 启动 Ollama如果尚未运行 ollama serve然后创建一个更强大的 MCP Server名为code-reviewer-mcpmkdir code-reviewer-mcp cd code-reviewer-mcp npm init -y npm install mcp/server mcp/types cat server.js EOF const { createServer } require(mcp/server); const { Tool } require(mcp/types); const { execSync } require(child_process); const fs require(fs).promises; // 工具1获取 Git 历史 const gitLogTool new Tool({ name: get_git_log, description: Get the git commit history for a specific file., inputSchema: { type: object, properties: { file_path: { type: string, description: The relative path to the file in the git repository. } }, required: [file_path] } }); gitLogTool.execute async ({ file_path }) { try { // 假设当前工作目录就是你的 Git 仓库根目录 const output execSync(git log -n 5 --oneline ${file_path}, { encoding: utf8 }); return { git_history: output.trim() }; } catch (error) { return { error: Failed to get git log: ${error.message} }; } }; // 工具2读取内部规范 const readSpecTool new Tool({ name: read_code_spec, description: Read the internal company coding specification document., inputSchema: { type: object, properties: { section: { type: string, description: The section of the spec to retrieve (e.g., Date Handling, Error Logging). } }, required: [section] } }); readSpecTool.execute async ({ section }) { try { // 读取本地 Markdown 文件 const specContent await fs.readFile(./coding-spec.md, utf8); // 这里可以添加简单的文本搜索逻辑根据 section 提取相关内容 return { spec_content: specContent.substring(0, 1000) ... }; // 简化版实际应做精确匹配 } catch (error) { return { error: Failed to read spec: ${error.message} }; } }; // 创建 Server const server createServer({ tools: [gitLogTool, readSpecTool], port: 5001, // 使用 5001避免与之前的 sqrt server 冲突 host: localhost }); server.listen(); console.log(Code Reviewer MCP Server running on http://localhost:5001); EOF # 创建一个模拟的规范文件 echo # Date Handling\n- Always use UTC for storage.\n- Convert to local time only for display. coding-spec.md # 启动 Server node server.js4.3 步骤二配置 LibreChat 以协同工作编辑 LibreChat 的.env文件关键配置如下# 启用所有需要的 Provider PROVIDERSollama,mcp # 配置 Ollama OLLAMA_BASE_URLhttp://127.0.0.1:11434 OLLAMA_DEFAULT_MODELcodellama:7b-instruct # 配置 MCP指向我们刚启动的 Server MCP_SERVER_URLhttp://localhost:5001 # 设置默认模型为本地模型 DEFAULT_MODELcodellama:7b-instruct # 启用文件上传默认是开启的但确认一下 ENABLE_FILE_UPLOADtrue MAX_FILE_SIZE10485760 # 10MB4.4 步骤三构造一个“智能” System PromptLibreChat 的强大之处在于它允许你为每个会话甚至每个模型定制system message。这是引导 Agent 行为的“宪法”。对于我们的代码审查场景我们在 LibreChat 的 UI 中为codellama:7b-instruct模型设置以下 system messageYou are an expert senior software engineer specializing in JavaScript and frontend development. Your task is to perform a thorough, line-by-line code review of the provided JavaScript file. You have access to two external tools: 1. get_git_log: Use this to retrieve the recent commit history for the uploaded file. This helps you understand the context and evolution of the code. 2. read_code_spec: Use this to retrieve the companys internal coding standards, especially regarding date handling, error logging, and security practices. Before giving your final verdict, you MUST: - First, call get_git_log with the exact file path. - Then, call read_code_spec with the section Date Handling. - Finally, analyze the code in light of both the git history and the coding spec. Your response must be in clear, concise English, structured as: - Summary: A one-sentence overall assessment. - Line-by-Line Analysis: For each line that has an issue, state the line number, the problem, and a concrete fix. - Recommendation: A single actionable step the developer should take next.这个 prompt 的精妙之处在于它没有告诉模型“怎么做”而是定义了“必须做什么”。它强制模型遵循一个固定的、可审计的流程先查历史再查规范最后分析。这直接规避了 LLM 常见的“幻觉”问题——模型不会凭空编造一个不存在的 Git 提交也不会杜撰一条公司没有的规范。它的所有结论都建立在两个 MCP 工具返回的真实数据之上。4.5 步骤四执行与结果验证启动 LibreChatpnpm run dev打开http://localhost:3001选择codellama:7b-instruct模型。点击左下角的 paperclip 图标上传dateFormatter.js。输入问题“这个函数有没有潜在的时区 bug请逐行分析。”观察控制台日志你会看到 LibreChat 后端日志显示它收到了chat请求。紧接着会看到它向http://localhost:5001/tools发起 GET 请求获取工具列表。然后它会向http://localhost:5001/tool_call发送 POST 请求调用get_git_log。code-reviewer-mcpServer 的控制台会打印出git log的输出。LibreChat 收到响应后会再次调用read_code_spec。最后LibreChat 将原始代码、Git 日志、规范片段一起打包发送给http://127.0.0.1:11434/api/chat。几秒钟后前端会显示一个结构清晰的回复其中明确指出了dateFormatter.js第 12 行new Date().toLocaleString()的问题“This line uses local timezone without explicit specification, which can cause inconsistent behavior across different user locales. Fix: Usenew Date().toISOString()for UTC storage, orIntl.DateTimeFormatfor controlled local display.”整个过程没有一行代码是 LibreChat 自己写的“AI 逻辑”它只是忠实地执行了你定义的协议和流程。它把一个复杂的、多步骤的、需要外部数据的 Agent 任务分解成了几个原子化的、可验证的 HTTP 调用。这就是 LibreChat 的核心价值它不取代你的专业判断而是把你已有的专业知识Git、规范文档、代码分析模型用一种标准化、可复用的方式编织成一个强大的 AI 工作流。5. 常见问题与排查技巧实录那些只有亲手部署过才会懂的坑5.1 “页面白屏Network Tab 显示 404” —— 最经典的入门陷阱现象浏览器打开http://localhost:3001一片空白F12 打开 Network Tab看到GET http://localhost:3001/返回 200但紧接着GET http://localhost:3001/static/js/main.123abc.js返回 404。根本原因LibreChat 的前端构建产物默认期望被托管在一个根路径/下。但如果你是通过pnpm run dev启动的开发服务器它会启动一个 Express 服务将build/目录下的静态文件托管在/下。然而如果你错误地使用了pnpm run build serve -s build这样的命令serve工具会启动一个静态文件服务器但它默认的index.html里引用的 JS/CSS 资源路径是./static/...而serve的根目录是build/所以./static/就是build/static/一切正常。但如果你的build/目录结构被破坏或者你手动移动了文件就会出问题。终极解决方案永远不要用serve工具。LibreChat 的开发模式就是pnpm run dev。这个命令会同时启动前端开发服务器Vite和后端 API 服务器Express并配置了代理确保所有/api/请求都转发给后端。白屏 40499% 的情况是因为你没有运行pnpm run dev而是试图用其他方式启动前端。快速验证在终端里运行ps aux | grep node你应该能看到两个node进程一个在运行vite一个在运行express。如果只有一个说明你只启动了后端或者只启动了前端必须用pnpm run dev一起启动。5.2 “MCP 工具列表为空或者调用时报 404” —— 协议握手失败现象LibreChat 启动日志里有MCP provider initialized但界面上看不到任何 MCP 工具。或者当你点击工具时控制台报错Failed to fetch http://localhost:5000/tool_call: 404 (Not Found)。排查链条第一步确认 MCP Server 是否真在运行在终端里运行curl -v http://localhost:5000/tools。如果返回Could not resolve host: localhost说明 Server 没启动或者端口不对。如果返回404 Not Found说明 Server 启动了但/tools路由没注册成功检查你的server.js里是否调用了createServer并传入了tools数组。第二步确认 LibreChat 是否真的在调用在 LibreChat 的后端日志里pnpm run dev的终端输出搜索MCP. 你应该能看到类似Fetching tools from MCP server at http://localhost:5000的日志。如果没有说明PROVIDERS里没加mcp或者.env文件没被正确加载检查pnpm run dev命令是否在 LibreChat 根目录下执行。第三步确认网络连通性。这是最隐蔽的坑。在 LibreChat 的后端代码里它用的是 Node.js 的fetchAPI。fetch(http://localhost:5000/tools)在 Node.js 里localhost指向的是 Node.js 进程所在的机器。这通常没问题。但如果 LibreChat 是在 Docker 容器里运行的而 MCP Server 在宿主机上那么