mcpField
S
SandBase Harness

SandBase Harness

本地服务
github.com/sandbaseaiAI 与智能体6362 周前更新

关于 SandBase Harness

SandBase Harness 是本地优先的 AI Agent 运行时,提供会话、沙箱化工具、记忆、凭证、审计日志和内置控制台。适合需要在自有环境中持久运行并可检查 Agent 行为的团队。

主要功能

  1. 01兼容 /v1 API 的本地运行时与控制台
  2. 02基于 SQLite 的本地元数据存储
  3. 03可恢复的 Server-Sent Events 会话流
  4. 04本地、Docker、Kubernetes 等沙箱后端
  5. 05MCP 工具集、权限策略与审批机制

适用场景

  1. 01在本地或自有基础设施上运行长时间 Agent 会话
  2. 02审计与回放 Agent 的执行过程
  3. 03通过 MCP 工具集与凭证库控制工具访问

MCP 相关

该项目以 MCP 工具集的形式接入工具,并通过权限策略和审批机制管理这些工具的访问。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"sandbaseai-sandbase-harness": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"MANAGED_AGENTS_URL",
"-e",
"MANAGED_AGENTS_API_KEY",
"ghcr.io/sandbaseai/sandbase-harness-mcp:0.3.8"
],
"env": {
"MANAGED_AGENTS_URL": "<MANAGED_AGENTS_URL>",
"MANAGED_AGENTS_API_KEY": "<MANAGED_AGENTS_API_KEY>"
}
}
}
}
启动命令docker run -i --rm -e MANAGED_AGENTS_URL -e MANAGED_AGENTS_API_KEY ghcr.io/sandbaseai/sandbase-harness-mcp:0.3.8
需要配置的环境变量
MANAGED_AGENTS_URLURL of the SandBase Harness runtime API.
MANAGED_AGENTS_API_KEY密钥API key when the connected Harness runtime requires authentication.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
ocighcr.io/sandbaseai/sandbase-harness-mcp:0.3.8

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

SandBase Harness

English | 中文

GitHub stars Listed on deepseek-plugin.org Release Official MCP Registry Discussions CodeQL License

AI 可读的项目元数据:llms.txt · 安装指南

面向 AI Agent 的本地优先运行时。会话、沙箱工具、记忆、凭据、 审计记录和内置控制台,全部运行在你的机器或自有基础设施上。

SandBase Harness 架构

为什么选择它

Agent SDK 负责处理模型循环。生产级 Agent 还需要更多能力:持久化 会话、工具治理、沙箱边界、凭据管理、记忆、可审计性,以及供人类检查 运行情况的界面。managed-agents 就是这一运行时层——不是可视化工作流构建器, 也不是又一个模型 SDK。

需求Harness 提供的能力
安全运行生成的代码本地、Docker、Kubernetes 和可自托管的 Worker 沙箱
检查长时间运行的 Agent持久化会话、可恢复事件流、审计和回放
控制工具访问权限MCP 工具集、凭据保险库、权限策略和审批
运行任意模型OpenAI、Anthropic、MiniMax 和兼容 OpenAI 的服务提供商,包括 DeepSeek V4
保持基础设施自主本地优先的 SQLite 和文件存储,无需托管控制平面

功能

  • 类 Claude Managed Agents 的 /v1 API 和本地控制台
  • 默认使用 SQLite 存储 Agent、会话、环境、凭据保险库、记忆存储、文件、 技能和 API 密钥的元数据;本地文件和技能内容存储在工作区状态目录中
  • 可恢复的 Server-Sent Events,用于会话回放和调试
  • 通过 Settings V2 配置唯一的活动模型服务提供商边界
  • 沙箱后端:本地进程、Docker(每个会话一个容器)、Kubernetes (kubectl exec/cp)、可自托管的 Worker 队列
  • MCP 工具集、权限策略、内置工具和技能包
  • 位于 managed-agents/sdk 的 TypeScript SDK
  • 发布门禁:npm run release:check

快速开始

要求:Node.js 22+、npm 10+,以及模型提供商 API 密钥(OpenAI、 Anthropic、MiniMax 或任何 OpenAI 兼容端点)。Docker 为可选项,仅在使用 Docker 支持的沙箱时需要。

