MCP 服务 (0.1.3)

Download OpenAPI specification:

Context Loader 把自己的检索能力同时以 MCP Server 形式对外:Cursor、Claude Desktop 等 MCP 客户端可以直接接入,不必逐个封装 REST 调用。

普通 Agent 默认只使用两个受管生命周期工具:bkn_start_interactionbkn_finish_interaction。每轮 start 都提交完整问题、固定的 agent_nameconversation_mode:没有当前 Conversation 时用 new 且不传 conversation_id;按显式 id 延续时用 continue 并传入 start 返回的 id。 宿主提供会话映射时,以宿主映射为准。finish 只提交当前 Interaction 的 结果,不关闭可跨轮、跨日复用的 Conversation。业务工具包括 search_schemaquery_object_instancequery_instance_subgraphget_logic_properties_valuesget_action_infoexecute_actionget_action_executionlist_action_executionsfind_skillsrun_sqllist_knowledge_networksget_kn_detailget_object_typesget_relation_typeslist_resourcesdescribe_resourcelist_skillsget_skill_contentread_skill_file。 另有一个默认不装配的 execute_skill:它把入口命令送进沙箱执行,只有显式开启 (EXECUTE_SKILL_ENABLED=true)才出现在 tools/listGET /mcp/info, 未开启时与「没编译进来」无异。该开关是技能执行能力的总闸,同时决定 /kn/execute_skill 这条 REST 路由是否注册。业务工具必须显式携带服务自描述 schema 中的 bkn_context, 其中只要求权威返回的 conversation_idinteraction_id;Operation key、租约、 重试和 closure manifest 由 Context Loader 与 BKN Trace Core 管理; 各工具的语义与参数含义见本目录下对应的 REST 文档。

接入方式:Streamable HTTP,端点 /api/agent-retrieval/v1/mcp, 协议流程 initializetools/listtools/call(JSON-RPC 2.0)。 鉴权与 REST 一致:Authorization: Bearer <token>,OAuth access token 或 bak_ 前缀的 AppKey。宿主适配器可选使用 X-OpenBKN-Host-Conversation-KeyX-OpenBKN-Client-Invocation-Id,或对应的 openbkn.ai/host-conversation-keyopenbkn.ai/client-invocation-id MCP _meta 提示会话关联与调用幂等;client-invocation-id 可用于 start 和每一次业务工具调用, 同一 ID 重试复用原 Interaction 或 Operation / Receipt,不同输入返回幂等冲突。 未提供逐调用提示时,跨连接重试退化为 at-least-once。这些提示不参与身份和权限判定, 普通 Agent 参数不得提交。

不想先握手就想知道有哪些工具时,直接 GET /mcp/info——它返回完整的工具目录 (含每个工具的输入输出 schema)与一份可直接粘贴的客户端配置。

MCP

MCP 服务自描述文档

一次 GET 拿到端点、协议、鉴权方式、全部工具的名称 / 描述 / 输入输出 schema, 以及一份可直接用的客户端配置示例。给人看,也给 Agent 自举用。

endpoint 按当次请求推导(识别 X-Forwarded-Proto),因此走网关访问时 返回的就是网关地址,可直接抄进客户端配置。

Authorizations:
OAuth2AppKey
header Parameters
Accept-Language
string

可选的 RFC 9110 语言偏好。服务从支持的 zh-CNen-US 中选择工具目录 (title / description / schema 描述)与服务端说明的语言。

MCP 协议本身不定义语言协商,initialize 参数里没有 locale 字段,所以这个 传输层请求头是唯一的通道。客户端在 MCP 连接配置的 headers 里设置它。

不传则使用部署配置的服务默认语言,无需客户端参与。每个请求独立判定, 不与 Mcp-Session-Id 绑定。

Responses

Response samples

Content type
application/json
{
  • "service": "context-loader",
  • "protocol": "MCP / JSON-RPC 2.0 (initialize → tools/list → tools/call)",
  • "transport": "Streamable HTTP",
  • "auth": "string",
  • "language": "zh-CN",
  • "supported_languages": [
    ],
  • "tool_count": 0,
  • "tools": [
    ],
  • "client_config_example": { }
}

PTC 工具包(旧路径,已弃用) Deprecated

已弃用,改用 GET /mcp/ptc/toolkit 响应完全相同,仅路径不同。

旧路径描述的是 PTC 那套工具面,却挂在 /mcp 下面,读起来像在描述 /mcp—— 与 /mcp/info 的对称关系是错的。保留只为兼容先上线的客户端,新接入不要用。

面向「只给模型一个写代码的工具」这种用法:模型写一段 Python,沙箱执行, 脚本里调用本服务的能力,中间结果留在沙箱,只有 stdout 回到上下文。

