关于 AMR (Agent Mandate Registry)
AMR 是用于记录和验证 AI Agent 代表委托方行动授权的开源 MCP 服务。它结合签名操作令牌与哈希链审计日志,并在本机运行。
主要功能
- 01登记并验证 Agent 授权
- 02带范围检查的签名操作令牌
- 03哈希链操作日志
- 04按角色划分工具配置
- 05撤销授权并生成审计证明
适用场景
- 01记录 Agent 的授权与行动边界
- 02执行前验证操作令牌
- 03审查或异议 Agent 的操作记录
- 04为监督工作提供授权凭证
MCP 相关
向 MCP 客户端提供授权、令牌、日志和审计工具。工具配置按角色区分委托方、Agent 与接收方的能力。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx mandatiaAMR_DB_PATHAbsolute path of the SQLite registry file (default: amr_mandates.db in the client's current directory)AMR_SIGNING_KEY_PATH密钥Absolute path of the registry's Ed25519 private key, created on first use; keep it out of version controlAMR_PUBLIC_KEY_PATH密钥Absolute path of the registry's public key file本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
17收录的工具列表 · 更新于 3 天前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| scope | string | 是 | |
| agent_id | string | 是 | |
| currency | string | 否 | |
| metadata | any | 否 | |
| signed_at | any | 否 | |
| max_amount | any | 否 | |
| period_days | any | 否 | |
| principal_id | string | 是 | |
| risk_classes | any | 否 | |
| amount_actions | any | 否 | |
| duration_hours | number | 是 | |
| allowed_actions | any | 否 | |
| forbidden_actions | any | 否 | |
| parent_mandate_id | any | 否 | |
| period_max_amount | any | 否 | |
| delegation_allowed | boolean | 否 | |
| legal_basis_article | string | 是 | |
| principal_signature | any | 否 | |
| max_delegation_depth | any | 否 | |
| legal_basis_regulation | string | 是 | |
| legal_basis_jurisdiction | string | 否 |
详细介绍
原文在翻译后有更新,译文可能不是最新。
Agent Mandate Registry(AMR)
AI Agent 的法律授权层。
AMR 是一款开源 MCP 服务,用于登记、验证和审计授权 AI Agent 代表委托人行事的法律授权。它提供一条经密码学链接的审计轨迹,记录谁授权哪个 Agent 执行什么操作,以及授权截至何时有效:这些证据可支持部署者履行 EU AI Act 第 26 条规定的人类监督和记录保存义务,并兼顾 eIDAS 2.0 电子授权。AMR 是一种技术工具:它本身并不能使系统合规。
面向 Agent 的快速入门
本节旨在让 AI Agent(Claude Code、Cursor 或任意 MCP 客户端)能够自行安装 AMR 并完成首个已验证的授权:无需账号、无需邮箱,也无需向任何人求助。所有操作都在本机完成;AMR 不会发起网络请求(两个默认关闭的可选例外:操作员设置 AMR_ISSUE_TOKEN 后可调用一次 report_issue;操作员设置 AMR_DID_WEB_RESOLVE=1 后可进行 did:web 密钥检查)。
1. 运行服务(需要 uv)。
uvx mandatia
PyPI 包名为 mandatia;Python 模块和 amr 命令保留原名。uvx amr 安装的是另一个无关项目,请勿使用。若要运行仓库中的最新代码:
uvx --from git+https://github.com/JC7333/amr amr
AMR 兼容 MCP Python SDK 的版本 1 和版本 2(mcp>=1.2,<3);无需额外锁定版本。
也可以克隆仓库并运行 uv sync && uv run amr。
2. 在 MCP 客户端中声明服务。
Claude Code:
claude mcp add amr -- uvx mandatia
Cursor(.cursor/mcp.json)及其他读取 mcpServers 对象的客户端:
{
"mcpServers": {
"amr": {
"command": "uvx",
"args": ["mandatia"],
"env": {
"AMR_DB_PATH": "/absolute/path/amr_mandates.db",
"AMR_SIGNING_KEY_PATH": "/absolute/path/amr_signing_key.pem",
"AMR_PUBLIC_KEY_PATH": "/absolute/path/amr_signing_key.pub"
}
}
}
}
若要运行仓库代码,参数为
["--from", "git+https://github.com/JC7333/amr", "amr"]。
设置这三个路径:默认情况下,AMR 会在客户端的当前目录中写入数据库和签名密钥。请勿将 .pem 私钥纳入版本控制。
3. 完成首个已验证的授权。 Agent 使用工具的顺序如下:
create_mandate:登记谁授权了哪些事项(principal_id、agent_id、scope、legal_basis_regulation、legal_basis_article、duration_hours);设置allowed_actions/forbidden_actions以限定范围;只有issue_action_token会强制执行该范围。verify_mandate(agent_id, action):只要 Agent 持有有效授权,就会返回authorized: true。它不会根据范围检查action;这由issue_action_token执行。log_action(mandate_id, action):向哈希链式日志追加一条记录。issue_mandate_attestation+get_registry_public_key:生成由第三方使用python -m amr.verify_attestation离线检查的签名文件。revoke_mandate(mandate_id, reason):停止按钮;此后verify_mandate会返回authorized: false。已签发的令牌和证明在过期前仍然有效,但接收方重新通过check_action_token检查令牌的情况除外。get_proof(mandate_id):完整的审计资料包(授权、操作、完整性)。 如果 Agent 已执行不该执行的操作,contest_action(mandate_id, action_id, reason, response_days)会记录对此操作提出异议,而list_action_contests会提醒操作员所选的截止日期。report_issue(title, description, version, context):报告 AMR 本身的问题。未设置AMR_ISSUE_TOKEN时,它不会发起网络请求,而会返回一个预填内容的链接供用户打开; 设置后,它会在 GitHub 上提交问题。详见docs/report-issue-spec.md。
测试套件会运行并验证同一流程,示例见
examples/quickstart_agent.py:
git clone https://github.com/JC7333/amr.git && cd amr && uv sync
uv run python examples/quickstart_agent.py # prints every step, ends with "OK"
供 Agent 使用的机器可读摘要:AGENTS.md 和 llms.txt。
如需报告问题,请调用 report_issue,或在
https://github.com/JC7333/amr/issues 提交问题(切勿在其中粘贴真实授权内容或个人数据)。
为什么选择 AMR?
现代 AI Agent 基础设施涵盖了许多方面,但缺少法律授权层:
| 关注领域 | 现有工具 | AMR |
|---|---|---|
| 基础设施与编排 | ✅ LangChain、AutoGen、CrewAI | — |
| 安全与沙箱隔离 | ✅ Docker、RBAC、网络策略 | — |
| 权限与访问控制 | ✅ OAuth、IAM、API 密钥 | — |
| 可观测性与追踪 | ✅ OpenTelemetry、Langfuse | — |
| 法律授权与问责 | ❌ 未涵盖 | ✅ AMR |
《欧盟 AI 法案》第 26 条(Regulation (EU) 2024/1689)要求高风险 AI 系统的部署者指定人工监督,并在其控制范围内,至少将系统生成的日志保存六个月(第 26(6) 条)。该要求自 2027 年 12 月 2 日起适用于附件 III 所列系统,自 2028 年 8 月 2 日起适用于附件 I 所列系统(Regulation (EU) 2026/1744)。违反第 26 条,最高可处以 1,500 万欧元或全球年营业额的 3% 的罚款,以较高者为准(第 99(4) 条;对中小企业和初创企业,以较低者为准,见第 99(6) 条)。AMR 以防篡改的形式记录由谁授权了某个 Agent、授权内容及期限,以及该 Agent 执行了什么操作,供监督工作依赖;它与系统自身的日志互为补充,并不取代这些日志。
结构性硬性拦截
AMR 不只是记录授权,还会强制执行授权。Agent 运行时在执行任何操作前,都必须先从 AMR 获取签名的操作令牌。只有当有效、未过期且未撤销的授权明确允许该 Agent 执行特定操作时,才会签发令牌。没有授权 → 没有令牌 → 无法执行操作。
令牌采用 JWS(RFC 7515),使用 Ed25519(EdDSA)签名;通过 jti 声明和 issued_tokens 审计表防止重放,并包含其授权的确切操作哈希和范围摘要。使用方可通过 AMR 公钥离线验证,并且必须检查 aud、exp 和 amr_action_hash。
边界执行与委托控制
授权可以包含一个结构化边界:Agent 可请求的操作类型(allowed_actions)、绝不可请求的操作类型(forbidden_actions,其优先级始终最高,并且也适用于子类型:禁止 agent.create 即禁止 agent.create.batch)、是否允许委托(delegation_allowed),以及可选的金额上限(带有 currency 的 max_amount,适用于 amount_actions)。随后,令牌签发方会根据边界检查请求的操作,而不只是确认授权是否存在:
- 不在
allowed_actions范围内,或与forbidden_actions匹配的操作类型,不会获得令牌(reason: "action_out_of_scope",并附带detail,以及在refused_by中注明拒绝该操作的授权令); - 仅当父授权令处于有效状态、允许委派,且授予了现在正在委派的 Agent 时,才会创建子授权令(
parent_mandate_id);子授权令必须限制在父授权令允许的操作范围和限额内,继承父授权令的禁止项,且有效期不得超过父授权令; - 根据子授权令签发的每个令牌都会重新检查整个授权链:撤销(
revoke_mandate)父授权令或让其过期后,其下的所有子授权令都将无法再获取令牌; - 可选的累计上限(滚动窗口内
period_days天的period_max_amount,且currency和amount_actions相同)会限制窗口内根据该授权令及其下所有子授权令签发的令牌金额总和:对于带有金额的操作(由amount_actions指定的操作、该列表为空时的所有操作,以及任何声明了amount的操作),Agent 不能把大额购买拆成多笔小额购买,也不能通过子 Agent 再次花掉同一笔预算(detail: "period_amount_above_limit:<max> <CUR>/<days>d",并在refused_by中注明预算已用尽的授权令)。令牌一经签发即计入,无论是否使用;被拒绝的令牌不计入。子授权令的自身上限不得超过父授权令的上限。父授权令的上限不会复制到子授权令的适用范围中(但在签发时,同样会约束子授权令):如需查看所有适用的上限,请像get_proof和证明声明一样,检查完整的授权链。若父授权令设置了单项操作上限,子授权令设置的上限会约束双方amount_actions的并集(任一方的列表为空即表示所有操作); - 可选的风险类别(
risk_classes)会根据所涉风险限制令牌的可用时长:每个类别指定操作类型(包括其子类型,如forbidden_actions中的类型)以及 1 到 86400 之间的max_token_seconds,例如{"name": "irreversible", "actions": ["invoice.pay"], "max_token_seconds": 30}。匹配某个类别的操作所对应的令牌,最多在该时长内有效;在当前授权令及委派链中的每个上级授权令中,均以最短的类别时长为准,因此子授权令可以缩短时长,但不能延长:子授权令会继承父授权令的类别(显示在自身适用范围内),且仅当max_token_seconds更短或相等时,才可以复用类别名称(否则为limit_exceeds_parent)。匹配的类别名称会以amr_risk_classes的形式写入令牌。类别不会延长令牌的有效期,使其超过AMR_TOKEN_LIFETIME_SECONDS。没有类别的授权令会保留原样的哈希值和令牌。类别还可以设置"registry_check": true:此时,其令牌会携带amr_registry_check: true,接收方会在执行操作时通过check_action_token重新检查令牌,从而发现期间发生的撤销。子授权令会继承此标志,且不能将其移除。没有此标志的类别会保留原有形式和哈希值。
示例:助手 Agent 被告知绝不创建子 Agent。
create_mandate(..., allowed_actions=["report.*"], forbidden_actions=["agent.create"])
issue_action_token(..., action_type="agent.create")
→ {"denied": true, "reason": "action_out_of_scope", "detail": "forbidden:agent.create"}
没有边界的根授权仍按原来的方式运作(自由文本范围,仅检查存在性和有效性,哈希值不变)。没有累计上限的边界仍保持其精确的规范形式,因此其哈希值、边界摘要和主体签名均不变;schema v7 仅新增了 token_amounts 表。
累计上限的限制:schema v7 之前签发的令牌没有记录金额,因此不会计入(旧版 AMR 无法在设有上限的分支上签发令牌:它会拒绝未知的边界字段);该上限约束的是一份授权及其分支,而不是同一主体的所有授权。对子授权有两项有意为之且会造成不兼容的变更:新建子授权时,父级授权必须允许委派(因此自由文本父级授权不再能委派);任何子授权下的令牌,包括 v1.1 之前创建的令牌,现在都要求所有父级授权处于有效状态且未过期。
部署规则。 只有在 Agent 无法注册自己的授权时,这些控制措施才有效。
create_mandate和register_principal_key是主体侧工具:应向主体(或其后台)开放,绝不能向其管辖的 Agent 开放。能够调用create_mandate的 Agent 可以为任意主体自行铸造新的根授权,无需密钥;能够调用register_principal_key的 Agent 则可以冒充尚未注册密钥的主体。一旦每个主体都注册了自己的密钥,主体签名(见下文)便可堵住第一个漏洞;将密钥绑定到经过验证的身份已列入路线图。
主体签名:主体对授权进行签名
主体可以注册自己的 Ed25519 公钥,且只能注册一次(register_principal_key)。
此后,注册表只会接受由该主体签名的授权:prepare_mandate_signature 会返回待签名的确切字节,而 create_mandate 接受 principal_signature 和 signed_at。该签名会封装在授权的 chain_hash 中,在同一注册表内不能重复使用,并会与公钥和已签名的字节一起保存在 Proof Pack 中,任何人都可以离线重新验证。设置 AMR_REQUIRE_PRINCIPAL_SIGNATURE=true,即可拒绝所有未签名的授权。
有效签名所能证明的内容:该授权是使用最先为该 principal_id 注册的密钥签署的。对于普通的 principal_id,注册表不会检查谁注册了密钥(以首次注册为准),因此应在接入时通过主体自己的渠道注册其密钥。组织也可以使用 did:web:<its domain> 标识符:只有当该域名在 https://<domain>/.well-known/did.json 发布密钥时,密钥才会被接受;该文档的 SHA-256 摘要会与密钥一起封装(需选择启用网络访问,AMR_DID_WEB_RESOLVE=1)。这只能证明注册时对该域名的控制权,不能证明签名具备合格的资质。依赖 did:web 主体的使用方必须检查 Proof Pack、attestation 或 insurer dossier 中的 did_web_unverified: false。
行为变更(did:web 密钥): 在默认配置下,现在会拒绝为 did:web: 标识符注册密钥(did_web_resolution_disabled),而不再采用“以首次注册为准”;已注册的密钥仍然有效,并会标记为 did_web_unverified。使用非 ASCII 相似字符书写的 scheme:method: 前缀会被拒绝(principal_id_lookalike)。没有密钥的主体,其授权行为与之前相同(哈希值不变;结果中会新增 "principal_signature": null);在注册密钥之前创建的授权仍然有效。另请参阅 docs/principal-signature-spec.md,其中包括已知限制。
完整规范请参阅 docs/token-issuance-spec.md。
行业模板
模板是为某类 Agent 准备好的、带版本号的权限边界,并附有目录,用通俗的语言说明每种操作类型的含义。首个模板
agent-sante-rgpd 面向医疗机构中的助手 Agent:它可以读取病历、处理日程安排、起草信件和患者消息供人工发送,
并在限额内订购用品;但绝不能开处方、诊断、修改或导出病历、主动联系患者,或创建子 Agent。
from amr.templates import get_template
template = get_template("agent-sante-rgpd")
await create_mandate(..., **template.create_mandate_kwargs())
授权书会在其元数据中记录 template_id、template_version 和 template_digest。这些元数据是标签,不会封入链哈希;权限边界才会封入,并由令牌签发方强制执行。模板只会填入现有的 create_mandate 参数:现有授权书及其哈希不会改变。目前模板仅提供 Python API(尚无 MCP 工具可列出模板)。和所有权限边界一样,只有在 Agent 无法自行调用 create_mandate 时,模板才有效(见上文的部署规则)。请参阅 docs/templates/agent-sante-rgpd.md。
如果某个机构(委员会、董事会)授权了该 Agent,授权书可以记录其决定(organ_decision:机构、标题、日期、可选参考信息、指定人员或角色);医疗模板接受此信息,create_mandate 会将其封入链哈希(仅限允许操作为封闭列表的根授权书),而 verify_mandate 和 get_proof 会返回该信息。不包含此信息的授权书,其哈希保持完全不变。
第三方验证:接收方仅凭授权书即可核验
Agent 可以向接收方(卖方、医院、保险公司)出示一份签名的授权书证明(issue_mandate_attestation)。接收方只需使用从注册表获取一次的公钥(get_registry_public_key),即可离线独立核验:无需账户,也无需调用注册表。证明声明授权书确实存在、授权方是谁(以及委托人是否签署;如果设置了 include_principal_payload,接收方可自行重新核验该签名)、Agent、范围和结构化权限边界、到期时间,以及签发证明时该授权书及其所有上级授权书均处于有效状态。
python -m amr.verify_attestation attestation.jws --public-key registry.pub --audience seller:acme
# registry.pub: the PEM (or the JSON) returned by get_registry_public_key
# {"valid": true, "reason": "ok", "attestation": {"principal_id": "...", "perimeter": {...}, ...}}
该证明无法证明的是:授权书目前仍然有效。证明的有效期最长为 AMR_ATTESTATION_LIFETIME_SECONDS(默认 15 分钟),且绝不会超过授权书或其上级授权书的有效期;签发后发生的撤销,只有在证明过期后才会对离线接收方生效。证明是一份持有者凭证:接收方必须确认其交互对象是 agent_id 中指定的 Agent。传入 audience 可将证明指定给某一接收方。除非设置了 include_principal_payload(该信息会包含在签名字节中),否则不会披露授权书的 metadata。注册表信任自身的数据库:请妥善保护该文件。现有授权书及其哈希不会改变;签发记录会写入新的只追加表 issued_attestations(架构 v5)。请参阅 docs/mandate-attestation-spec.md。
公共注册表:无需账户即可在线验证
AMR 通过 stdio 在每位运营者的本地运行,因此其他人无法查询它。公共注册表是独立的只读验证点:运营者导出注册表的签名快照,然后由一个小型 WSGI 应用(仅使用标准库)提供服务。接收方无需账户,即可在浏览器中(HTML)或通过脚本(JSON)查询授权标识符,或粘贴证明。
python -m amr.public_registry export --out amr_public_registry.jws # read-only, signed EdDSA
python -m amr.public_registry serve --export amr_public_registry.jws --public-key registry.pub
curl http://127.0.0.1:8080/mandates/<mandate-id>
# {"status": "active" | "revoked" | "expired" | "cut_by_parent" | ..., "verification_ms": 0.2, ...}
快照按每项授权保存 Agent、主体的 SHA-256 引用(绝不保存明文标识符)、权限范围、日期、记录状态、撤销日期和链哈希;绝不保存权限范围文本、法律依据、元数据或撤销原因。应用在提供快照前,会使用固定的注册表密钥验证快照(并在 /snapshot 提供原始快照,供接收方自行验证;是否信任 JSON 答案,取决于是否信任应用的运行者)。
应用没有写入路径、不保留日志,也从不读取客户端地址。每条结果都会给出快照日期和验证所用时间。限制:快照生成后发生的撤销,只有在下次导出时才会显示;设置 AMR_PUBLIC_SNAPSHOT_MAX_AGE_SECONDS,可拒绝基于较旧快照给出的答案。部署和域名由运营者负责。现有授权及其哈希均保持不变;无需更改架构。请参阅 docs/public-registry-spec.md。
愿景:从注册表到强制执行
AMR 最初是一个授权注册表——用于存储、验证和审计授权。这是必要的,但还不够。
问题在于:如果授权检查只是自愿调用,Agent 就会跳过它。系统在投入实际使用后的几周内,就会退化为仅提供建议的合规机制。
AMR 现在提供结构性强制执行:它是发放执行授权(issue_action_token)的层。没有有效授权 → 没有授权 → 无法执行操作。系统拒绝在没有授权的情况下工作——不是因为有人建议进行检查,而是因为架构使绕过检查成为不可能。
| 层级 | 功能 | 状态 |
|---|---|---|
| 注册表 | 存储、验证、审计授权。SHA-256 链。原生支持 MCP。 | ✅ 已上线 |
| 强制执行 | 以授权为前提的执行授权(issue_action_token、check_action_token)。没有授权 = 无法执行操作。 | ✅ 已上线 |
| 生态系统 | AMR 在操作发生前发放授权。认证代理可证明操作期间发生了什么。 | 目前兼容 |
开源注册表仍然免费。强制执行层是商业产品。
快速开始
git clone https://github.com/JC7333/amr.git
cd amr
uv sync
uv run amr
Claude Desktop 集成
将 AMR 添加到 Claude Desktop 配置文件中:
位置: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"amr": {
"command": "uv",
"args": ["--directory", "C:\\dev\\amr", "run", "amr"]
}
}
}
重启 Claude Desktop。所有 AMR 工具将立即可用。
工具
create_mandate
注册一项新的法律授权,允许 AI Agent 代表主体行事。
参数:
| 参数 | 类型 | 描述 |
|---|---|---|
principal_id | str | 授予委托的主体。例如,"user:audric" |
agent_id | str | 接受授权的 Agent。例如,"agent:korvex-advisor-v1" |
scope | str | Agent 获准执行的操作 |
legal_basis_regulation | str | 法规或合同。例如,"EU AI Act Art.26" |
legal_basis_article | str | 具体条款。例如,"Art.26(1)(a)" |
duration_hours | float | 时长(小时,最长 8760 小时,即 1 年) |
legal_basis_jurisdiction | str | 司法管辖区代码(默认为 "EU") |
parent_mandate_id | str | null | 委托链中父委托的 UUID(父委托必须允许转授权) |
metadata | dict | 可选的字符串键值对,用于添加注释 |
allowed_actions | list[str] | null | Agent 可请求的操作类型:"invoice.pay"、"invoice.*" 或 "*" |
forbidden_actions | list[str] | null | 永不允许的操作类型(优先于 allowed_actions)。例如,["agent.create"] |
delegation_allowed | bool | Agent 是否可以授予子委托(默认为 false) |
max_delegation_depth | int | null | 在 delegation_allowed 启用时,允许存在的子委托层数,范围为 1 到 16(1 = Agent 可以转授权,但其子 Agent 不可以)。超出层数的子委托将被拒绝,并返回 delegation_depth_exceeded;系统会检查每个祖先委托的限制。未设置时,此委托不施加层数限制。仅在设置时才会加入封存范围,因此现有委托的哈希保持不变。该限制会与委托一同封存,并在其下创建子委托时检查(子委托声明的层数不能超过其祖先允许的剩余层数);签发令牌时不会重新检查,且仅约束声明了父委托的链:阻止 Agent 单独开启根委托的机制是主体签名。包含此键的封存范围无法由较旧版本的 AMR 读取。 |
max_amount | str | null | 每项操作的金额上限,以十进制字符串表示。例如,"500" |
currency | str | max_amount 的 ISO 4217 代码(默认为 "EUR") |
amount_actions | list[str] | null | 必须在金额上限内携带 amount 的操作(为空表示全部操作) |
period_max_amount | str | null | period_days 时间段内,此委托及其所有子委托的累计金额上限,以十进制字符串表示。例如,"2000" |
period_days | int | null | period_max_amount 的滚动时间窗口,范围为 1 到 366 天(使用 period_max_amount 时必填)。例如,30 |
risk_classes | list[dict] | null | 类别 {name, actions, max_token_seconds, registry_check?},用于限制这些类别所覆盖操作在此委托及其所有子委托中的令牌有效期;registry_check: true 表示要求接收方通过 check_action_token 重新检查。例如,[{"name": "irreversible", "actions": ["invoice.pay"], "max_token_seconds": 30, "registry_check": true}] |
principal_signature | str | null | 主体对 prepare_mandate_signature 载荷的 base64url Ed25519 签名(主体注册密钥后必填) |
signed_at | str | null | ISO 8601 时间戳,包含在签名载荷中(时间与注册表时钟相差不得超过 15 分钟) |
返回值:
{
"status": "created",
"mandate_id": "550e8400-e29b-41d4-a716-446655440000",
"principal_id": "user:audric",
"agent_id": "agent:korvex-advisor-v1",
"scope": "Compare and recommend financial products to retail clients",
"perimeter": null,
"parent_mandate_id": null,
"principal_signature": null,
"expires_at": "2026-05-13T20:00:00+00:00",
"chain_hash": "a3f5c2d1e8b9..."
}
perimeter 在提供结构化封存范围时保存该范围(并将其封存到
chain_hash 中)。封存范围和转授权错误会返回 {"error": "...", "code": "..."}
,且错误代码稳定:perimeter_invalid、parent_mandate_not_found、
parent_mandate_<status>、parent_mandate_expired、delegation_not_allowed、
delegator_mismatch、sub_mandate_requires_perimeter、perimeter_exceeds_parent、
limit_exceeds_parent、expires_after_parent。父委托上方的链路损坏时会返回
parent_mandate_<status>、parent_mandate_expired 或
delegation_chain_too_deep(超过 16 层)。
签名委托中的 principal_signature 为 {"key_id", "signed_at"}。签名错误:principal_signature_required、principal_signature_incomplete、
principal_key_not_registered、signed_at_invalid、principal_signature_stale、
principal_signature_invalid、principal_signature_replayed。
register_principal_key
通过所有权证明注册主体的 Ed25519 公钥,每个主体仅可注册一次。
| 参数 | 类型 | 描述 |
|---|---|---|
principal_id | str | 主体。例如 "user:audric" |
public_key | str | 原始的 32 字节公钥,采用 base64url 编码 |
proof_signature | str | 对 {"context":"amr.principal_key.v1","principal_id":...,"public_key":...}(规范 JSON)的签名 |
返回 {"status": "registered", "principal_id", "key_id", "registered_at", "chain_hash", "domain_proof"}。除 did:web:<domain> 主体外,domain_proof 为 null:此类主体的密钥只有在
https://<domain>/.well-known/did.json 列出该密钥时才会被接受(需要
AMR_DID_WEB_RESOLVE=1),且 domain_proof 包含 did_document_url、
did_document_sha256 和 verified_at。参见 docs/principal-signature-spec.md,
第 1 bis 节。
prepare_mandate_signature
参数与 create_mandate 相同(另加可选的 signed_at,默认为当前时间)。不写入任何内容;返回
{"payload", "payload_b64url", "signed_at"}:主体在调用 create_mandate 之前签署的确切字节内容。
prepare_mandate_pdf
参数与 prepare_mandate_signature 相同。不写入任何内容;返回委托 PDF,供主体阅读并使用自己的签名工具
(例如 PAdES 签名)签署:{"pdf_base64", "filename", "pdf_sha256", "attachment_name", "payload_sha256", "payload", "payload_b64url", "signed_at"}。PDF 将 prepare_mandate_signature 的确切
负载作为附件 amr-mandate.json,并在每一页印上其 SHA-256。相同的参数和 signed_at 始终会生成相同的 PDF。
注册表不会对此 PDF 签名,并且在此版本中不会检查在其上完成的签名:委托仍须通过主体对相同负载的
Ed25519 签名来接受,且 signed_at 与注册表时钟的时间差必须在
AMR_PRINCIPAL_SIGNATURE_MAX_AGE_SECONDS(默认为 900 秒)以内;须在此时间窗口内生成、签名并注册
(参见 docs/principal-signature-spec.md,第 2 bis 节)。
verify_mandate
检查 AI agent 是否拥有当前有效且未过期的委托(对于子委托,其上级的每一项委托也必须有效且未过期)。
此操作不会根据权限范围检查操作:该检查由 issue_action_token 执行。
参数:
| 参数 | 类型 | 描述 |
|---|---|---|
agent_id | str | 要检查的 Agent。例如 "agent:korvex-advisor-v1" |
action | str | Agent 希望执行的操作 |
context | str | 用于审计日志的可选上下文 |
返回:
{
"authorized": true,
"mandate_id": "550e8400-e29b-41d4-a716-446655440000",
"reason": "Active mandate found",
"scope": "Compare and recommend financial products to retail clients",
"perimeter": null,
"parent_mandate_id": null,
"expires_at": "2026-05-13T20:00:00+00:00"
}
log_action
在有效委托下记录 Agent 操作。与之前的操作进行加密链式关联。
参数:
| 参数 | 类型 | 描述 |
|---|---|---|
mandate_id | str | 执行该操作所依据委托的 UUID |
action | str | 对所执行操作的描述 |
evidence | str | 可选的引用或证据。例如 "email:msg_abc123" |
result | str | 可选的结果。例如 "Delivered" |
返回:
{
"status": "logged",
"action_id": "7f3e9b2a-...",
"mandate_id": "550e8400-...",
"action": "Generated investment recommendation for Product X",
"chain_hash": "c8d7e6f5..."
}
委托必须处于有效状态,未撤销且未过期。对于子委托,其上级的每一项委托也必须满足这些条件:撤销或任由父级委托过期,都会导致其整个分支停止记录日志。拒绝响应会说明原因以及链条中断的委托:
{"error": "...", "reason": "parent_mandate_revoked", "refused_by": "<parent id>"}
(也可能是 parent_mandate_expired、parent_mandate_<status>、parent_mandate_not_found、
delegation_chain_too_deep)。
revoke_mandate
委托人的停止按钮。记录委托人的撤销理由,并最终撤销一项委托。仅追加:在 mandate_revocations 中添加一条链式记录,并添加一条 revoked 委托事件;不修改委托行,其哈希也不会改变。
参数:
| 参数 | 类型 | 说明 |
|---|---|---|
mandate_id | str | 要撤销的委托的 UUID |
reason | str | 撤销理由,将按原样记录(1 到 500 个字符) |
principal_signature | str | null | 撤销负载的 Ed25519 签名(委托人已注册密钥时必填) |
signed_at | str | null | 负载中使用的 signed_at |
只有该委托自己的委托人可以撤销它(对于子委托,即授予该委托的 Agent)。签名策略与 create_mandate 相同;使用 prepare_revocation_signature(mandate_id, reason, signed_at=None) 构建要签名的确切字节。
返回后立即生效: issue_action_token 和 issue_mandate_attestation 会拒绝该委托(mandate_status_revoked)及其下的所有子委托(parent_mandate_revoked);
verify_mandate 不再返回该委托;无法在其下创建子委托;
log_action 会拒绝该委托及其下的所有子委托;get_proof 和 export_insurer_dossier 会报告该委托。已签发的令牌无法撤回,并会一直有效到其 exp;响应会给出令牌数量和最晚过期时间,除非接收方在执行操作时重新使用 check_action_token 检查令牌(见下文)。对于离线检查委托证明的接收方,已签发的委托证明也会一直有效到其 exp(默认 15 分钟);响应也会给出该委托及其子委托的证明数量和最晚过期时间。
返回:
{
"status": "revoked",
"mandate_id": "550e8400-e29b-41d4-a716-446655440000",
"principal_id": "org:clinic",
"reason": "agent exceeded its order limit",
"revoked_at": "2026-10-23T20:30:01.123456+00:00",
"principal_signature": null,
"chain_hash": "a3f1...",
"outstanding_tokens": {"still_valid": 1, "last_expires_at": "2026-10-23T20:34:12+00:00"},
"outstanding_attestations": {"still_valid": 0, "last_expires_at": null}
}
令牌的有效期最长为 AMR_TOKEN_LIFETIME_SECONDS(默认 300 s),且不得超过其委托、委托链上任一上级委托的过期时间,也不得超过委托链中适用于该操作类型的最短风险等级(risk_classes)所允许的期限。调用方的 lifetime_override_seconds 只能缩短有效期。对于要求令牌有效期长于默认值的调用方,这是一个破坏性变更:现在它们会获得默认有效期。撤销后,已签发令牌仍可使用的时间窗口最长不超过该有效期,与委托链的深度无关。参见 docs/revocation-spec.md。
contest_action
Agent 已经采取了行动,而委托人对该行动提出异议。撤销授权可以阻止后续行动;contest_action 用于记录某项过去已通过 log_action 记录的行动受到异议,以及提出异议的时间、原因和人员。此操作仅追加:在 action_contests 中添加一条链式记录(每项行动一条;不可撤回或编辑),并添加一个 action_contested 授权事件。行动日志、授权以及所有已记录的哈希值均保持不变。
参数:
| 参数 | 类型 | 说明 |
|---|---|---|
mandate_id | str | 记录该行动所用授权的 UUID |
action_id | str | log_action 返回的 action_id |
reason | str | 提出异议的原因(1 至 500 个字符) |
response_days | int | 距离 respond_by 的天数(1 至 365),由操作者选择 |
contested_by | str | null | 提出异议的委托人;默认值:该授权的委托人 |
principal_signature | str | null | 异议载荷的 Ed25519 签名(若提出异议的委托人已注册密钥,则必填) |
signed_at | str | null | 载荷中设置的 signed_at |
contested_by 可以是该授权的委托人,也可以是其委托链上任一上级授权的委托人(例如,组织对下属 Agent 的行为提出异议),无论这些授权处于何种状态。签名规则与 create_mandate 和 revoke_mandate 相同;使用 prepare_contest_signature 构造字节(参数相同,另加 signed_at=None)。
respond_by = contested_at + response_days 是操作者自行设定的期限,例如,法律顾问建议在保留或使用所要求的内容前等待一段时间,逾期可能被视为接受该要求。**AMR 不计算任何法律期限,也不对其作出任何断言。**提出异议不会撤销该行动,也不会撤销授权;如需撤销授权,请调用 revoke_mandate。
返回:
{
"status": "contested",
"mandate_id": "550e8400-e29b-41d4-a716-446655440000",
"action_id": "0b6f7c1e-3d0a-4c55-9a43-5d1f1f0e2a10",
"action_chain_hash": "9c2e...",
"contested_by": "org:clinic",
"reason": "order placed above the agreed quantity",
"response_days": 14,
"contested_at": "2026-11-01T21:30:00+00:00",
"reminder": {"respond_by": "2026-11-15T21:30:00+00:00", "days_left": 14, "deadline_passed": false},
"principal_signature": null,
"chain_hash": "5be0..."
}
错误(code):invalid_input、mandate_not_found、action_not_found(行动属于其他授权时也会返回此错误)、contester_not_in_chain、action_already_contested,以及 revoke_mandate 的委托人签名错误代码。
提醒:list_action_contests(mandate_id=None, contested_by=None, due_within_days=None)(只读;提供 mandate_id、contested_by 或两者)会返回异议记录,按 respond_by 从最近到最远排序;每条记录都包含 reminder.days_left(逾期后为负数)和 reminder.deadline_passed。请按计划定期调用,例如每天早晨调用一次并设置 due_within_days=3。get_proof 会在授权的 action_contests 中列出异议记录,并在 chain_integrity.contests_intact 中重新校验这些记录。请参阅 docs/action-contest-spec.md。
check_action_token
供 Agent 操作的接收方使用:在执行不可逆步骤之前,操作当下向注册表重新检查令牌。当令牌携带
amr_registry_check: true 时(即带有 registry_check 的风险类别),必须进行检查;任何令牌都可以检查。
只读。
| 参数 | 类型 | 描述 |
|---|---|---|
token | str | issue_action_token 返回的 JWS |
audience | str | 你是谁;必须与令牌的 aud 相等 |
expected_action_hash | str | null | 即将执行的规范操作的 SHA-256;必须与 amr_action_hash 相等 |
max_token_age_seconds | int | null | 你自己设定的、更严格的时限(1 到 86400):拒绝签发时间早于该时限的令牌。绝不会延长 exp |
它会验证签名(仅限 EdDSA,且须使用此注册表的密钥)、iss、aud、exp、nbf,
确认该令牌由注册表签发,然后检查授权及其上层的每一项授权是否仍然有效、未撤销且未过期。
{"valid": true, "reason": "ok", "jti": "...", "mandate_id": "...", "agent_id": "agent:billing",
"action_type": "invoice.pay", "registry_check_required": true,
"expires_at": "2026-10-29T21:30:30+00:00", "checked_at": "2026-10-29T21:30:12.400000+00:00"}
{"valid": false, "reason": "mandate_status_revoked", "jti": "...", "mandate_id": "...",
"checked_at": "2026-10-29T21:30:14.100000+00:00"}
注册表以只读方式打开数据库,检查时不会写入任何内容,且返回的结果未签名:它不能作为任何人执行过检查的证据。请通过你自己的渠道联系注册表;切勿接受由其令牌所属 Agent 转发的检查结果。一旦存在带有 registry_check 的授权,较旧版本的 AMR 就无法读取其管辖范围(会默认拒绝)。参见 docs/token-issuance-spec.md 中的执行时注册表检查部分。
get_proof
生成完整的 Proof Pack —— 包含某项授权的所有操作及加密链验证的完整审计包。
参数:
| 参数 | 类型 | 描述 |
|---|---|---|
mandate_id | str | 要证明的授权的 UUID |
format | str | 输出格式(当前为 "json") |
返回:
{
"proof_pack_version": "0.1.0",
"generated_at": "2026-04-13T18:00:00+00:00",
"mandate": { "...": "full mandate details" },
"delegation_chain": {"broken": false, "reason": null, "refused_by": null},
"actions": [ "...list of all logged actions..." ],
"events": [],
"action_contests": [],
"chain_integrity": {
"actions_chain_valid": true,
"principal_signature_valid": null,
"revocation_signature_valid": null,
"contests_intact": true,
"total_actions": 5,
"total_events": 0
},
"compliance_notes": {
"ai_act_art26": "This Proof Pack documents the mandate chain for AI Act Art.26 compliance.",
"retention": "Logs must be retained for minimum 6 months per AI Act Art.26(6)."
}
}
mandate.principal_signature 保存委托方的签名、公钥、公钥持有证明以及已签名字节(或 null);principal_signature_valid
会根据存储的授权重新验证这些内容。如果签名不匹配,或创建授权时委托方已有密钥但签名缺失,则为 false;如果当时委托方没有密钥,则为 null。
运行 revoke_mandate 后,mandate.status 显示为 "revoked"(存储的值保留在 mandate.stored_status 中),而 mandate.revocation 保存 revoked_at、reason、撤销的委托方签名(或 null)及其链哈希;revocation_signature_valid 会根据委托方的密钥重新验证该签名(没有可检查内容时为 null)。
delegation_chain 表示子授权上方的链是否仍然有效:
当其上方的授权被撤销、已过期、未激活或缺失时,值为 {"broken": true, "reason": "parent_mandate_revoked", "refused_by": "<parent id>"}(子授权自身的 mandate.status 不会改变:断链发生在其上方);
否则为 {"broken": false, "reason": null, "refused_by": null},根授权始终如此。
issue_mandate_attestation
| 参数 | 类型 | 描述 |
|---|---|---|
mandate_id | str | 要出具证明的授权的 UUID |
agent_id | str | 必须与授权的 Agent 相匹配 |
audience | str | null | 可选的目标接收方 |
lifetime_seconds | int | null | 可选的较短有效期(绝不会超过配置的最大值) |
include_principal_payload | bool | 同时携带委托方的签名和已签名字节(会披露 metadata);默认为 false |
返回 {"attestation", "jti", "issued_at", "expires_at", "key_id", "issuer"},或
{"denied": true, "reason", "mandate_id"},例如 mandate_not_found、
agent_mismatch、mandate_status_<status>、mandate_status_revoked、mandate_expired、
parent_mandate_<status>、parent_mandate_revoked、principal_signature_invalid;由父级授权导致拒绝时,还会包含 refused_by(完整列表见 docs/mandate-attestation-spec.md)。
get_registry_public_key
无参数。返回 {"issuer", "key_id", "algorithm": "EdDSA", "public_key_pem", "public_key_jwk"}:接收方离线验证证明所需的信息。
export_insurer_dossier
导出某个委托在一段时间内的签名档案:保险公司或审计员就 AI Agent 提出要求时所需的材料。只读;内容仅取自注册表。
参数:
| 参数 | 类型 | 说明 |
|---|---|---|
mandate_id | str | 委托的 UUID |
period_start | str | null | ISO 8601 日期时间起始值(无时区 = UTC;不接受单独的日期);默认值为委托的创建时间 |
period_end | str | null | ISO 8601 日期时间结束值(无时区 = UTC;不接受单独的日期);默认值为当前时间 |
format | str | "json"(默认值)或 "html",以同时获取可打印页面 |
**档案内容包括:**委托(委托人、Agent、范围、声明的法律依据、日期);其权限范围(允许和禁止的操作类型、委派权、金额限制);生成时委托是否有效,以及无效的原因(mandate_revoked、mandate_expired,或上级链断裂,例如 parent_mandate_revoked);其子委托,每项包含深度、权限范围、有效状态,以及该时间段内记录的操作数量(被撤销的委托会使其整个分支失效);该委托自身的 Agent 在该时间段内记录的操作;该时间段内此委托及其子委托的状态事件和操作令牌;完整性检查(操作日志链、委托人签名、最后一个链哈希);以及档案限制的固定列表(例如:被拒绝的令牌请求不会被记录,因此档案列出的是已发放的令牌,而不是被拦截的操作)。
返回值:
{
"dossier": { "dossier_version": "1.0", "period": {}, "mandate": {}, "status": {},
"integrity": {}, "sub_mandates": [], "events": [], "actions": [],
"tokens": [], "limits": [] },
"dossier_sha256": "hex SHA-256 of the canonical dossier",
"signature": { "jws": "...", "algorithm": "EdDSA", "key_id": "...",
"public_key_pem": "..." },
"html": "only when format is \"html\""
}
签名采用 JWS(RFC 7515、EdDSA / Ed25519,与操作令牌使用相同的注册表密钥),载荷为档案的规范化 JSON。离线验证方法:
from amr.proof.insurer_dossier import verify_dossier
dossier = verify_dossier(jws, registry_public_key_pem) # raises if anything is off
导出过程绝不会创建签名密钥:如果注册表没有密钥,则会返回错误。请通过带外方式获取注册表公钥:导出结果中的 public_key_pem 仅为方便提供,档案若携带自己的密钥,并不能证明签名者的身份。HTML 页面是可独立使用的打印视图(无外部资源;可在浏览器中打印为 PDF),会显示档案的 SHA-256 和密钥 ID;只有 JSON 签名才是证明。请参阅 docs/insurer-dossier-spec.md。
工作原理
┌─────────────────────────────────────────────────────────────────────┐
│ PRINCIPAL │
│ (user:audric, org:acme-corp) │
└──────────────────────────┬──────────────────────────────────────────┘
│ create_mandate()
▼
┌─────────────────────────────────────────────────────────────────────┐
│ MANDATE (SHA-256 chained) │
│ id · principal · agent · scope · legal_basis · expires_at │
│ chain_hash = SHA256(mandate_data + prev_hash) │
└──────────────────────────┬──────────────────────────────────────────┘
│ verify_mandate() → authorized: true
▼
┌─────────────────────────────────────────────────────────────────────┐
│ AGENT │
│ (agent:korvex-advisor-v1) │
└──────────────────────────┬──────────────────────────────────────────┘
│ log_action() × N
▼
┌─────────────────────────────────────────────────────────────────────┐
│ ACTION LOG (append-only, SHA-256 chained) │
│ action_1 ──hash──▶ action_2 ──hash──▶ action_3 ──hash──▶ ... │
│ Each action links to the previous via chain_hash │
└──────────────────────────┬──────────────────────────────────────────┘
│ get_proof()
▼
┌─────────────────────────────────────────────────────────────────────┐
│ PROOF PACK (JSON) │
│ mandate + actions + chain_integrity + compliance_notes │
│ Ready for regulatory audit, eIDAS submission, or archival │
└─────────────────────────────────────────────────────────────────────┘
安全性
-
Pydantic v2 验证 — 所有工具输入都会在任何数据库交互前进行验证。拒绝未知字段(
extra="forbid")。在模型层强制执行时长、字符串长度和 UUID 格式要求。 -
仅使用参数化 SQL — 每个数据库查询都使用
?占位符。SQL 中不使用字符串插值或 f-string。每次提交都会由ruff的 S608 规则强制检查。 -
仅追加表 —
mandates和action_logs表绝不会执行UPDATE或DELETE。审计记录在设计上不可变。状态变更使用独立的mandate_events表。 -
SHA-256 加密链 — 每个委托和每条操作日志记录都通过 SHA-256 哈希与前一项关联(类似 git)。任何篡改都会使后续所有哈希失效,从而使记录链具备防篡改能力。
-
仅使用 stdio 传输 — AMR 作为本地 MCP 服务通过 stdio 运行。没有监听端口,没有入站网络暴露,工具也不会发出出站 HTTP 请求,只有一个主动启用的例外:
report_issue会向 GitHub API 发送一个 HTTPS 请求,且仅当操作员设置了AMR_ISSUE_TOKEN时才会发送。攻击面极小。
监管背景
| 法规 | 与 AMR 的相关性 |
|---|---|
| EU AI Act 第 26 条 | 高风险 AI 系统的部署者必须按照说明使用这些系统,安排人工监督,并保存系统生成的日志。AMR 会记录每个 Agent 及其操作背后的授权,作为监督证据。自 2027 年 12 月 2 日(附件 III 系统)和 2028 年 8 月 2 日(附件 I 系统)起适用,Regulation (EU) 2026/1744。 |
| EU AI Act 第 26(6) 条 | 高风险系统生成的日志必须至少保存六个月。AMR 的只追加 SQLite 数据库和 Proof Pack 导出功能有助于满足此项要求。 |
| eIDAS 2.0 | 适用于代表自然人或法人行事的 AI Agent 的电子授权。AMR 的授权链与 eIDAS 电子委托信任框架相对应。 |
| 罚款 | 违反第 26 条可能被处以最高 1,500 万欧元或全球年营业额的 3% 的罚款,以较高者为准(第 99(4) 条;对中小企业和初创企业,以较低者为准,见第 99(6) 条)。 |
路线图
| 状态 | 功能 |
|---|---|
| 已发布 | 授权注册表 · SHA-256 链 · Proof Pack JSON · 结构化权限范围 · 子授权和委托链 · 撤销 · 有争议的操作 · 已签名操作令牌(强制执行)和执行时检查 · 离线授权证明 · 已签名保险方档案(JSON 和可打印 HTML) · 主体签名和 did:web 密钥 · 只读公共注册表 · 行业模板(医疗) · MCP SDK v1 和 v2 · PyPI 软件包 mandatia |
| 计划中 | PDF Proof Pack 导出 · MCP 客户端远程传输 · PostgreSQL 后端 · 多租户支持 · 与 MCP 并行提供 REST API · eIDAS 2.0 合格电子签名 · 跨境授权互认 · webhook 通知 · 仪表板和告警 |
开发
# Install all dependencies including dev extras
uv sync --all-extras
# Run the full test suite
uv run pytest -v
# Run with short traceback on failure
uv run pytest -v --tb=short
# Lint and security check (src + tests)
uv run ruff check src/ tests/
# Auto-fix safe issues
uv run ruff check --fix src/ tests/
# Start the MCP server (stdio — normal to wait for input)
uv run amr
项目结构
src/amr/
├── config.py # Settings via pydantic-settings (env prefix: AMR_)
├── server.py # MCP server entrypoint (stdio transport; mcp 1.x or 2.x)
├── models/mandate.py # Pydantic models: MandateCreate, Mandate, ActionLog
├── crypto/chain.py # compute_hash() and verify_chain() — stdlib only
├── db/engine.py # init_db(), get_db(), get_last_mandate_hash()
├── tools/
│ ├── create_mandate.py
│ ├── prepare_mandate_pdf.py # the mandate as a PDF the principal signs itself
│ ├── verify_mandate.py
│ ├── log_action.py
│ ├── get_proof.py
│ ├── check_action_token.py # receiver re-checks a token when it acts
│ ├── issue_mandate_attestation.py # attestation + registry public key
│ ├── revoke_mandate.py
│ ├── contest_action.py # contested acts and their response deadline (reminder)
│ ├── report_issue.py # network call, opt-in (AMR_ISSUE_TOKEN)
│ └── export_insurer_dossier.py
├── attestation.py # offline attestation verifier (no DB, no network)
├── did_web.py # did:web key check, network opt-in (AMR_DID_WEB_RESOLVE)
├── mandate_pdf.py # deterministic mandate PDF, payload attached (stdlib only)
├── verify_attestation.py # python -m amr.verify_attestation
├── proof/insurer_dossier.py # Signed insurer dossier: canonical form, JWS, print view
└── templates/ # Sector mandate templates (agent-sante-rgpd)
tests/
├── conftest.py # Isolated temp DB fixture (autouse)
└── test_*.py # One file per tool or feature (`uv run pytest -q`)
环境变量
| 变量 | 默认值 | 描述 |
|---|---|---|
AMR_DB_PATH | amr_mandates.db | SQLite 数据库文件的路径 |
AMR_LOG_LEVEL | INFO | 日志详细程度 |
AMR_SERVER_NAME | Agent Mandate Registry | MCP 服务的显示名称 |
AMR_REQUIRE_PRINCIPAL_SIGNATURE | false | 拒绝所有未由其主体签名的授权 |
AMR_PRINCIPAL_SIGNATURE_MAX_AGE_SECONDS | 900 | signed_at 与注册表时钟之间允许的最大时间差 |
AMR_ISSUE_TOKEN | 未设置 | 允许 report_issue 自动提交问题的 GitHub 令牌(细粒度,Issues:写入,仅限一个仓库)。只从进程环境读取,绝不从 .env 读取。未设置:不进行网络调用 |
AMR_DID_WEB_RESOLVE | 未设置 | 1 允许 register_principal_key 读取 did:web 主体的 DID 文档(向该域名发起一次 HTTPS GET 请求)。只从进程环境读取,绝不从 .env 读取。未设置:拒绝 did:web 密钥 |
AMR_ISSUE_REPOSITORY | JC7333/amr | report_issue 提交问题的仓库(owner/name) |
AMR_ATTESTATION_LIFETIME_SECONDS | 900 | 授权证明的最长有效期 |
AMR_PUBLIC_EXPORT_PATH | amr_public_registry.jws | 由 python -m amr.public_registry export 写入并由其应用提供服务的已签名快照 |
AMR_PUBLIC_KEY_PATH | amr_signing_key.pub | 注册表公钥;公共注册表应用会固定使用此密钥验证快照 |
AMR_PUBLIC_SNAPSHOT_MAX_AGE_SECONDS | 未设置 | 公共注册表:若快照超过此时限,则返回 snapshot_too_old,而非状态 |
许可证
Apache License 2.0 — 完整条款请参阅 LICENSE。
可免费用于商业产品。符合 EU AI Act 关于开源的规定。
⚠️ 免责声明: AMR 是一种技术基础设施工具,不构成法律建议。遵守 EU AI Act、eIDAS 2.0 或任何其他法规的责任仍由运营方承担。请咨询合格的法律顾问,了解您特定的监管义务。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。