git clone --branch v0.3.8 --depth 1 https://github.com/sandbaseai/sandbase-harness.git
cd sandbase-harness
npm ci
npm run build
mkdir ../my-agents && cd ../my-agents
node ../sandbase-harness/dist/index.js init
node ../sandbase-harness/dist/index.js start

init 会在你运行命令的目录中写入一个工作区:一个 Agent、一个技能 文件夹和 config.yaml,其中的提供商引用使用 ${OPENAI_API_KEY} 环境变量。start 会在 http://127.0.0.1:3000 上提供 API 和控制台。

完成设置还需两个步骤,都在 http://127.0.0.1:3000/dashboard 的 Settings > Setup 中进行:

  1. 提供商。 将 API 密钥粘贴到提供商表单中并保存。页面随后会提示已保存的配置尚未生效,因此需要重启运行时——按 Ctrl+C 停止运行,然后再次运行 start 命令,或使用重启按钮。已保存的设置只有在启动时才会生效。如果列表中没有你的提供商,请选择 OpenAI 兼容供应商并设置其 base URL。
  2. 模型。 在 Agent models 面板中,设置提供商实际提供的模型 ID——例如,DeepSeek 对应 deepseek-chat。每个 Agent 都有自己的模型 ID,因此 init 写入的 gpt-4o 并非适用于所有提供商,错误的 ID 会导致本轮对话因 model_not_found 而失败。

要发送第一条消息,请在控制台中打开 Sessions,为 Agent 创建一个会话,然后在输入框中输入内容。在终端中只需运行一条命令:

node ../sandbase-harness/dist/index.js chat agent_assistant --message "hello" --tool-approval allow

chat 会发送这条消息,并在本轮处理完成后退出;不带 --message 时,它会保持会话打开并持续流式传输,直到你中断它。--tool-approval allow 会预先授权 Agent 可以发起的工具调用;否则,init 模板会将这些调用暂停,等待用户批准。详见 CLI。

npm 上未限定作用域的 managed-agents 并非本项目。在本仓库宣布正式的限定作用域包之前,请只从上方所示的带标签 GitHub 源码版本安装。请勿运行 npx managed-agents 或 npm install managed-agents。

在 Codespaces 中试用

在 GitHub Codespaces 中打开

随附的开发容器会安装依赖项并构建运行时。终端准备就绪后,在转发的端口上启动服务:

node dist/index.js start --host 0.0.0.0

打开转发的 SandBase Harness 控制台端口,然后在 Settings > Setup 中配置模型。Codespaces 的使用可能会产生 GitHub 费用;上方的本地快速开始仍然免费,且所有运行时数据都保存在你的计算机上。

屏幕截图

控制台概览设置API 参考
概览设置API 参考

使用官方 SDK

运行时会在同一端口上提供自己的 /v1 API,官方 Anthropic TypeScript SDK 客户端无需修改即可调用它:将客户端的 baseURL 指向运行时,并提供运行时 API 密钥,然后 examples/official-sdk 中的快速入门示例就能针对它运行完整的一轮交互——消息、工具调用、工具结果和最终回复。每个拉取请求都会运行 tests/conformance/official-sdk-quickstart.test.ts 来执行该示例,因此其中所述的兼容性是经过测试的,而非仅仅声称具备。

同一接口规范见 docs/api.md,本仓库自己的 TypeScript SDK 则在下方的 SDK 部分中介绍。

CMA 兼容性

src/core/capabilities/matrix.ts 逐项声明了对已发布的 Claude Managed Agents 契约的覆盖情况:在官方 SDK 的路由接口中(截至 SDK 0.131.0,共有 110 个方法/路径组合),90 个路由已挂载,20 个按名称拒绝;没有延后处理的路由。 Partial 和 Unsupported 条目始终会注明原因。 下表由 npm run docs:compat 生成;如果与矩阵不一致,契约一致性测试就会失败。

