AI Bot – 自带 MCP 服务器

:bookmark: 本指南介绍如何将外部 Model Context Protocol (MCP) 服务器连接到 Discourse AI 代理,使任何兼容 MCP 的工具提供商都能直接在 AI 机器人中使用。

:person_raising_hand: 所需用户级别:管理员


什么是“自带 MCP”(Bring Your Own MCP)?

Model Context Protocol 是一项开放标准(最初由 Anthropic 提出),它允许 AI 代理通过标准的 HTTP/JSON-RPC 接口与外部工具服务器进行通信。MCP 服务器公开一组“工具”——即具有类型化输入的函数——LLM 可以调用这些函数来完成任务。

Discourse AI 现在充当 MCP 客户端。您可以在管理面板中注册任何 HTTPS MCP 服务器,Discourse 会自动发现其可用的工具,这些工具随即成为您选择的任何 AI 代理中的核心功能。无需编写任何 JavaScript;工具由远程服务器定义。

这与 自定义脚本工具 不同,后者需要编写在 Discourse 内部运行的 JavaScript。使用 MCP,您只需引入一个已经运行的外部服务器即可。


摘要

  • 注册 MCP 服务器(URL + 可选的身份验证)
  • Discourse 自动发现并缓存服务器的工具
  • 将服务器分配给一个或多个 AI 代理
  • 可选地限制每个代理可使用的工具
  • 工具由 LLM 在运行时调用,通过 Discourse 路由到外部服务器

注册 MCP 服务器

导航至:

管理 → 插件 → Discourse AI → 工具MCP 服务器 选项卡 → 新建 MCP 服务器

填写以下字段:

字段 描述
名称 人类可读的标签(显示在代理编辑器和日志中)
描述 此服务器的用途(供管理员参考)
URL MCP 服务器的 HTTPS 端点——必须是公共 HTTPS URL,不得使用私有 IP
身份验证 选项包括:无身份验证标头凭据OAuth
超时(秒) Discourse 等待每个请求的时间——默认 30 秒,最大 300 秒
启用 切换开关可暂时禁用服务器而无需删除它

:warning: URL 必须使用 HTTPS。localhost 和 RFC-1918 私有地址将被阻止(服务器端强制执行 SSRF 防护)。


身份验证选项

无身份验证

服务器可公开访问。不发送任何凭据。

标头凭据

