AWR 通过 MCP(Model Context Protocol,模型上下文协议)暴露它的工作 台账。MCP 是让 agent 宿主——例如编码助手或桌面 AI 客户端——发现并调用 工具的标准协议。MCP 服务让你的 agent 无需自己调用 CLI,就能读取项目 状态、编译上下文、记录证据并推进工作。它有两种运行方式:
- stdio——由你的客户端直接启动的本地进程,一次服务一个项目。这是 经典部署方式,仍然可用。
- 共享 HTTP——一个 Streamable HTTP 端点,服务多个项目和多个相互 独立的客户端。npm 和 PyPI 包都包含这一能力。
本文重点介绍共享 HTTP 服务,也就是当不止一个人或 agent 需要同一批项目 时你该运行的形态。连接之后 agent 用这些工具做什么,见 Agents。 同样操作面向人的等价物,见 AWR CLI。
共享服务的工作方式
你在服务器上用 awr init 初始化每个项目,然后注册它的规范绝对根路径, 连同以下命令返回的 project_id:
awr --json status
AWR 在启动时和每次请求时都会核验这一身份。各项目的来源文件和 .awr 数据库保持相互独立——服务不会克隆仓库、挂载客户端文件系统,也不会合并 项目台账。客户端需要的是到服务的网络访问,而不是本地的 AWR 可执行文件; 项目文件必须在服务器上可读:客户端笔记本上的路径不会因此变得可以远程 读取。不存在共享的"当前项目"——每个项目工具都要求显式的 project 参数,也没有任何工具可以打开服务器上的任意路径。
配置服务
在公开仓库之外创建一个由运维人员持有的 TOML 文件:
version = 1
allowed_hosts = ["awr.internal.example"]
[[projects]]
key = "billing"
root = "/srv/projects/billing"
project_id = "<actual project ID>"
[[projects]]
key = "support"
root = "/srv/projects/support"
project_id = "<actual project ID>"
[[clients]]
id = "engineering"
token_env = "AWR_ENGINEERING_TOKEN"
write = ["billing", "support"]
[[clients]]
id = "reviewer"
token_env = "AWR_REVIEWER_TOKEN"
read = ["billing"]
每个客户端条目指定一个环境变量名,其中保存它的 bearer 凭证。请提供 互不相同、随机生成、长度至少 32 个字符的凭证。write 授权包含读权限; read 授权不能修改项目。在轮换凭证时保持客户端 ID 不变——对话和请求 绑定附着在客户端 ID 上,改变它会创建一个不同的作用域。配置变更只有在 服务重启后才生效。
运行服务
awr-mcp --registry /etc/awr/service.toml --listen 127.0.0.1:8080
每个 HTTP 请求都经过认证。内置机制是静态 bearer 认证——不是 OAuth 授权服务器,也不是企业身份提供方。对外提供远程访问时,请在带认证的 部署边界上终结 HTTPS,并限制对后端的直接访问。额外的访问控制:
- 除非显式列在
allowed_origins中,否则 Origin 一律被拒绝;原生客户端 通常不发送Origin头。 - SDK 会检查
allowed_hosts,未配置时默认仅允许回环(loopback)主机。 - 服务会校验 Origin,但不实现浏览器 CORS 预检,因此浏览器前端需要合适 的网关。
在 Unix 上,SIGTERM 和 Ctrl-C 会优雅地停止接受新请求并排空进行中的 HTTP 工作。断开客户端连接或重启服务绝不会结束一个 AWR 工作会话—— 协议连接和持久会话是两个独立的身份。AWR 不安装系统守护进程——请使用 你部署环境的进程管理器来处理启动和重启。对于本地单客户端使用,stdio 命令仍然可用:
awr-mcp --project /absolute/project
连接客户端
把每个 MCP 客户端配置为使用 Streamable HTTP,指向同一个服务 URL 的 /mcp 路径,并通过该客户端的凭证机制在 Authorization: Bearer … 头中 携带它自己的 bearer 凭证。连接成功后,调用 awr_projects_list 发现你的 凭证有权访问的项目键。此后每个项目工具都要求 project 参数:
{"project": "billing", "work": "INVOICE-001"}
工具一览
共享 HTTP 服务总共暴露 21 个工具(stdio 为 20 个,少了项目列表工具)。 它们分为三组。
工作与上下文工具
这些工具对应日常 CLI 操作:
| 工具 | 作用 |
|---|---|
awr_project_status | 当前续接事项、可认领工作、等待项、阻塞、历史摘要 |
awr_work_ready | 已就绪条目,附带诊断和认领提示 |
awr_work_get | 工作项的任务、验收标准、依赖、决策、证据 |
awr_context_compile | 为工作项或分支编译上下文数据包 |
awr_work_transition | 推进、阻塞、解除阻塞、取消、重开或完成工作 |
awr_event_append | 向台账追加事件 |
awr_evidence_record | 记录绑定到工作与验收条目的证据 |
awr_search | 在整个项目台账中搜索 |
会话与续接工具
会话把一段对话绑定到一个工作单元。请提供来自你宿主的稳定 conversation 标识符——而不是 HTTP 连接标识符。同一个对话字符串在 另一个项目或客户端下是独立的绑定。
| 工具 | 作用 |
|---|---|
awr_session_start | 启动绑定工作的会话,可选地认领该工作 |
awr_session_get | 查看绑定、会话、认领、检查点、被中断的保存 |
awr_session_list | 分页浏览该客户端的会话历史 |
awr_session_checkpoint | 持久化已消费的上下文哈希、摘要、下一步行动、未闭合环节 |
awr_session_claim | 获取或释放会话的认领 |
awr_session_end | 显式结束或中断会话并释放其认领 |
awr_session_resume | 创建继承检查点和认领的后继会话 |
awr_session_wait | 保存检查点并为用户记录一个持久的问题 |
awr_session_reply | 把用户的回答送达已记录的等待 |
awr_operation_get | 按请求 ID 查看一次写入的记录结果 |
awr_operation_recover | 在有证据时为被中断的写入记录已提交的结果 |
awr_source_reindex | 从权威来源刷新项目的投影 |
一个未决的等待会阻塞工作转换和恢复,直到宿主记录了回复。回复会解除 这个阻塞,但不改变工作状态,也不安排宿主的下一轮——你的宿主检查会话、 编译新的上下文,然后决定是继续还是创建后继会话。
写入、修订版本与不确定结果
共享 HTTP 上的每次写入都要求两样东西:
- 一个由客户端生成、保持稳定的
request_id(最长 256 字节), - 你最近观测到的
expected_revision。
{
"project": "billing",
"request_id": "host-turn-42-start",
"expected_revision": 120,
"work": "INVOICE-001",
"conversation": "invoice-review",
"agent": "billing-assistant",
"provider": "example-provider",
"model": "example-model",
"claim": true
}
用完全相同的请求 ID 和参数重复请求,会返回已记录的结果而不再次执行, 因此超时后的重试是安全的。参数变了就必须用新的 ID。保存返回的 project_revision 供下一次写入使用,绝不要用加一的方式推算下一个 修订版本:请求日志和域操作都会消耗修订版本号。
超时或断连之后,用同一个项目和请求 ID 调用 awr_operation_get。未完成 的请求会报告 write_outcome: unknown;被中断的写入可能已经提交,所以 绝不要从 HTTP 响应流的关闭推断失败。只有当请求绑定了明确的终止事件时, awr_operation_recover 才能记录已提交的结果——它绝不会重新调用原始 工具。读取可以并发;写入按项目串行化,不同项目有独立的锁。过期的写入 会返回冲突——先读取当前状态,重新考虑后再重试。
工作流读取(开发中)
开发版源码增加了注册表 version = 2,向客户端授予对显式列出的、不可变 工作流的只读访问,适用于使用 YAML 工作流台账的项目。这些是由运维人员 持有的权限:仅有项目级 read/write 授权不会授权任何隔离的工作流。
[[clients.workstreams]]
project = "billing"
workstream_id = "<actual immutable workstream ID>"
authority_version = 1
被授权的客户端使用仅共享服务提供的 awr_workstream 工具,从 action: "capabilities" 和 action: "list" 开始发现自己可以读取什么。 请注意当前的限制:这个扩展只授予读取——不支持变更、内容文件读取或 Team PostgreSQL 操作——而且在有授权实现可用之前,启用它的项目会拒绝 旧的共享工具,包括所有写入。在现阶段,启用和重建索引都是本地运维操作。