完整兼容性表(自动生成) | 区域 | 官方能力 | 状态 | 备注 | | --- | --- | --- | --- | | headers | `compatibility-header-admission` | 部分支持 | 对任何携带兼容性标头的请求,都会强制执行版本、beta 和互斥规则。不带兼容性标头的请求会作为本地调用方接受;已发布的契约未定义这种情况。这条无标头路径是面向可自托管单租户运行时的刻意本地优先扩展,并在 headers contract §4 中作了记录,因此此项仍标记为部分支持。 | | headers | `extension-namespace-exclusion` | 支持 | | | pagination | `opaque-cursors` | 部分支持 | 集合的封装格式取决于挂载路径:operations 路由器在 `/v1` 下提供 `{data, prev_page, next_page}`,在其 `/v1/x` 镜像下提供本地格式 `{data, has_more, first_id, last_id}`;两者由同一个分页器选择,因此没有任何处理程序会同时输出两种格式;游标是可读的 base64url JSON,而非不透明二进制。每个规范的 `/v1` 集合都提供规范封装格式,没有例外:完整集合列表包含 `{data, prev_page: null, next_page: null}`,分页集合则带有可继续使用的游标——`/v1/sessions` 按页码分页,游标包含 `{order, created_at bounds, page}`,并拒绝在其他排序方式或创建时间范围下重放的游标;`/v1/sessions/{id}/events` 包含 `{order, filter, after_id}`;`/v1/skills` 和凭证审计列表使用 `{offset, filter}`——因此被截断的页面会明确说明这一点,而不会看起来像完整结果。唯一既不属于上述两种格式的列表是 `/v1/environments/{id}/work-items`,这是一个包含 `counts` 对象的分页扩展,契约中有明确说明。 | | pagination | `cursor-query-binding` | 支持 | | | errors | `structured-error-envelope` | 支持 | | | agents | `agent-crud` | 支持 | | | agents | `model-object-profile` | 部分支持 | 字符串和对象形式的模型配置都会逐字段解析。`effort` 和 `speed` 会被存储,并由读取投影返回(Agent 读取、版本读取和会话快照);在 Anthropic 提供方上,它们会根据模型能力表执行——`effort` 会转换为 `output_config.effort`,`fast` 会转换为 `speed: "fast"` 并启用 fast-mode beta,自适应思考模型会接收 `thinking: {type: "adaptive", display: "omitted"}`;如果某个列出的模型不支持指定的级别或速度,则会在准入时拒绝;未知模型 ID 或非 Anthropic 提供方不会发送这些参数;部署自身的 `reasoning_effort` 模型设置属于运维级配置,与此分开处理。对于 `inference_geo`,会按名称以 `unsupported_model_field` 拒绝,因为此运行时没有推理地理区域控制;对于规范的 `multiagent` roster,也会按名称拒绝,而不会执行。 | | agents | `multiagent-roster` | 不支持 | 由于没有可用于实现该功能的线程、协调器或顾问接口,因此在创建和更新 Agent 时都会按名称拒绝规范的 `multiagent` roster;若接受该配置,调用方可能会误以为 roster 委派已生效。本地委派作为单独的扩展注册。 | | agents | `local-delegation-subagent` | 支持 | | | sessions | `session-lifecycle` | 支持 | | | sessions | `initial-events` | 支持 | | | sessions | `prompt-caching` | 支持 | | | sessions | `session-update` | 支持 | | | budget | `session-budget` | 部分支持 | 消耗量根据只追加日志以整数微美分计价;创建会话时可以声明 `max_list_cost` 上限。内置循环会在每轮中检查上限:导致超限的步骤是最后一步,会话会以 `stop_reason budget_reached` 进入空闲状态,并在其前立即记录 `session.usage`;接受预算更新或移除预算后,会话会自行恢复——因上限而搁置的工具调用会完成结算,确保恢复后的轮次有成对的对话记录。达到上限后,下一个会启动工作的事件会因 `budget_reached` 被拒绝,而已在进行中的工作仍可通过结算事件完成,因此不会启动下一个模型请求;已声明结果的修订循环也会读取相同的支出并在达到上限时停止,以 `result budget_reached` 关闭结果,而不会开始下一轮评分或轮次,因为循环中的轮次属于已准入的事件。以下两点差异是有意为之:价格来自运维人员提供的成本配置,而非官方标价,因此若配置无法为会话所用模型定价,则会拒绝该会话的预算;只要有任何已用模型无法定价,就不会提供 `usage.list_cost`。此外,暂停状态只会通过会话自身的 `status_idle` 报告,因为已发布的线程级 `budget_reached` 信号属于本运行时未实现的线程接口。 | | events | `append-only-event-log` | 支持 | | | events | `processed-at-lifecycle` | 支持 | | | events | `session-error-structure` | 支持 | | | events | `error-enum-completeness` | 支持 | | | events | `model-request-span-pair` | 支持 | | | streaming | `resumable-sse` | 支持 | | | streaming | `agent-message-stream-preview` | 支持 | | | tools | `builtin-tool-execution` | 支持 | | | tools | `web-fetch-execution` | 部分支持 | WebFetch 通过 HTTP/HTTPS 执行,并支持域名策略、逐次重定向重新验证、拒绝私有地址、超时和字节数上限、HTML 文本提取以及 `max_content_tokens` 预算;它只转换类文本内容(不渲染图像或 PDF),令牌预算是字符数估算;TLS 主机名会经过验证,但除内容脱敏外,不会对内容进行沙箱隔离。 | | tools | `web-tool-domain-policy` | 支持 | | | tools | `tool-output-overflow` | 支持 | | | tools | `mcp-tool-approval-gate` | 支持 | | | tools | `auto-permission-policy` | 支持 | | | custom-tools | `custom-tool-declaration` | 支持 | | | custom-tools | `custom-tool-worker-execution` | 支持 | | | system-message | `system-message-events` | 支持 | | | memory-stores | `memory-crud` | 支持 | | | memory-stores | `memory-limits-and-preconditions` | 支持 | | | memory-stores | `memory-version-audit` | 支持 | | | memory-stores | `memory-multi-mount` | 支持 | | | memory-stores | `memory-worker-materialization` | 支持 | | | github-repository | `github-repository-materialization` | 支持 | | | github-repository | `github-repository-identity-freeze` | 支持 | | | files | `file-resources` | 支持 | | | files | `file-mount-path` | 支持 | | | credentials | `canonical-credential-wire-profile` | 支持 | | | credentials | `credential-rotation` | 支持 | | | credentials | `credential-injection-execution` | 支持 | | | credentials | `oauth-refresh` | 支持 | | | credentials | `mcp-oauth-validation` | 支持 | | | operations | `webhook-subscriptions` | 部分支持 | 本地已实现,但投递行为不符合已发布契约。订阅通过 `/v1/webhooks` 下的 REST 接口管理(也提供 `/v1/x` 镜像),投递由运行时在启动时组合的桥接器执行:每个持久化事件在广播时都会投影,60 秒的定时任务会重试到期投递并运行到期部署;`POST /v1/webhooks/dispatch` 和 `POST /v1/webhooks/retry-due` 仍可用于按需执行。每次尝试都会携带已发布的标头名称,并使用 Standard Webhooks v1 签名对 id.timestamp.body 进行签名——重试会保留事件 ID,并使用自身的时间戳签名;每个订阅都有自己的 `whsec_` 密钥,该密钥只在创建时返回一次。轮换窗口会在第二个 webhook-signature 条目中保留旧密钥的有效性,直到手动通过 retire-secret 将其退役,或在窗口开放达到部署设置的时长后自动退役(默认 24 小时,可通过 `MANAGED_AGENTS_WEBHOOK_ROTATION_WINDOW_SECONDS` 设置,启动时记录为 webhook_rotation_window;到期时会删除旧列,并在生成签名时强制执行且在重试定时任务中清理;若窗口在 `since` 时间戳功能出现之前开放,则仍须手动退役)——负载采用已发布的 `{type: "event", id, created_at, data: {type, id, organization_id, workspace_id}}` 引用封装,webhook-id 等于事件 ID,组织和工作区值为本地常量。订阅只能指定官方目录中的事件;`*`、`prefix.*` 和未知名称会在写入时被拒绝。会话流只通过已发布名称的投影传递给订阅方(状态事件会映射,`budget_reached` 会按会话和上限去重,内部事件会被丢弃);资源路由会为会话、Agent、环境、保险库和凭证、记忆存储及部署发布生命周期事件。目录中的每个名称都有事件生产方(较粗粒度的会话生命周期名称沿用相同的状态转换:创建时为 pending,通过流投影为 running/idled/requires_action);没有生产接口的已发布名称(`session.thread_*`、`agent.deleted`)会像任何未知名称一样在订阅时被拒绝。已发布的三种自动禁用情况均已实现,其中两种无条件生效,一种为可选启用:尝试中检测到重定向时,会使用已发布的 `disabled_reason` 禁用端点,且不会重试;当端点主机是内部名称或解析为私有地址时,会在建立连接前以其专属的已发布原因拒绝,但仅在部署设置 `MANAGED_AGENTS_WEBHOOK_SCREEN_PRIVATE_ADDRESSES` 时启用;该选项默认关闭,因为环回地址属于私有地址,而可自托管的接收端通常与运行时共用主机;端点持续至少一个窗口失败时,会使用已发布的持续失败原因将其禁用。契约规定了触发条件(持续时间,而非尝试次数;2xx 响应会重置状态),但未规定窗口时长,因此该时长是本地参数:默认 10 分钟,部署可通过 `MANAGED_AGENTS_WEBHOOK_SUSTAINED_FAILURE_WINDOW_SECONDS` 自行设置;运行时会在启动时记录生效的窗口,因为部署变量本身没有写入路径)。重试遵循已发布的带抖动 5-120 秒指数退避规则:上限从 60 秒加倍至 120 秒,每次延迟在 5 秒与当前上限之间均匀随机抽取。 | | operations | `scheduled-deployment-timers` | 部分支持 | 已发布的部署接口端到端实现:对象以 `type deployment`、`depl_` ID、固定的 `{type, id, version}` Agent、`environment_id`、必填且非空的 `initial_events` 列表(用于会话准入以及仅部署使用的 `system.message`)、资源、`vault_ids`、预算、元数据,以及包含 `last_run_at` 和接下来三个 `upcoming_runs_at` 的 schedule 对象进行响应——仅手动运行的部署中这些值为 null,因为自 M052 起 cron 可为空。两种挂载路径都通过同一个路由器提供创建/读取/更新(已发布的动词为 POST,本地版本为 PUT)/归档/暂停/取消暂停/运行/运行到期任务接口,并继续接受本地扁平别名(`agent_id`、`cron`、`timezone`、`payload`)。每次运行都会通过 createWithInitialEvents 创建会话,并记录一条可在 `/v1/deployment_runs` 读取的 `drun_` 运行记录(支持按 `deployment_id`、`has_error`、`trigger_type`、`created_at` 过滤);定时运行的 `trigger_context` 中包含 `scheduled_at`。失败处理遵循已发布契约,且不对称:绑定的 Agent 不存在或已归档时,会归档部署且不创建运行记录;可恢复的 `session_rate_limited_error` 只会记录失败运行;其他已分类的失败会记录运行,并自动暂停部署,`paused_reason.error` 会镜像该运行已分类的 `error.type`。支持手动暂停和取消暂停;已暂停的部署仍接受手动运行。定时运行会发布 `deployment_run.started`/`.succeeded`/`.failed`,手动运行则不会发布这些事件;部署状态转换时会发布 `deployment.created`/`.updated`/`.paused`/`.unpaused`/`.archived`,包括 Agent 消失时的级联操作;而 DELETE 会在一个事务中删除部署及其运行记录,随后发布 `deployment.deleted`。运行时每 60 秒运行一次到期部署;启动时会重新安排其后续日程,不会补跑错过的触发。尚存差距:由于 MCP 出站流量没有受到限制,因此没有产生 `mcp_egress_blocked_error` 的路径。 | | operations | `outcome-grading` | 支持 | | | operations | `outcome-evaluation` | 支持 | | | capabilities | `capability-inventory-endpoint` | 支持 | | | capabilities | `capability-status-truthfulness` | 支持 | | | environments | `environment-hosting-config` | 支持 | | | environments | `environment-network-policy` | 部分支持 | 已发布的 `config.networking` 对象会按其自身词汇接受(limited/unrestricted、`allowed_hosts`、`allow_mcp_servers`、`allow_package_managers`),并由单个规范化器转换为记录中的本地 `config.network` 格式;对于无法识别的类型和未设置的权限,默认采取失败关闭策略;若请求声明的两种格式互不一致,则会被拒绝。现在会应用 limited 策略:每个 limited 沙箱都会获得一个会话级环回出站代理,支持 CONNECT 和绝对 URI HTTP,并且只允许有效许可名单中的目标(`allowed_hosts`,以及在启用包管理器标记时加入的精选公共注册表端点)。docker 提供方会将会话容器连接到一个 `--internal` 网络,该网络唯一允许的对等端是转发至代理的中继 sidecar,因此边界是强制执行的,而非仅供参考;本地提供方会将代理变量注入每个沙箱子进程和 stdio MCP 服务,但这种方式本质上仅为建议——忽略代理变量的进程仍可自由出站——因此会报告 best_effort,而不会声称实现了强制限制。MCP 连接边界会拒绝主机不在策略允许范围内的 url 服务(除非启用了 `allow_mcp_servers`);`web_fetch` 会在每一跳重定向时,将声明的许可名单与现有域名和 SSRF 防护规则取交集;Environment 读取接口会根据有效后端声明的能力,投影 `networking_enforcement`(enforced/best_effort/unsupported/not_applicable)。此项仍标记为部分支持,因为 kubernetes 和 self-hosted 提供方没有安装出站边界——对它们实施 limited 策略时会报告 unsupported,而不会实际应用——而且本地提供方的限制本质上只是建议性的。 | | environments | `environment-work` | 部分支持 | 已在本地工具执行队列之上挂载了完整的已发布 Work API。数据平面:poll 会在调用凭证所属环境范围内,认领最早的可认领项目,并以已发布的 BetaSelfHostedWork 形式返回,同时附带每次认领专属的密钥(包含为该次认领签发的 `sessions_token` 的 base64url JSON,以及 `api_base_url`);ack 会提交认领;heartbeat 会根据已发布的 NO_HEARTBEAT 首次认领哨兵值和 `expected_last_heartbeat` 乐观并发检查来续期心跳租约(412 响应中包含服务器当前的 `current_state`);update 会合并元数据补丁;stop 会记录队列的停止标记。管理平面:list 按从新到旧的顺序使用键集分页游标分页列出项目;retrieve 通过与项目操作相同的项目范围校验来检索单个项目的答案;stats 会根据租约模型计算并报告已发布的 `work_queue_stats` 字段(depth = 当前可认领项数量,pending = 租约有效期内已认领的数量,workers_polling = 最近 30 秒内在 poll 时出现过的身份数量)。除了 Work 系列接口之外,`sessions_token` 还是工作进程的会话级凭证:它可用于读取自身会话(资源列表是工作进程发现所附加存储的方式)、列出和流式传输会话事件、仅发布工具答案类型事件,以及读取或写入会话所附加存储中的记忆——`access: "read_only"` 的附件会以 403 拒绝写入,其他所有路由均返回 401。该投影如实反映了自身的边界:`data` 始终为 `{type: "session", id}`,因为本地每个项目都属于某个会话;每个项目的 `desired_ttl_seconds` 会原样返回而不实际应用;强制停止没有单独的本地模式;结果报告仍通过本地 `/v1/x/worker` 通道进行。此项仍标记为部分支持,是因为存在这些语义差异,而不是因为缺少路由;该系列中的接口没有任何拒绝实现。 | | routes | `documented-route-surface` | 支持 | | | dreams | `dreams` | 支持 | | | threads | `threads-and-coordinator` | 不支持 | 未实现:没有线程资源、线程生命周期或每个线程独立隔离事件的机制,也没有协调器或顾问角色,以及线程级预算事件。已挂载五个已发布的线程路由;这些路由会返回 `unsupported_capability` 拒绝响应并指出此能力,因此 SDK 调用方收到的是 400,而非 404。携带 `multiagent` roster 的请求会按名称拒绝,而不会被静默移除。委派仅通过本地单层 `delegations`/`enable_general_subagent` 扩展实现,这不属于此接口。 | | unsupported | `session-budget-alerts` | 不支持 | (not_applicable) 预算通知是托管计费功能:它需要向支付账户费用的一方提供出站通知渠道;而 SandBase 是单租户本地服务,因此运维人员已经是唯一需要通知的一方。 | | unsupported | `mcp-tunnel` | 不支持 | (not_applicable) MCP tunnel 是托管连接功能,不属于本地优先范围。 | | tools | `web-search-execution` | 支持 | |