本接口一次返回客户端需要的全部素材:

  • tools —— 要暴露给模型的工具全表。客户端应当遍历它建工具,不要按名字 硬编码,这样以后加工具是纯服务端改动。
  • stub —— 沙箱内的 Python 实现,随每次执行内联进脚本。
  • sandbox_mcp_url —— 沙箱回访本服务的集群内地址。沙箱用不了浏览器 侧的网关地址,而集群内地址只有服务端知道。
  • version —— 上述内容的哈希,客户端据此缓存;工具表一变它就变。

由服务端而非客户端渲染工具说明,有两个客户端做不到的地方:一是 schema 里 没有 bkn_context(它是生命周期守卫在运行时向业务工具索取的),从 tools/list 自行渲染的客户端会把它当成必填参数写进签名,让模型去填一个它 没有的值;二是只有服务端知道哪些工具真正注册了。

digest / stub / sandbox_mcp_url 三个顶层字段先于 tools 上线,保留 为兼容字段;digesttoolsrun_codedescription 恒为同一份内容。

Authorizations:
OAuth2AppKey
header Parameters
Accept-Language
string

可选的 RFC 9110 语言偏好。服务从支持的 zh-CNen-US 中选择工具目录 (title / description / schema 描述)与服务端说明的语言。

MCP 协议本身不定义语言协商,initialize 参数里没有 locale 字段,所以这个 传输层请求头是唯一的通道。客户端在 MCP 连接配置的 headers 里设置它。

不传则使用部署配置的服务默认语言,无需客户端参与。每个请求独立判定, 不与 Mcp-Session-Id 绑定。

Responses

Response samples

Content type
application/json
{}

PTC MCP 端点(只有 run_code / run_shell)

/mcp 同为 MCP Streamable HTTP,差别只在工具面:这里只有四个工具

  • bkn_start_interaction / bkn_finish_interaction —— 会话生命周期
  • run_code —— 写一段 Python 交沙箱执行
  • run_shell —— 跑一条 shell 命令

BKN 的全部能力(知识网络、对象类、实例查询、SQL)不在工具面上,而是以 Python 函数的形式存在于 run_code 的沙箱里,签名清单就是 run_code 的工具 描述。中间结果留在沙箱,只有 stdout 回到调用方的上下文。

为什么另开一个端点而不是加到 /mcp:两套工具面互斥。客户端同时看到 run_code 和二十来个业务工具时,模型会挑后者——一行 JSON 就能发,而 run_code 要构思一段脚本。PTC 于是退化成普通工具调用,省上下文这件事也就 不成立了。接入时二选一。

执行在服务端:客户端只发代码,context-loader 带上调用方本人的令牌去打 执行工厂的公开面,那边照常校验算子类型上的 execute 权限。因此任何 MCP 客户端(Claude Desktop、Cursor、第三方 Agent)都能直接用,不必自己实现 「取工具包 + 拼 handler + 打执行工厂」那一套。想自己实现的走 GET /mcp/ptc/toolkit

run_coderun_shell 共用同一个工作目录(按 conversation_id 分), 前者写下的文件后者能直接 wc / head / grep

调用顺序:先 bkn_start_interactionconversation_idinteraction_id, 之后每次调用都带 bkn_context,结束时 bkn_finish_interaction

默认不启用。 run_code / run_shell 是沙箱执行通道,且比 execute_skill 更宽(后者只能跑已注册技能的入口命令),因此服从同一道部署级总闸 EXECUTE_SKILL_ENABLED(默认关)。未开启时本端点返回 404,与「没编译进来」 无异——503 等于向探测者承认这里本该有一条执行通道。

注意 GET /mcp/ptc/toolkitGET /mcp/ptc/info 不受该开关影响:它们只是 文档,不执行任何东西。自建前端拿工具包后是自己去打执行工厂,那侧另有算子类型上 的 execute 权限判定。

Authorizations:
OAuth2AppKey
header Parameters
Accept-Language
string

可选的 RFC 9110 语言偏好。服务从支持的 zh-CNen-US 中选择工具目录 (title / description / schema 描述)与服务端说明的语言。

MCP 协议本身不定义语言协商,initialize 参数里没有 locale 字段,所以这个 传输层请求头是唯一的通道。客户端在 MCP 连接配置的 headers 里设置它。

不传则使用部署配置的服务默认语言,无需客户端参与。每个请求独立判定, 不与 Mcp-Session-Id 绑定。

Request Body schema: application/json
required
object

JSON-RPC 2.0 请求(initialize / tools/list / tools/call …)

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
{ }

PTC 工具包(自行实现 PTC 时用)