每个请求都会将秘密值作为 HTTP 标头注入。

  1. 首先在 管理 → AI → 凭据 下创建一个 凭据
  2. 在 MCP 服务器表单中将其选为 凭据
  3. 设置 身份验证标头 名称(默认:Authorization
  4. 设置可选的 身份验证方案 前缀(默认:Bearer

发送到 MCP 服务器的请求标头将为:

Authorization: Bearer <your-secret-value>

您可以更改标头名称和方案以匹配服务器所需的任何身份验证样式(例如,通过留空方案来使用 X-Api-Key: <value>)。

OAuth

Discourse 实现了完整的 OAuth 2.0 + PKCE 流程作为 MCP 客户端。这支持在 OAuth 背后保护其工具的 MCP 服务器。

设置步骤:

  1. 身份验证 设置为 OAuth
  2. 选择 客户端注册
    • 客户端元数据文档(默认)——Discourse 会在 https://your-site.com/discourse-ai/mcp/oauth/client-metadata 发布其自己的 OAuth 客户端元数据。如果 MCP 服务器支持 RFC 7591 动态客户端注册,Discourse 将自动注册
    • 手动客户端凭据——输入您预先注册的 OAuth 客户端 ID 并选择一个 OAuth 客户端密钥 凭据
  3. 可选地设置 OAuth 范围(空格分隔)
  4. 保存服务器
  5. 点击 连接——Discourse 将重定向您到提供商的授权页面
  6. 授权后,您将被返回到管理界面,状态将显示为 已连接

高级 OAuth 选项(切换“显示高级选项”):

选项 用途
OAuth 授权参数 合并到授权请求中的 JSON 对象(例如 {"access_type":"offline"}
OAuth 令牌参数 合并到令牌交换请求中的 JSON 对象
需要刷新令牌 如果提供商未返回刷新令牌,则连接失败

Discourse 会在访问令牌过期前自动刷新,并在有刷新令牌可用时针对 401 错误重试。


测试连接

在将服务器分配给代理之前,请使用编辑器表单上的 测试连接 按钮。这将立即初始化 MCP 会话,调用 tools/list,并返回:

  • 协商的 MCP 协议版本
  • 发现的 工具数量
  • 所有工具的名称

如果测试失败,将内联显示来自服务器的错误消息(或超时指示器)。


Discourse 如何发现工具

Discourse 遵循 MCP 规范 2025-03-26。连接序列如下:

Discourse → POST /  { method: "initialize", params: { protocolVersion, capabilities, clientInfo } }
Server    → { result: { protocolVersion, capabilities } } + Mcp-Session-Id 标头
Discourse → POST /  { method: "notifications/initialized" }   (会话握手完成)
Discourse → POST /  { method: "tools/list", session_id: … }
Server    → { result: { tools: [ { name, description, inputSchema } … ] } }

工具定义按服务器 缓存 1 小时。缓存过期后,后台作业会透明地刷新它。缓存键按站点/服务器区分,因此多站点安装是隔离的。

您也可以通过点击 测试连接 手动触发刷新——这总是会获取最新数据。

服务器的健康状态(healthy / error)会在每次缓存刷新时更新。


将 MCP 服务器分配给 AI 代理

注册服务器后,将其分配给代理:

  1. 前往 管理 → 插件 → Discourse AI → 代理,编辑或创建一个代理
  2. 滚动到 MCP 服务器 部分(位于常规“工具”部分下方)
  3. 列表显示所有启用的 MCP 服务器及其工具数量和估计的令牌成本
  4. 切换启用服务器——它现在对该代理可用

提示:默认情况下,来自服务器的 所有 工具都会对代理可用。本地化字符串很好地说明了这一点:“选定的 MCP 服务器默认公开其所有工具。按代理进行筛选可减少令牌使用量并保持工具选择的专注。”


为每个代理选择特定工具

拥有数十个可用工具会增加每条消息的令牌成本(每个工具定义都会作为系统提示发送给模型)。为了保持精简:

  1. 在代理编辑器中,点击已分配 MCP 服务器旁边的 选择工具
  2. 一个模态框将显示服务器当前公开的所有工具,包括其描述和参数列表
  3. 仅勾选该代理所需的工具
  4. 点击保存——该代理现在将仅看到选定的子集

ai_agent_mcp_servers 连接表将 selected_tool_names 存储为 JSONB 数组。空数组表示“启用所有工具”。


工具命名与冲突解决

MCP 工具名称在单个代理的工具列表中必须是唯一的(包括代理的内置工具和自定义脚本工具)。Discourse 会自动处理冲突:

  • 如果两个不同的 MCP 服务器公开了 同名 的工具,Discourse 会对其进行命名空间处理:servername__toolname
  • 如果内置 Discourse 工具与 MCP 工具共享名称,MCP 工具也会被命名空间处理
  • 如果命名空间处理后仍有冲突,将附加数字后缀(_2, _3, …)

因此,LLM 调用中使用的 function_name 可能与 MCP 服务器上的原始 tool_name 不同。这是透明处理的——MCP 工具类始终单独存储原始的 tool_name_value,并在调用服务器时使用它。


运行时工具调用如何工作

当 LLM 决定使用 MCP 工具时:

  1. 会话重用:Discourse 在当前机器人上下文(context.mcp_state)中查找该服务器的缓存 MCP 会话 ID。会话按机器人回复链创建,并在对同一服务器的工具调用之间重用。
  2. 如需要则初始化:如果不存在会话,则运行新的 initialize + notifications/initialized 握手。
  3. 调用POST / 携带 { method: "tools/call", params: { name: tool_name, arguments: params } }
  4. 会话过期:如果服务器返回 404(会话过期),Discourse 会自动重新初始化并重试一次。
  5. 响应标准化:类型为 text 的 MCP 内容项将被连接。非文本项将被 JSON 序列化。structuredContent 将被格式化为 JSON。
  6. 错误结果:如果服务器返回 isError: true,机器人将收到错误消息而不是结果。

服务器响应可以是纯 JSON 或 SSE 流——Discourse 两者都支持。


令牌成本显示

在代理编辑器中,每个已分配的 MCP 服务器都会显示估计的令牌数量。这是使用 OpenAI 的 cl100k_base 分词器应用于每个工具的完整 JSON 签名(名称 + 描述 + 输入模式)计算得出的。这是一个近似值——实际成本取决于您的 LLM 分词器。

显示令牌成本细分是为了帮助您就分配给特定代理的服务器和工具做出明智的决定。


故障排除

症状 检查内容
测试连接因超时失败 增加 超时(秒)。默认为 30。如果服务器初始化缓慢,尝试 60–120。
测试成功但工具未出现在代理中 确保服务器已 启用,并且代理在其 MCP 服务器部分已将其切换为开启状态。
OAuth 状态显示“需要关注” 编辑器表单上将显示最后的 OAuth 错误。常见原因:刷新令牌过期(点击重新连接)、服务器返回了意外的范围,或客户端元数据 URL 无法从您的服务器访问。
工具名称看起来像 myserver__sometool 这是正常的——另一个工具(内置或来自其他服务器)具有相同的名称。LLM 会自动看到并使用这个命名空间名称。
健康状态在一段时间后显示“错误” 后台刷新作业无法连接到服务器。检查您站点的 /logs,并验证 Discourse 主机是否可以访问 MCP 服务器。
工具在对话中途停止工作 会话过期。Discourse 每次工具调用会自动重试一次,但如果服务器持续重启,请缩短其会话 TTL 或调查服务器端日志。

如需更深入的调试,请通过 ai_bot_debugging_allowed_groups 启用对 AI 转录的访问,并检查完整的对话日志。


技术参考

MCP 协议详情

属性
协议版本 2025-03-26
传输 HTTP POST (JSON-RPC 2.0)
SSE 支持 是(用于流式传输 tools/call 响应)
会话管理 Mcp-Session-Id HTTP 标头
最大响应体 5 MB
客户端 User-Agent Discourse AI MCP Client / <version>

JSON Schema 支持

Discourse 在将工具 inputSchema 定义传递给 LLM 之前,会解析以下 JSON Schema 构造:

  • $ref——相对于根模式的 $defs / definitions 进行解析
  • allOf——合并(属性和 required 数组进行并集合并)
  • anyOf / oneOf——使用第一个非 null 变体

相关源文件


相关主题

:bulb: Discourse-as-MCP-server 功能(discourse/discourse-mcp)是本文的补充:它允许外部 AI 客户端(如 Claude Code、Cursor 等)读写您的 Discourse 站点。本指南则是其逆过程——它让您的 Discourse AI 代理能够调用外部 MCP 服务器。

3 个赞