CLI

managed-agents init
managed-agents start [--host 127.0.0.1] [--port 3000]
managed-agents apply <file...>   # create or update agents/environments/deployments from manifests
managed-agents list
managed-agents reload
managed-agents chat <agent-id> --message "hello" [--tool-approval ask|allow|deny]
managed-agents template list | install <name> | create <name>

apply 是同一 API 的声明式形式:Markdown 文件,其 frontmatter 是 Agent 定义(--- 下方的正文会成为系统提示词);.yaml 环境文档;或 Markdown 部署清单(frontmatter 包含 name、agent、environment、schedule;正文会成为初始的 user.message)。解析出的 ID 会写入这些文件旁的 managed-agents-lock.json,因此编辑后重新运行 apply 会更新同一资源,而不是创建重复资源——请将锁文件与清单一同提交。后续文件可以按名称引用先前文件,因此 apply coding-assistant.md environment.yaml deployment.md 会将部署配置连接到前两个文件创建的条目。

工具需要审批的轮次会暂停,而不会失败;chat 会先询问,然后让运行时继续同一轮。--tool-approval allow 会预先批准每次此类调用,适用于脚本或 CI 作业;deny 则会拒绝这些调用。没有可供提示的终端时,默认的 ask 不会作出任何决定,并以非零状态退出,同时列出正在等待的调用,因此脚本必须明确声明策略,而不是继承默认策略。自定义工具是例外:只有你自己的客户端才能提供其结果,chat 会说明这一点并以非零状态退出。请参阅用法。