给不走 POST /mcp/ptc、想自己实现 PTC 的客户端(例如自建前端)用:一次返回 全部素材,客户端自行组装工具并打执行工厂。

  • tools —— 要暴露给模型的工具全表。遍历它建工具,不要按名字硬编码, 这样以后加工具是纯服务端改动。
  • stub —— 沙箱内的 Python 实现,随每次执行内联进脚本。
  • sandbox_mcp_url —— 沙箱回访本服务的集群内地址。沙箱用不了浏览器侧的 网关地址,而集群内地址只有服务端知道。
  • version —— 内容哈希,客户端据此缓存;工具表一变它就变。

由服务端而非客户端渲染工具说明,有两个客户端做不到的地方:一是 schema 里 没有 bkn_context(它是生命周期守卫在运行时向业务工具索取的),从 tools/list 自行渲染的客户端会把它当成必填参数写进签名,让模型去填一个它 没有的值;二是只有服务端知道哪些工具真正注册了。

注意与 POST /mcp/ptc 的差别:那边由服务端代跑代码,bkn_context 是工具的 必填入参;这里返回的 schema 不含 bkn_context,因为自建前端自己管会话。

digest / stub / sandbox_mcp_url 三个顶层字段先于 tools 上线,保留为 兼容字段;digesttoolsrun_codedescription 恒为同一份内容。

Authorizations:
OAuth2AppKey
header Parameters
Accept-Language
string

可选的 RFC 9110 语言偏好。服务从支持的 zh-CNen-US 中选择工具目录 (title / description / schema 描述)与服务端说明的语言。

MCP 协议本身不定义语言协商,initialize 参数里没有 locale 字段,所以这个 传输层请求头是唯一的通道。客户端在 MCP 连接配置的 headers 里设置它。

不传则使用部署配置的服务默认语言,无需客户端参与。每个请求独立判定, 不与 Mcp-Session-Id 绑定。

Responses

Response samples

Content type
application/json
{}

PTC MCP 端点自描述文档

GET /mcp/info 同构,只是 endpoint 指向 /mcp/ptc。给要接 PTC 端点的 客户端抄连接配置用。

Authorizations:
OAuth2AppKey
header Parameters
Accept-Language
string

可选的 RFC 9110 语言偏好。服务从支持的 zh-CNen-US 中选择工具目录 (title / description / schema 描述)与服务端说明的语言。

MCP 协议本身不定义语言协商,initialize 参数里没有 locale 字段,所以这个 传输层请求头是唯一的通道。客户端在 MCP 连接配置的 headers 里设置它。

不传则使用部署配置的服务默认语言,无需客户端参与。每个请求独立判定, 不与 Mcp-Session-Id 绑定。

Responses

Response samples

Content type
application/json
{
  • "service": "context-loader",
  • "protocol": "MCP / JSON-RPC 2.0 (initialize → tools/list → tools/call)",
  • "transport": "Streamable HTTP",
  • "auth": "string",
  • "language": "zh-CN",
  • "supported_languages": [
    ],
  • "tool_count": 0,
  • "tools": [
    ],
  • "client_config_example": { }
}

MCP Streamable HTTP 端点

标准 MCP Streamable HTTP 入口,收发 JSON-RPC 2.0 报文。请求与响应结构由 MCP 协议定义,本文档不再复述——用现成的 MCP 客户端接入即可,不要手写调用。

同一路径也接受协议规定的其他方法(如用于服务端推送的 GET、用于结束会话的 DELETE),具体以 MCP 规范为准。

tools/list 的每个工具除协议必备字段外,还带一组展示元数据,供客户端直接 渲染工具目录,不必自行维护工具名到中文名的映射表:

  • title:展示名,MCP 协议自身的字段(2025-06-18 起)。缺失时回退到 name
  • _meta["openbkn.ai/group"]:分组标识,稳定值,可用于分支判断。
  • _meta["openbkn.ai/group_title"]:分组展示名。
  • _meta["openbkn.ai/order"]:目录内位置,升序;未声明的排在末尾。

titlegroup_title 随部署的语言设置本地化;grouporder 不随语言 变化。_meta 下这三项不是协议字段,不认识它们的客户端会按协议忽略。 GET /mcp/info 返回同一份元数据,只是平铺成普通字段。

Authorizations:
OAuth2AppKey
header Parameters
Accept-Language
string

可选的 RFC 9110 语言偏好。服务从支持的 zh-CNen-US 中选择工具目录 (title / description / schema 描述)与服务端说明的语言。

MCP 协议本身不定义语言协商,initialize 参数里没有 locale 字段,所以这个 传输层请求头是唯一的通道。客户端在 MCP 连接配置的 headers 里设置它。

不传则使用部署配置的服务默认语言,无需客户端参与。每个请求独立判定, 不与 Mcp-Session-Id 绑定。

Request Body schema: application/json
required
property name*
additional property
any

Responses

Request samples

Content type
application/json
Example
{
  • "jsonrpc": "2.0",
  • "id": 1,
  • "method": "tools/list"
}

Response samples

Content type
{ }