企业代理连接
连通你公司的应用程序一次, 然后给每个AI代理 自己的钥匙,只有访问你 给它。 代理通过一个 MCP 端点到达应用程序; 每一次通话都会对照 代理人的补助金,并写给审计日志。 特工从不持有应用程序的证书.
- 内建的应用程序 : Jira, Microsoft 365(外观邮件和日历、SharePoint文件和Excel, 团队,Entra ID, Intune, Dynamics 365),Jamf Pro, Okta, Slack, Salesforce, Gong, SAP S/4HANA,, Oracle NetSuite, ServiceNow, Workday, FedEx, Dell TechDirect, GitHub;以及,在JSON中只描述, GitLab,Argo CD, SonarQube, Datadog, PagerDuty, Grafana, Zephyr Scale, Conference, Lusha, , , (原始内容存档于2018-09-21) (英语), ChurnZero、Adestra、Cvent、Forsta调查(Decipher)、Intercom、Sprout Social、Synthesia、, WordPress, Automox, Qualys, Druva, Drata, SafeBase, Adobe 行政控制台, Ironclad, One Stream,,, Zip, UKG Pro, iCIMS, ZoomInfo, DocuSign, Axonius. (原始内容存档于2018-09-21) (英语).
- 您的应用程序没有代码 : 描述一个内部的 REST API 或 SaaS 应用程序在一个
connector.json,或从它的 OpenAPI 光谱中起草一个 (单位:千美元)文件/http-connectionor.md); SOAP 服务 (单位:千美元)文件/肥皂连接器.md或SAP S/4HANA等OData服务, 动态 365 或 成功因素文档/数据连接器页:1 从它的 WSDL 或$metadata;或数据库(PostgreSQL, SQL 服务器, MySQL, MariaDB, Oracle) 作为命名的查询( e)文档/sql-连接器) (中文(简体) ). - 代理访问 : 勾选每个代理商每个应用程序可以做什么,并将其限制在数值(mailboxs, 网站、项目、客户)。 任何删除的内容都需要明确确认.
- 代理从应用事件开始: a 创建或更新的 Jira 问题开始您选择的代理, 在自己的限制范围内,通过webhook或无法发送一个的投票程序 (单位:千美元)文件/触发器) (中文(简体) ).
- 自办: 一个节点服务 和邮局。 没有UI船;管理者API
(单位:千美元)
packages/server/openapi.json)和输入客户端(packages/client) 用于建筑 您的管理员页面.
如何确保: 文档/安保。添加应用程序 : 文档/连接器在内部系统旁边运行(你自己的) 证书权威, 前面的代理 : 文件/内置网络。 。 。 .
快速开始(约10分钟)
需要使用 Confose v2 的 Docker 选项 , openssl 财务报告和审定财务报表 curl运行服务、邮递和小型
例如内部app(一个命令API),然后让代理阅读一个客户的命令.
cd deploy/docker
cp .env.example .env
sed -i.bak "s|^CONNECT_ENCRYPTION_KEY=|CONNECT_ENCRYPTION_KEY=$(openssl rand -base64 32)|; \
s|^AGENT_CONNECT_ADMIN_TOKEN=|AGENT_CONNECT_ADMIN_TOKEN=$(openssl rand -hex 32)|; \
s|^POSTGRES_PASSWORD=|POSTGRES_PASSWORD=$(openssl rand -hex 24)|" .env && rm .env.bak
docker compose -f docker-compose.yml -f docker-compose.example.yml up --build --wait
保留 CONNECT_ENCRYPTION_KEY:它封存每个存储的证书,没有保存的任何东西都会打开
这个 该服务只收听此机的3000端口,并应用其数据库迁移.
1. 制作一个组织并连接示例应用程序 (它的 API 密钥是 example-key:
TOKEN=$(grep ^AGENT_CONNECT_ADMIN_TOKEN .env | cut -d= -f2)
admin() { curl -s -H "Authorization: Bearer $TOKEN" -H 'content-type: application/json' \
"http://localhost:3000/agent-connect/admin/v1$@"; }
ORG=$(admin /orgs -X POST -d '{"name":"Example Org"}' | sed 's/.*"id":"\([^"]*\)".*/\1/')
admin /orgs/$ORG/connections/orders -X PUT \
-d '{"capabilities":["read","notes"],"fields":{"api_key":"example-key"},"connectedBy":"Example Admin"}'
capabilities 是任何代理从此应用中可以得到的最多; 连接运行该应用的检查 .
2. 制作代理并批准客户的"读取订单" acme 只有这个. 键一次显示 :
NEW=$(admin /orgs/$ORG/agents -X POST -d '{"name":"demo","createdBy":"Example Admin"}')
KEY=$(echo "$NEW" | sed 's/.*"key":"\([^"]*\)".*/\1/')
AGENT=$(echo "$NEW" | sed 's/.*"agent":{[^}]*"id":"\([^"]*\)".*/\1/')
admin /orgs/$ORG/agents/$AGENT/grants/orders -X PUT \
-d '{"capabilities":["read"],"limits":{"customers":["acme"]},"by":"Example Admin"}'
3. 使用克劳德代码:
claude mcp add --transport http orders http://localhost:3000/agent-connect/mcp \
--header "Authorization: Bearer $KEY"
问克洛德要Acme的订单,然后是1002订单(一个不同的客户的):第一部作品,The
两者均在审计日志中(admin /orgs/$ORG/audit) (中文(简体) ). MCP 客户端工作
同样的方式,例如 curl数字 :
curl -s http://localhost:3000/agent-connect/mcp -H "Authorization: Bearer $KEY" \
-H 'content-type: application/json' -H 'accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"orders_get","arguments":{"id":"1001"}}}'
停下来 docker compose -f docker-compose.yml -f docker-compose.example.yml down (编) -v 改为
删除数据库.
更进一步: 连接一个来自 GET /agent-connect/admin/v1/connectors (每个)
列出其设置步骤,作为点击路径和命令,添加自己的应用程序
(单位:千美元)文件/http-connectionor.md),或将服务嵌入到自己的节点应用程序中
(下关.
仅 /agent-connect/mcp, (中文(简体) ), /agent-connect/teams 财务报告和审定财务报表 /agent-connect/events 可能公开。 管理员 API 拒绝任何
载有请求 X-Forwarded-For所以永远不要通过公共负载平衡器.
用你的代码
npm install @arbium/enterprise-agent-connect @arbium/enterprise-agent-connect-client
两种包件船TypeScript类型. 这里每个片段都由 scripts/consumer-test.sh
(完整的文件 : scripts/consumer/对照包装的包裹,在CI.
嵌入礼拜. 每个进程的一个实例,在自己的模块中:
import { builtinConnectors, createAgentConnect } from "@arbium/enterprise-agent-connect";
export const eac = await createAgentConnect({
database: { url: process.env.DATABASE_URL! }, // or a postgres.js instance
encryptionKey: process.env.CONNECT_ENCRYPTION_KEY!,
adminToken: process.env.AGENT_CONNECT_ADMIN_TOKEN!,
connectors: [...builtinConnectors, orders, inventory], // default: every built-in app
});
eac.start(); // the Teams and app event workers; await eac.stop() on shutdown
connectors 是一个应用程序列表 。 每个内置应用程序都别管了;
通过 builtinConnectors.filter((c) => ["jira", "fedex"].includes(c.id)) 只给一些.
eac.fetch 是一个平地 (Request) => Promise<Response> 服务 /agent-connect/*装入
该路径, 在任何正文解析器之前( Express and plain Node use) @hono/node-server:
// Hono
app.all("/agent-connect/*", (c) => eac.fetch(c.req.raw));
// Express 5
import { getRequestListener } from "@hono/node-server";
app.all("/agent-connect/*splat", getRequestListener(eac.fetch));
// Next.js: app/agent-connect/[...path]/route.ts (Node runtime)
const handler = (req: Request) => eac.fetch(req);
export { handler as GET, handler as POST, handler as PUT, handler as PATCH, handler as DELETE };
// Plain Node
import { serve } from "@hono/node-server";
serve({ fetch: eac.fetch, port: 3000 });
输入的管理员客户端 . 管理员 API 拒绝通过负载平衡器提出的请求
(单位:千美元)X-Forwarded-For),因此从您的服务器、网络或同一过程中调用它
(后面有个代理: 文件/内置网络:
import { createClient } from "@arbium/enterprise-agent-connect-client";
const admin = createClient({ baseUrl: "http://localhost:3000", token: process.env.AGENT_CONNECT_ADMIN_TOKEN! });
// In the same process as eac, with no network hop:
// createClient({ baseUrl: "http://agent-connect", token, fetch: (input, init) => eac.fetch(new Request(input, init)) })
const org = await admin.organizations.create("Example Org");
await admin.connect(org.id, "orders", {
capabilities: ["read"],
fields: { api_key: "example-key" },
connectedBy: "Example Admin",
});
const { agent, key } = await admin.createAgent(org.id, { name: "demo", createdBy: "Example Admin" });
await admin.setGrant(org.id, agent.id, "orders", ["read"], { customers: ["acme"] }, "Example Admin");
const rows = await admin.audit(org.id, { agent: agent.id });
你自己的应用程序,没有代码. 将连接符定义通过一个 http 块
(单位:千美元)文件/http-connectionor.md),或 a soap 或者说 odata 块,直入
connectors。检查它像
(单位:千美元) connector.json; 类型是 ConnectorJson数字 :
import type { ConnectorJson } from "@arbium/enterprise-agent-connect";
const orders: ConnectorJson = {
id: "orders",
name: "Orders",
// ...setup steps, fields, capabilities, limits and verify, as in a connector.json
http: {
baseUrl: "https://orders.internal.example.com/api",
auth: { type: "header", header: "X-Api-Key", value: "api_key" },
tools: [{ name: "orders_get", description: "Read one order by its id.", method: "GET", path: "/orders/{id}",
params: { id: { type: "string", description: "The order id", in: "path" } } }],
},
};
你自己的应用程序,每个组织. 每个组织可以通过管理员加入自己的应用程序 API, 随其所欲, 不重启 : 见 通过管理员添加内部应用程序 API 密码。 。 。 .
你自己的应用程序,作为代码. 构建一个 ConnectorModule 在连接器包上,并给它它的
定义为 connector (单位:千美元)文档/连接器) (中文(简体) ). create 获得一个
ConnectorContext, (中文(简体) ), { connector }:定义解析出,并填入了品牌.
import { z } from "zod";
import { audited, Denied, json, listLimit, type ConnectorModule } from "@arbium/enterprise-agent-connect/kit";
const inventory: ConnectorModule = {
id: "inventory",
connector: { id: "inventory", /* ...the rest of its connector.json */ },
create: () => ({
vendor: { connect: async (fields) => ({ ... }), call: async (connection, request) => ({ ... }) },
toolset: {
names: ["inventory_get_stock"],
register(server, ctx, allowed) {
if (allowed.has("inventory_get_stock"))
server.registerTool("inventory_get_stock",
{ description: "How many of one item are in stock.", inputSchema: z.object({ sku: z.string() }) },
({ sku }) => audited(ctx, "inventory_get_stock", sku, async (mark) => {
const skus = listLimit(ctx.limits, "skus");
if (skus && !skus.includes(sku)) throw new Denied(`This agent may not read ${sku}`);
const res = await ctx.call({ method: "GET", path: `/stock/${encodeURIComponent(sku)}` });
mark(res.status);
return json(res.data);
}));
},
},
}),
};
联系一个特工. 每个代理人都使用自己的钥匙(key (上文)关于一个多边协商进程终点,
<your origin>/agent-connect/mcp数字 :
- 克劳德代码 :
claude mcp add --transport http agent-connect https://agents.example.com/agent-connect/mcp --header "Authorization: Bearer $KEY" - Claude API的 MCP 连接器( β)
mcp-client-2025-11-20:mcp_servers: [{ type: "url", url: "https://agents.example.com/agent-connect/mcp", name: "agent-connect", authorization_token: key }]与tools: [{ type: "mcp_toolset", mcp_server_name: "agent-connect" }]. 端点必须可从互联网上达到. - 克劳德管理特工:一个金库
static_bearer证书持有密钥, 键在同一 URL 上 . - 任何 MCP 客户端超过可流 HTTP :
Authorization: Bearer <key>快速开始curl显示原始调用.
报告错误
过 onError 改为 createAgentConnect 在任何错误中听到失败的声音
您使用的服务。 离开,什么也没有叫。 容器的输入为
serveFromEnv 从 @arbium/enterprise-agent-connect/server,所以一个小文件你自己可以
从同一环境启动同一服务器并添加钩:
import { serveFromEnv } from "@arbium/enterprise-agent-connect/server";
await serveFromEnv({
onError: (e) => {
// e.g. your error service's capture call, or a POST to its ingest endpoint
console.log(JSON.stringify({ level: "error", ...e }));
},
});
每种类型都报告在它决定的地方,最多每类每分钟一次,应用,组织, 每个过程中的订阅和bot(因此一个被损坏的不能淹没或隐藏另一个). 钩子扔出的东西,或者一个响起的钩子 被记录下来,永远不会到达服务; 在网络上发送的钩子不应该被挡住(火和遗忘).
| 仁爱 | 何时 |
|---|---|
teams_send_failed | 文件、 文件卡、 批准卡编辑失败或通知 Teams 中的机器人发送失败 |
teams_event_failed | 无法处理来自团队的信件 |
teams_run_start_failed | a 启动启动失败 |
event_failed | 无法处理应用程序事件 |
event_run_start_failed | 无法启动 app 事件触发运行 |
event_poll_failed | 应用程序订阅的民调或图形同步开始失败( 不是每次重试) |
vendor_auth_failed | 应用回复了401或403次被审计的呼叫 |
活动AgentConnectError:
| 外地 | |
|---|---|
kind | 上面的同类之一 |
tags | 作为字符串的 id : org, (中文(简体) ), agent, (中文(简体) ), app, (中文(简体) ), bot, (中文(简体) ), subscription, (中文(简体) ), source, (中文(简体) ), tool, (中文(简体) ), runner, (中文(简体) ), what (各小组拒绝: file, (中文(简体) ), file_card, (中文(简体) ), approval_card, (中文(简体) ), notice, (中文(简体) ), status |
errorClass, (中文(简体) ), code, (中文(简体) ), status | 错误的类名,其 code 和 HTTP 状态, 当它有它们时 |
frames | 发生的地方, {function, file, line, column}当出现错误时 |
timestamp | ISO 8601 标准 |
永远不要错误的信息,信息体,符号或个人的细节:信息可以持有 卖家或一个人的话。 木线不变.
当跑者不回答时
Teams消息或应用事件,其跑者不回答,或回答5xx,408,409或429是
15分钟后再次移交RUNNER_RETRY_SECONDS,0至3600;0 从未重复),
每次尝试都带有相同的 X-Agent-Connect-Delivery id的接收器 调试.
docs/triggers.md,当跑者不回答时,有时间表.
库伯涅斯
只提供一些内置应用程序,设置 BUILTIN_APPS 以逗号分隔(例如
jira,servicenow,sap-s4hana· ; GET /agent-connect/admin/v1/connectors 列出每个编号。 未设置, 每
提供内建应用程序。 您添加的应用程序 CONNECTOR_DIRS 总是提供.
deploy/helm/agent-connect 是一个小图表:部署(replicaCount,默认情况下,任何
数字是安全的),一个服务,以及只有公共路径的可选入侵. 它需要图像
(单位:千美元)image.repository, (中文(简体) ), image.tag; 释放为 ghcr.io/try-caret/enterprise-agent-connect:<version>和一个秘密 DATABASE_URL, (中文(简体) ), CONNECT_ENCRYPTION_KEY
财务报告和审定财务报表 AGENT_CONNECT_ADMIN_TOKEN (单位:千美元)existingSecret) (中文(简体) ). 对于自己的证书的应用
授权签名, 名称为“ 配置图” 或“ 密件” caBundle
(单位:千美元)文件/内置网络) (中文(简体) ).
版式
packages/server:服务(HTTP, admin API, MCP, Teams, app events, store,, ) :, 移民)及其检验packages/connector-kit:连接器所依赖的(计划、工具助手、供应商类型)packages/client: 输入的管理员 API 客户端connectors/<app>: 每个应用程序一个文件夹 :connector.json,用于有代码的应用程序index.ts, (中文(简体) ),tools.ts, (中文(简体) ),vendor.tsconnectors/http, (中文(简体) ),connectors/soap, (中文(简体) ),connectors/odata, (中文(简体) ),connectors/sql: 运行任何应用程序 仅在其connector.json(docs/http-connector.md,docs/soap-connector.md, docs/odata-connectionor.md,docs/sql-connectionor.md) 互联网档案馆的存檔,存档日期2014-12-21examples/internal-app:一个小型内部API及其连接器,用于快速启动scripts/openapi-to-connector.ts: 从 OpenAPI 3.x spec (the 起草本身是connectors/http/openapi.ts,同样在管理员API的内部应用草稿后)examples/legacy-apps: SOAP 和 SAP OData 连接器,仅在 JSON 中描述scripts/wsdl-to-connector.ts, (中文(简体) ),scripts/odata-to-connector.ts: 从 WSDL 起草连接器 或 OData 数据$metadataexamples/legacy-orders: 一个小命令数据库及其连接器deploy/docker, (中文(简体) ),deploy/helm: 图像、 编译文件和图表
许可证
Apache 许可证 2.0。 。 。 .
发展
npm ci
npm run check
scripts/test-databases.sh postgres://postgres@localhost:5432 # a scratch Postgres
TEST_DATABASE_URL=postgres://postgres@localhost:5432/ac_test DATABASE_SSL=disable npm test