SDK

import { ManagedAgentsClient } from 'managed-agents/sdk';

const client = new ManagedAgentsClient({
  baseUrl: 'http://127.0.0.1:3000',
});

const session = await client.sessions.create({
  agent: 'agent_...',
  environment_id: 'env_...',
});

for await (const event of client.sessions.chat(session.id, 'Hello')) {
  if (event.type === 'agent.message_chunk') {
    process.stdout.write(event.delta ?? '');
  }
}

/v1 API 遵循 Claude Managed Agents 资源格式,因此你也可以将 Anthropic SDK 指向本地运行时:

import Anthropic from '@anthropic-ai/sdk';

const client = new Anthropic({
  apiKey: process.env.MANAGED_AGENTS_API_KEY ?? 'local-dev-key',
  baseURL: 'http://127.0.0.1:3000',
});

const session = await client.beta.sessions.create({
  agent: 'agent_...',
  environment_id: 'env_...',
});

身份验证

默认开放。至少存在一个 API 密钥时,身份验证会启用:

# Static key via environment
export MANAGED_AGENTS_API_KEY=sk-local-example

# Or create a managed key
curl -X POST http://127.0.0.1:3000/v1/api-keys \
  -H "Content-Type: application/json" \
  -d '{ "name": "Local Console" }'

