跳到主要内容

接入外部工具 (MCP)

你可以把任意一个符合 MCP (Model Context Protocol) 的外部服务挂到 Agent 上,让它在对话里调用你自己的工具——查订单、改工单、拉数据都行。SDK 更进一步:让每个终端用户都用「他自己的」凭据去调用,而不是所有人共用一把后台密钥。 这对把 Agent 嵌进你自己产品的场景尤其重要。

自定义连接器是进阶能力,需要为你的账号开通后才能配置。如果你在「应用」里看不到自定义连接器入口,请联系 OpenHex 团队开通。

一个连接器,三种凭据来源​

把外部 MCP 挂到 Agent 上,叫做配置一个连接器 (Connector)。配置时最关键的选择是:注入给外部服务的 Token 从哪来?

凭据来源 tokenSourceToken 从哪来适用场景
owner(默认)所有者配置一次的共享密钥不区分用户的后台工具,如一个内部只读 API
perUser每个终端用户在对话里通过卡片自助填写用户有 OpenHex 账号、愿意自己填 Token
session你的应用在每次发送时通过 SDK 带上该用户的 Token企业内嵌:用户在你自己的站点登录,你的后端已持有他的 Token

三种来源注入到外部服务的方式完全一致(都放进同一个鉴权头),区别只在「值从哪取」,所以随时可以切换来源而不用改外部服务。

Token 全程不落库、不进 Prompt、也不进入模型上下文——平台只在短时间内持有,由网关在调用外部服务时注入。

session:让每个用户用自己的 Token(推荐用于内嵌)​

终端用户在你的站点登录、可能没有 OpenHex 账号,而你的后端已经握着他的第三方 Access Token。用 SDK 的 mcpTokens 在每次发送时带上即可,用户全程无感。

mcpTokens 的 key 是连接器的 slug,value 是该用户的 Token。

slug 在哪看? 打开该 Agent 的管理后台,进入**「应用」→「自定义应用」**,每个连接器卡片的名称旁都有一个 slug 徽章(标注「Slug(SDK 集成标识)」),点旁边的复制按钮即可。创建连接器时也可以在「Slug(SDK 集成标识)」输入框里自定义后缀——例如填 crm,实际 slug 为 custom-crm(固定带 custom- 前缀);留空则按名称自动生成。slug 创建后不可修改。

import { OpenhexClient } from '@openhex-ai/agent-sdk';

const client = new OpenhexClient({
apiKey: sessionToken,
agentId,
// 传函数:每次发送前重新求值,轮换中的 OAuth Token 自动保持最新
mcpTokens: () => ({ 'custom-crm': currentUser.crmAccessToken }),
});

const turn = await client.sendMessage('帮我查一下我名下所有未结的工单');

也可以按对话或按单轮指定,优先级为 单轮 > 对话 > 客户端:

const convo = client.conversation({ mcpTokens: { 'custom-crm': tokenForThisChat } });

await convo.send('同步我的日历到本周任务', {
mcpTokens: { 'custom-crm': oneOffToken },
});

Token 过期了怎么办​

平台不会在用户 Token 缺失或过期时改用所有者的密钥代为调用——那是跨身份越权。Token 失效时,这一轮里对应的工具调用会失败,Agent 会据此回复用户。

因为 SDK 在每次发送时都会重新带上 Token,你只需要保证 mcpTokens 回调返回的是最新的 Token(例如在回调里刷新你自己的 OAuth 会话),下一轮就会恢复正常,不需要额外处理。

perUser:让用户自助填写(BYOK 卡片)​

连接器配成 perUser 时,如果用户还没填过 Token,Agent 首次调用该工具会在对话里放出一张连接卡片。SDK 负责解析卡片,并把用户填写的凭据保存到他自己的账户下(不会交给 Agent 所有者)。

import { OpenhexClient, extractConnectorSetup } from '@openhex-ai/agent-sdk';

const client = new OpenhexClient({ apiKey: userToken, agentId });
const convo = client.conversation();

const turn = await convo.send('用我的 Notion 建一个页面');

// 从本轮记录里找连接卡片
const setup = turn.records.flatMap(extractConnectorSetup)[0];

if (setup) {
// setup.fields: [{ key, label, … }],按字段渲染表单,收集用户输入
const retry = await convo.submitConnectorSetup(setup, { token: userTypedToken });
console.log(retry?.text); // 保存后 SDK 自动发一条提示,让 Agent 带着新凭据重试
}

submitConnectorSetup 保存凭据后,默认会自动发送一条提示消息让 Agent 重试,并返回这一轮的结果;不要再自己补发一条,否则 Agent 会收到两次。只想保存、不想触发重试时传 { notify: false }。

在 React 里使用​

会话级凭据直接作为组件 / Hook 的属性传入,每次发送时自动带上:

import { ChatWidget } from '@openhex-ai/agent-sdk/react';

<ChatWidget
agentId="你的-agent-id"
getToken={getToken}
mcpTokens={() => ({ 'custom-crm': currentUser.crmAccessToken })}
/>;

连接卡片出现在消息的 connectorSetup 上;用 useOpenhexChat 自己画界面时,调用返回值里的 submitConnectorSetup(setup, values) 提交。

外部服务需要满足什么​

你的 MCP 服务(或你指向的第三方 MCP)需要:

  • 协议:MCP 的 streamable-HTTP(一个 POST 端点)。
  • 鉴权:从请求头读取网关注入的凭据(如 Authorization: Bearer <token>)。
  • 公网可达:HTTPS。

下一步​