客户端发送 Authorization: Bearer <key>。

集成和示例

  • DeepSeek Harness 插件 — 将此运行时作为 MCP stdio 上的 DSH 插件运行:安装、预检、工具列表和故障排除说明请参阅 examples/deepseek-harness。DSH 项目也可以从 GitHub 源获取便携式 Skill — npx --yes github:sandbaseai/sandbase-skills add multi-source-search 会将其安装到 .dsh/skills/multi-source-search。
  • Agent Plugins 1.0 客户端(Copilot CLI、VS Code)以及独立的 MCP bridge container — 请参阅 agent-plugin/PLUGIN.md。
  • 用例 — Showcase 展示了可审计的编码 Agent、作为交互式前端的 DSH,以及在 Local、Docker、Kubernetes 和可自托管沙箱中受控执行代码的流程。
  • Agent 配置 — YAML Agent 定义、config.yaml 和工作区布局请参阅用法指南;每种资源的 curl 操作指南请参阅 docs/api.md。

文档

开发

npm ci
npm run typecheck    # src + tests + Console
npm test             # vitest
npm run build        # runtime + console + SDK
npm run release:check  # full local release gate

release:check 会运行类型检查、测试、两个构建、npm pack --dry-run、CLI 初始化冒烟测试和 examples/basic 启动冒烟测试。

点赞并分享

如果此运行时解决了你在 Agent 基础设施方面的实际问题, 请为此仓库点星,让其他构建者也能找到它。

生态目录、社区指南和相关项目请参阅 docs/ecosystem.md。社区用例讨论: 在 Codex、Claude Code 和 DSH 之间迁移记忆, 为第三方插件提供沙箱和文件系统保护。

许可证

Apache-2.0

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。