关于 Autopia
Autopia 实测带有 OpenAPI 规范的 HTTP API,并保存可复现、带版本的发现结果,供 AI Agent 和 Claude Code 使用。它重点记录文档与实际行为的差异,包括错误、分页和认证。
主要功能
- 01依据 OpenAPI 规范探测 API
- 02复现并验证每项发现
- 03生成带版本的行为说明
- 04记录规范差异与未注明规则
- 05比较不同 API 版本的发现
适用场景
- 01检查 API 的实际错误行为
- 02定位分页和认证方面的特殊表现
- 03在 Agent 调用前查阅已验证的行为
- 04审查版本之间的行为变化
MCP 相关
Autopia 通过 MCP 服务提供已验证的 API 行为知识库,供 AI Agent 查询。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://autopia-mcp.onrender.com/mcpclaude mcp add --transport http maydaytrey-autopia https://autopia-mcp.onrender.com/mcp{"mcpServers":{"maydaytrey-autopia":{"type":"http","url":"https://autopia-mcp.onrender.com/mcp"}}}在 Cursor 中打开{"servers":{"maydaytrey-autopia":{"type":"http","url":"https://autopia-mcp.onrender.com/mcp"}}}在 VS Code 中打开{"mcpServers":{"maydaytrey-autopia":{"type":"http","url":"https://autopia-mcp.onrender.com/mcp"}}}{"mcpServers":{"maydaytrey-autopia":{"serverUrl":"https://autopia-mcp.onrender.com/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
https://autopia-mcp.onrender.com/mcp需要授权工具
9此工具无需参数。
详细介绍
Autopia
Autopia 会对提供 OpenAPI 规范的 HTTP API 进行实证测试,发现它们实际的行为,通过重现每项发现来验证,并将结果作为带版本控制、可查询的知识库提供给 AI Agent,以便它们通过 MCP 查询;Claude Code 插件则会在 Agent 即将调用这些 API 时,将相关信息注入其上下文。
这是 docs/compendium-spec.txt(蓝图)和 docs/compendium-stack.txt(技术栈选择)中所述“Discrimen Compendium”的 MVP。请先阅读规范中的术语表;代码使用的正是其中的术语。HANDOFF.txt 记录了当前进展和决策。
**线上服务:**托管服务位于 https://autopia-mcp.onrender.com/mcp(使用个人密钥,见身份(个人密钥));数据库是托管在 Neon 上的 Postgres;GitHub Actions 会按计划每晚刷新每个目标(仅运行规则),每周刷新一次(包含模型流程)。目录目前收录了 16 个 API,包括 GitHub REST、npm registry、PyPI、Anthropic 模型端点、Open-Meteo 系列、weather.gov、Binance、Frankfurter、Open Library、PokeAPI 和 Nager.Date。
Agent 能获得什么
每个 API 都有一份行为说明:仅根据已验证的断言生成 Markdown,并按价值排序。最先列出实时 API 与其自身规范相矛盾的情况,然后是规范中从未提及的规则,接着是所有端点共有的行为,最后按端点说明响应形式、错误正文结构、分页、验证和身份验证。每一行末尾都标有支持该内容的试验 ID。以下是这些说明中记录的示例,均已在实时 API 上重现:
- GitHub 会悄悄将提交接口上的
since=not-a-date用作过滤条件,且该条件不会匹配任何结果(返回 200 和空列表);而 Issues 接口会以 422 拒绝同一值,并明确说明格式要求。 - GitHub 允许公共读取请求不带令牌,但会将请求限制在每小时 60 次,而非每小时 5000 次;
per_page会被限制为 100(已通过 Link 标头证实)。 - npm 搜索接口接受
size=2500,尽管文档规定的最大值是 250,而且不会对分数权重参数进行类型检查。 - Anthropic
/v1/models的游标必须指定现有模型 ID;未知 ID 用作游标时会返回 400,用作路径时则会返回 404。
流水线
discover -> exercise -> aggregate -> cross-ref -> verify -> write (+ diff)
spec TRIALS rules + spec + evidence CLAIMS
fetch, (no LLM) shape rules siblings + check + + DIFFS
hash, + one LLM self- reproduce
trim pass consistency
- 试验是由 battery(
src/worker/battery, 版本 1.3.0)生成的固定请求,是一个确定性的边缘情况目录:省略必需参数、类型错误、枚举值超出文档所列范围、null 和空值、数值边界(零、负数、最大整数、低于最小值、略高于最大值和远高于最大值、2048 个字符的字符串)、重复参数、未知字段、错误和缺失的凭据(保留方案)、页码为零、超大页面大小、超出最后一页的页码、日期时间参数的四种日期格式(仅日期、无时区、纪元时间、无效值)、错误的内容类型、尾随斜杠、HEAD。全程没有随机性,因此两次运行会生成完全相同的试验输入。每个存储的响应都会保留截断前数组的长度,因此列表语义不会在存储时丢失。 - 声明来自三个来源:对试验应用的确定性规则(免费)、对成功响应应用的结构规则(内容类型、时间戳格式、值为 null 的字段、分页字段、速率限制和缓存标头),以及一次用于开放式发现的批量 LLM 调用。LLM 输出会根据
src/schemas/claim.schema.json使用 ajv 验证;无效对象会被丢弃。规则判定的是实际返回的内容,而不只是状态:对于无效日期值,若列表为空而对照请求有结果,则 200 会被判定为“作为不可能的筛选条件应用”;若数量相同,则判定为“显然被忽略”;否则判定为“已解释”。只有在能够确证存在更多项目时(存在rel="next"的 Link、总数值字段,或已达到文档规定的最大值),才会提出页面大小上限的声明。错误形态声明只统计发送了错误值的探测,不统计认证、HEAD 或内容类型探测。 - 验证是核心产物:每条声明都引用试验 ID 及各试验显示的状态。证据检查是机械化的;重现时会重新运行完全相同的输入,并比较规范化的响应签名(状态、正文类型、JSON 结构、错误消息),而非原始字节,因此实时数据变化不会导致重现失败。无法重现的声明会被丢弃。存储的声明始终为
verified = true。 - 偏差是与文档记载事实(必需标记、类型、枚举、范围)相矛盾的声明。它是价值所在。规范中的沉默绝不算偏差:API 强制执行但规范从未说明的规则(必须同时发送的参数、隐式默认值)会以独立类型
undocumented_constraint存储。 - 声明类型:
required、type、auth、pagination、error_behavior、response_shape、undocumented_constraint、undocumented、other。 - 同类工具比较。 共享
category的工具会按探测逐一比较:若同一参数名上的同一规则得到相反结论,则会将该声明标记为divergence_type = sibling,并添加注明另一工具名称的注释。 - 延续沿用。 仅运行规则的任务会将上次运行中的 LLM 声明重新纳入候选项,根据端点和探测映射到本次运行的试验,再通过相同的证据检查和重现流程。如果新一轮 LLM 声明引用了同一端点上的相同探测,则会丢弃沿用的声明(模型用新的措辞重述发现);对于彼此重复的沿用声明,则保留置信度较高的一条。
- 差异通过稳定的
claim_key比较不同工具版本的声明集。每当工具的规范哈希发生变化时,就会生成一个新版本;大型规范会裁剪后仅存储实际测试过的路径,但哈希仍基于完整文档计算。
场景试验集:API 在实际使用中的行为
探测测试组会更改一个请求中的一个参数,并根据规范判断回答。 这能找到文档中的错误,但只限于文档已经说明的内容。场景测试组会像程序一样使用 API,在多个请求之间传递状态,并根据任何合理 API 都必须满足的不变量判断结果,因此无需文档作为对照,也能发现文档从未说明的行为。
场景 1,分页完整性,适用于所有基线请求返回列表且支持页码的端点。以几页较小的页面进行两次遍历:一次按页码遍历,一次跟随 Link 标头中的 rel="next" 遍历;此外再重复读取一次页面:
- 每个条目在所有页面中恰好出现一次(或者列出重复的 ID 及其所在页面);
Link链访问的页面与逐页递增相同(或者指出偏差之处,或者说明完全没有Link标头、必须通过页码翻页);- 相隔几秒重复读取同一页面,结果是否一致(或者列表会实时排序并发生变化);
- 返回的页面大小是否与请求的页面大小相同(或者是否被静默限制);
- 列表如何结束:页面不足、页面为空,或没有
rel="next"。
每个请求都是一次试验;每项结论都会引用所有相关试验,并像其他结论一样通过 VERIFY 复现。只有在两次遍历都显示重复项时,才会报告这类发现,因此第二次遍历复现的是不变量本身。预算:以每页 5 条记录遍历 4 页,共两次(在目标配置中使用 scenarios.pagination: { pages, page_size },或设为 false 跳过),每个端点约 8 个请求。报告表会在实际使用行为下展示这些结果;简要表会将其列为分页注意事项。
场景 3 和 6,条件请求与速率限制计数,适用于所有基线请求成功的端点,每个端点最多发送 4 个请求:一次全新的 GET、一次设置为其返回的 ETag 的 If-None-Match 的相同 GET、一次设置过期标签的相同 GET,以及(如果响应中包含 Last-Modified)一次带有 If-Modified-Since 的请求。通过这一系列请求,可以确定:
If-None-Match是否会返回空响应体的 304,以及过期标签是否仍会返回 200(从而证明 304 确实是由条件触发的);或者 ETag 是否被忽略;或者是否完全没有验证器、每次轮询都是完整请求;- 304 是否会计入请求数,从而消耗速率限制额度,还是免费;
- 每个完整请求是否会使剩余次数恰好减少 1,且重置时间保持不变(固定窗口);重置值的格式是什么,以及限制额度是多少。
结论不会提及任何易变数字,因此每晚运行时都能保持稳定。在目标配置中将 scenarios.conditional 设为 false 即可禁用。在 GitHub 上,这项测试发现 /rate_limit 不计入额度,搜索有独立的 30 次额度池且没有验证器,而其他所有端点都会遵循 ETag,且 304 请求免费。
场景 4,筛选器组合,适用于筛选器参数及其已知有效值在目标配置中给定的列表端点:请求一个未筛选页面、每个筛选器各请求一个页面,以及每对筛选器各请求一个页面。当每个返回条目都符合与筛选器同名的字段时,该筛选器即为“有效”;不匹配绝不解读为“筛选器无效”(GitHub 的 commits sha 是起始引用,而不是条目谓词),而是解读为“没有明显影响”或“不会按该字段筛选”。只有当某筛选器自身的检查通过时,才会检查组合筛选结果是否包含于各单独结果中,以及字段是否匹配。场景 2,列表与详情,会在规范中查找详情端点(列表路径加一个模板段),读取两条记录的详情,并指出详情新增了哪些字段、仅列表中包含哪些字段,以及共享的标量值是否一致,以便程序知道何时需要发送第二个请求。将 scenarios.filters / scenarios.list_detail 设为 false 即可禁用。
场景 5,排序契约,针对带有排序参数的列表端点运行:先获取一个未排序页面,然后针对每个排序键(目标值加上规范中的枚举值,最多三个)和每种方向各获取一个页面,最后重复一次。它会说明每个页面是否确实按照键名对应的字段及指定方向排序;默认顺序与哪个排序页面一致;两个方向是否不同;以及相同排序是否两次返回相同顺序。在 GitHub issues 上,它发现 sort=comments&direction=asc 返回的页面并未按照条目的 comments 字段升序排列,而其他所有键和方向均符合预期。设置 scenarios.sort: false 可禁用此场景。
接下来的场景:编码和边界。全部为只读场景,均不需要账户;写入测试组稍后运行。
健康状况(供维护者参考)
npm run autopia -- tool-delete <name> --yes 会在单个事务中删除失效工具及其所有内容(版本、运行、试验、声明、差异);如果某个 API 无法访问,或者曾手动运行一次后便不再安排运行,可使用此命令。
npm run autopia -- health 会为每个需要关注的工具打印一行:当已安排运行的工具,其最近一次生成声明的运行距今已超过 3 天;当最新运行保留的声明少于此前运行中最佳结果的一半(或一条也没有);当最近三次运行全部失败;或者已安排运行的工具已运行三次却从未存储声明时,标记为红色;仅当最新一次运行失败(偶尔一晚出错很正常)、工具没有目标文件且从未刷新,或未安排运行的工具从未存储声明时,标记为警告。夜间 run-all 会在末尾打印相同的内容块,且仅在出现红色项时以非零状态退出;因此,单次暂时性故障不会再导致工作流失败,悄然退化的工具也不会。
新鲜度
每条声明都会记录其证据最近一次复现的时间。完整表格会注明其声明最近一次针对在线 API 重新执行的日期;最近 3 个夜晚内未重新运行的声明,会在其证据 ID 后注明这一点;3 个夜晚内无人重新运行的表格会显示已过时横幅;若某次运行保留的声明少于上一次成功运行的一半,则会显示覆盖率下降横幅,因为缺失并不代表已被证伪。简要表格仅在存在过时内容时提及时效。list_tools 行包含 last_verified_at / verified_days_ago;search_claims 和 get_tool_knowledge 记录包含 verified_days_ago。时效是在渲染表格时计算的,因此每晚进行差异比较的声明内容本身不会改变。
快速开始
npm install
npm run autopia -- run targets/open-meteo-forecast.json # full pipeline (LLM pass if a key is set)
npm run autopia -- docs open-meteo-forecast # the behavior sheet
npm run autopia -- claims open-meteo-forecast --divergences
npm run autopia -- search "is latitude required"
npm test
配置存放在本地 .env 文件中(已加入 gitignore),并在启动时读取:
| 变量 | 用途 |
|---|---|
ANTHROPIC_API_KEY | 启用大模型处理;未设置时,流水线仅运行规则,并会说明这一点。它也是 anthropic-api 目标的凭据 |
AUTOPIA_MODEL | 大模型处理所用的模型,默认值为 claude-opus-5-5 |
DATABASE_URL | Postgres 连接字符串;未设置时,使用 ./data/pglite 中的嵌入式 PGlite |
GITHUB_TOKEN | github-rest 目标的凭据(细粒度、仅公开读取的令牌即可) |
AUTOPIA_MCP_TOKEN | HTTP MCP 服务的管理员令牌(每位用户的密钥无需此令牌即可使用) |
AUTOPIA_MCP_OPEN | 设为 1 可在不提供任何凭据的情况下开放 /mcp;仅用于测试,切勿用于部署 |
AUTOPIA_MCP_PORT | HTTP 服务端口,默认值为 4200 |
AUTOPIA_LOG | 设为 debug 可记录每次试验的日志 |
AUTOPIA_OFFLINE | 设为 1 后,HTTP 服务无需打开数据库,即可对除 /healthz 以外的所有请求返回 503(紧急关闭开关) |
RENDER_API_KEY、NEON_API_KEY | 可选;允许通过一条命令使用 npm run kill / npm run revive 暂停和恢复托管服务 |
目标文件在请求头中使用 ${ENV_VAR} 引用凭据,因此已提交的目标文件不会包含密钥。
**PGlite 注意事项:**默认数据库是位于 data/pglite 下的嵌入式 Postgres(PGlite),同一时间只能由一个进程打开。启动 MCP 服务或仪表板前,请先停止工作进程。将 DATABASE_URL 设为真正的 Postgres,即可解除此限制(架构相同,无需更改代码)。npx tsx scripts/whichdb.ts 会显示某条命令将使用哪个数据库。
提供知识库服务
npm run mcp # MCP server over stdio (register in Claude Code / any MCP client)
npm run mcp:http # the same server over Streamable HTTP at http://localhost:4200/mcp
npm run dashboard # read-only dashboard at http://localhost:4100 (local only; not deployed)
将 stdio 服务注册到客户端时,使用 npx tsx <repo>/src/server/mcp.ts;也可以让支持 HTTP 的客户端连接 HTTP 服务上的 /mcp(通过 GET /healthz 检查服务是否正常)。该服务附带一个指令块,告知 Agent 何时查阅它:在会话中首次向受支持的主机发出请求之前,以及 API 调用失败或结果出乎意料之后。
| MCP 工具 | 用途 |
|---|---|
get_tool_docs | 行为说明;在首次请求受支持的 API 前调用。设置 brief: true 时,仅返回差异、未记录的规则、身份验证、分页和错误信息 |
search_claims | 错误排查路径:按主机和症状进行全文搜索,例如“github per_page 500” |
get_divergences | 仅返回实时 API 与其规范相矛盾的声明 |
get_tool_knowledge | 以结构化记录形式返回所有已验证的声明,支持分页和按类型筛选 |
list_tools | 工具目录;每个工具都列出其试验涉及的主机 |
list_versions、get_version_diff | 规范版本,以及两个版本之间行为上的变化 |
request_target、get_request_status | 申请尚未覆盖的 API(需要密钥) |
每个工具的 tool 参数都接受工具名称、主机,或你即将调用的 URL(api.github.com、https://registry.npmjs.org/-/v1/search)。该知识库是目录,而非数据转储:get_tool_docs 接收 URL 或 path 时,仅返回与该路径匹配的端点,以及该工具其他端点的一行索引,让 Agent 可以深入查阅所需内容,而不必接收全部信息。每份说明末尾都有覆盖范围部分,列出该 API 中已探测的端点、还存在哪些其他 API(按主机列出)、目前尚未探测的内容,以及可用于获取更多信息的工具,让读者查阅某份说明时知道还可以询问什么。证据采用精简格式(试验 ID、探测内容、状态、请求行);只有设置 verbose=true 才会返回响应预览。存储请求输入前会先进行脱敏,因此不会将凭据作为证据提供;npx tsx scripts/scan-stored-secrets.ts 可审计数据库,查找任何未能脱敏的内容。
Claude Code 插件:在需要时提供行为说明
只有在有内容提示 Agent 时,它才会读取行为说明。plugin/ 中的插件让这一过程变得确定:在 Bash 和 WebFetch 上设置 PreToolUse hook,将命令或 URL 与涵盖的主机进行匹配,并在调用前将该端点的行为说明注入模型上下文;如果对涵盖主机的调用失败,PostToolUse hook 会注入与 4xx/5xx 匹配的已验证声明。遇到任何错误时,两者都会放行。插件还会注册托管 MCP 服务以便进一步查询,并附带一项包含相同触发文本的技能。
claude plugin install autopia --marketplace MaydayTrey/autopia
claude plugin configure autopia # optional: a per-user key raises your quota; reads work without one
Hook 只会在提及看起来像 URL(https://host/... 或 host/path)时触发,并注入该 URL 中端点的简要行为说明:该端点的规范矛盾、未记录规则、身份验证、分页和错误行为、整个工具的身份验证行为,以及其他端点的一行索引。每个会话中,每个主机和端点只触发一次;内容远低于 5KB。
项目级指令。 仓库的 CLAUDE.md 或 AGENTS.md 中的一行指令,比任何服务端指令块都更可靠。对于集成了涵盖 API 的项目,请添加:
Before the first call to api.github.com (or registry.npmjs.org, pypi.org, api.anthropic.com) in a
session, read its verified behavior sheet: Autopia MCP tool get_tool_docs {"tool":"<the URL you are about to call>"}.
On an unexpected 4xx/5xx or an empty result from one of those hosts, call search_claims with the host
and the symptom before retrying.
该插件仅适用于 Claude Code。Cursor、Codex、Claude Desktop,以及任何会读取 AGENTS.md 的 Agent,都可以通过托管服务加上粘贴式指令块获得相同的行为;这些指令块位于 docs/distribution.md。
要从检出目录开始仅在当前会话中试用:claude --plugin-dir ./plugin。在配置密钥之前,会话会显示 autopia MCP 服务连接失败(401),且 Hook 会注入设置说明,而不是行为说明;运行 claude plugin configure autopia 并开启新会话后,两者都会消失。详情、状态文件位置和隐私说明见 plugin/README.md。
静态页面:Agent 已经会查找的地方
搜索错误字符串时,应能找到引用了复现试验的页面,无需插件或 MCP 连接。npx tsx scripts/build-site.ts --out site --base <url> 会将汇编内容渲染为静态网站:包含目录、每个 API 各一页、每个端点各一页、列出每条已观察到的错误消息及其触发条件的索引、llms.txt(AI 爬虫索引)、站点地图和 robots.txt。页面是采用最简 HTML 包装的行为说明;每个页面都有对应的纯文本 .md 版本,并注明可实时返回相同内容的 MCP 调用。
.github/workflows/pages.yml 会在刷新后每日从托管数据库构建网站(也可按需构建),并发布到 GitHub Pages。一次性设置:仓库 Settings -> Pages -> Source: GitHub Actions。网站地址为 https://<owner>.github.io/<repo>/。
数据传输(按量计费的资源)
Neon 免费计划会对读取量收费:每月 5 GB 数据传输额度,而存储额度为 0.5 GB。数据库本身很小(夜间运行十天后约为 90 MB);成本来自读取。过去有三类读取操作占了大头,已于 2026-10-20 进行削减:除非调用者提供密钥请求预览,否则读取证据试验时会跳过响应正文(响应列占试验表的大部分);网站构建会为每个工具加载一次知识,而不是每页加载一次(每天约从 50 MB 降至 2 MB);目录会在 SQL 中统计声明数量,而不是加载每一行声明;服务端的响应缓存有效期从十分钟延长至两小时。渲染行为说明或扫描试验的临时命令也会读取托管数据库,因此做实验时请将 DATABASE_URL 指向本地 PGlite 目录。
紧急停止开关
如果流量失控,有三个级别可供选择,每个级别都可撤销,且都不会产生账单(Render 和 Neon 均未绑定信用卡;唯一会产生费用的账户是每周 LLM 运行所用的 Anthropic 密钥,它在 Anthropic 控制台中设有自己的支出限额):
- 停止提供服务,保留进程: 在 Render 服务的环境变量中设置
AUTOPIA_OFFLINE=1。除/healthz外,所有请求都会返回 503 和 retry-after,且不会打开数据库。静态网站仍会继续提供表单。移除该变量即可恢复。 - 停止托管服务:
npm run kill通过 API 暂停 Render Web 服务和 Neon 计算端点(需要在.env中设置RENDER_API_KEY和NEON_API_KEY;服务和端点会自动发现)。npm run revive会恢复两者;npm run kill:status会显示状态。如果没有密钥,命令会改为打印控制面板中的操作步骤。 - 停止支出: 在 Actions 下禁用
run-all-llm工作流。这是唯一会调用付费 API 的作业。
保持最新(自动化)
npm run run-all # every targets/*.json in sequence, one summary line per tool
npm run run-all -- --no-llm --prune-days 14
run-all 会先处理待处理的用户请求,然后重新获取每份规范;如果规范哈希发生变化,就会创建新工具版本,接着重新运行测试、重新验证,并与上一版本计算差异。任何目标失败时,进程都会以非零状态退出。无法访问的目标会提前放弃,不会逐次试验直到超时。
计划任务。 .github/workflows/run-all.yml 每晚运行仅规则模式(免费);run-all-llm.yml 每周使用模型运行一次;两者都会从仓库机密中读取 DATABASE_URL、ANTHROPIC_API_KEY 和内置的 GITHUB_TOKEN,也可以从 Actions 选项卡手动触发。模型运行是唯一会随目标数量增加而增加成本的部分;延续机制会在每周运行之间保留其声明。保留策略: --prune-days N(或 autopia prune N)会删除超过 N 天的运行记录,但会保留每个版本最新的已完成运行,以及任何差异记录引用的运行;--dry-run 只报告,不执行删除。其他环境中可使用现有的任意调度器(任务计划程序、cron,或主机上的计划作业)运行相同命令。
用户请求的目标
任何持有密钥的人都可以在自己的 Agent 中使用 request_target MCP 工具,请求知识汇编测试尚未收录的 API。请求会立即验证:获取并解析规范、规划测试集,并向用户返回所需的端点和试验数量。范围限制会在提交时强制执行,而非通过审核:
- 仅允许公开的 http(s) 主机,规范及其列出的所有服务器均须符合要求(不允许 localhost、私有地址范围、IP 字面量或
.internal风格的名称:工作进程绝不能成为通往其运行环境中任意位置的代理) - 不需要密钥:拒绝带有请求头的目标;凭据由贡献者层级负责
- 我们可控的调用规范:并发数为 1、每次调用至少间隔 300ms,最多 300 次试验
- 工具名称不得重复,且每个密钥每天最多可提交 3 个请求
待处理请求会在下一次 run-all 运行开始时以仅规则模式处理,也可以手动运行 npm run autopia -- requests process 处理。处理完成后,目标会被保存,并像文件目标一样加入之后的每次运行。get_request_status 会报告 pending / running / done / failed;npm run autopia -- requests list 会显示所有请求。
带密钥的目标:两种路径
服务端层级,凭据存储在 Actions secrets 中。 github-rest 和 anthropic-api 是由服务端自行运行的带密钥目标:目标文件将请求头命名为 ${GITHUB_TOKEN} 或 ${ANTHROPIC_API_KEY},工作流传入密钥,存储的试运行输入会按请求头名称进行脱敏,重现时则从内存中的目标恢复真实值。密钥只会通过网络发送给 API,不会出现在其他地方。测试组用于错误认证探测的虚假凭据会刻意保留,不做脱敏,以便重现时能将其与真实密钥区分开来。
贡献者层级,凭据绝不会离开贡献者的设备。 对于密钥不能存放在本仓库的 secrets 中的 API,同一个开源 worker 会在贡献者的设备上运行,使用他们的 API 密钥、模型密钥和自己的数据库,然后上传结果:
npm run autopia -- contribute my-keyed-api --to https://autopia-mcp.onrender.com --key ak_... --yes
从设计上说,上传内容只有声明,以及表示为状态码和响应签名的证据(不包含任何值的类型结构)。不包含请求输入、请求头、响应正文或错误消息文本。声明内容会在本地和服务端各清理一次:任何看起来像电子邮件地址、令牌、bearer 凭据、长十六进制字符串或长数字标识符的内容,都会导致该声明被丢弃。若不使用 --yes,命令会打印准备上传的所有声明,然后停止。贡献者工具属于一个明确标示的信任层级:其工作表会显示横幅,注明贡献者密钥前缀和声明上次重现的日期,并说明此服务端此后尚未重新验证这些声明。此服务端自行验证的工具绝不会被贡献内容覆盖。
托管:托管式 Postgres + HTTP MCP 服务
嵌入式数据库适合一台笔记本电脑。托管式目录使用托管式 Postgres,以便 worker 和服务端能够同时运行,并将 HTTP MCP 服务部署在一个始终在线的位置。代码路径完全相同:DATABASE_URL 会切换驱动程序,连接时会应用迁移,而 tests/integration/postgres-path.test.ts 会通过真实的 Postgres wire protocol 对其进行测试。
1. 数据库(Neon 或 Supabase,两者都包含 pgvector)。 创建项目,复制连接字符串,然后迁移现有目录:
npx tsx scripts/db-export.ts data/export.json
DATABASE_URL="postgres://..." npx tsx scripts/db-import.ts data/export.json
导入会保留 ID,跳过已存在的行,并重置序列,因此可以安全地重复运行。将相同的 DATABASE_URL 放入 .env 后,笔记本电脑上的每条命令都会改为访问托管数据库。
2a. 在 Render 上运行服务端(免费层级,无需银行卡;当前部署方式)。 render.yaml 是一个 Blueprint。在 Render 中:New -> Blueprint -> 选择代码仓库。Render 会构建 Dockerfile,提示输入 DATABASE_URL 并生成 AUTOPIA_MCP_TOKEN(从服务的 Environment 选项卡中复制)。免费服务在空闲约 15 分钟后会休眠,并在收到第一个请求时唤醒,因此首次调用可能较慢;插件的 hook 会通过失败时放行并在下次调用时重试来应对此情况。Render 会从 main 自动部署。
2b. 在 Fly.io 上运行服务端(付费账户,始终在线)。 仓库中包含 fly.toml 和 Dockerfile:
fly launch --copy-config --no-deploy
fly secrets set DATABASE_URL="postgres://..." AUTOPIA_MCP_TOKEN="$(openssl rand -hex 24)"
fly deploy
服务端会在 /mcp 上监听,并提供 GET /healthz 用于平台检查。镜像中也包含 worker,因此 run-all 可以作为计划任务机器运行,也可以手动运行。Railway 使用相同的 Dockerfile,配置方式也相同。
身份:匿名读取,写入需密钥
读取公开,但有配额限制。 七种读取工具无需任何凭据即可调用,受每 IP 限制(AUTOPIA_ANON_PER_MINUTE,默认值为 30;AUTOPIA_ANON_PER_DAY,默认值为 300)和全局每日上限(AUTOPIA_ANON_DAILY_CAP,默认值为 5,000)约束。匿名调用者不会收到响应预览,且页面大小有限制。读取响应(表格、目录、搜索结果、声明)会在内存缓存中保存十分钟(AUTOPIA_CACHE_TTL_MS),因此重复的匿名调用不会访问数据库。这些默认值适配底层免费套餐:每天 5,000 份简要表格大约产生 75 MB 出站流量和几百次数据库往返,远低于 Render 和 Neon 的免费额度;如果托管资源能承受更多流量,可调高这些数值。达到上限后,匿名调用者会收到带有重试等待时间的 429 响应;持密钥的调用者不受影响。读取公共 API 不需要按用户进行身份识别。设置 AUTOPIA_ANON_READS=0 可恢复仅密钥访问。request_target 和 /contribute 始终需要密钥。
密钥为调用者提供专属配额、使用日志中的名称,以及写入工具:
npm run autopia -- keys create alice --quota 2000
密钥(ak_...)仅显示一次;系统只存储其哈希值。用户通过 Authorization: Bearer ak_... 发送密钥。keys list 会显示密钥前缀、配额和调用次数;keys revoke <name-or-prefix> 会停用指定密钥;超过每日配额的密钥会收到 429 响应。每次工具调用都会记录密钥、工具、请求的目标、是否成功及延迟;npm run autopia -- usage --days 7 会按密钥和最常被查询的工具汇总数据。
如果设置了 AUTOPIA_MCP_TOKEN,它会作为管理员令牌使用(无配额;比较时采用恒定时间;调用会在没有密钥的情况下记录)。AUTOPIA_MCP_OPEN=1 会完全禁用匿名限制(仅用于测试)。目前密钥由维护者发放;自助发放已列入路线图。
CLI
| 命令 | 功能 |
|---|---|
run <target.json> [--no-llm] [--max-trials N] [--no-reproduce] | 对单个目标运行完整流水线 |
run-all [dir] [--no-llm] [--prune-days N] [--dry-run] | 处理待处理请求,然后处理 dir 中的每个目标(默认值为 targets/) |
plan <target.json> | 打印试验计划,不发送任何内容 |
tools、versions <tool>、runs <tool> | 目录 |
docs <tool> [--version ID] | 以 Markdown 格式显示行为说明 |
claims <tool> [--divergences] [--version ID] [--json] | 显示附有证据的已验证声明 |
search "<question>" [--tool NAME] | 搜索声明文本 |
diff <tool> <fromVersionId> <toVersionId> | 查看版本间的变更日志 |
trial <id> | 查看某次完整试验 |
compare-runs <tool> | 检查最近两次运行的确定性 |
requests list、requests process [--llm] | 用户请求的目标 |
keys create <name> [--quota N]、keys list、keys revoke <name-or-prefix> | 用户专属密钥 |
usage [--days N] | 按密钥和工具统计调用次数 |
contribute <tool> [--to URL --key ak_... --yes] [--out file] | 构建(并上传)贡献者数据包 |
prune [days] [--dry-run] | 保留策略 |
AUTOPIA_LOG=debug 会输出每次试验和每项验证决策。辅助脚本位于 scripts/ 下:run-progress.ts(监控运行)、fail-stale-runs.ts(将中断的运行标记为失败)、inspect-repro.ts 和 auth-probe-check.ts(调试复现和身份验证探测)、plan-dry-run.ts、db-smoke.ts、whichdb.ts、scan-stored-secrets.ts。
添加目标
创建 targets/<name>.json(文件名就是工具名称):
{
"name": "my-api",
"category": "weather",
"spec_url": "https://example.com/openapi.yml",
"include_paths": ["/v1/path"],
"baseline": { "/v1/path": { "required_param": "known good value" } },
"optional_values": { "/v1/path": { "optional_param": "known good value", "since": "2026-01-01T00:00:00Z" } },
"headers": { "x-api-key": "${MY_API_KEY}" },
"rate": { "concurrency": 1, "min_interval_ms": 500 },
"rate_overrides": { "/v1/search": { "min_interval_ms": 2500 } },
"server": "https://api.example.com",
"max_trials": 300
}
include_paths用于从大型规范中筛选出值得探测的端点(GitHub 的规范有 816 个路径;该目标会测试 7 个)。存储的规范会裁剪为这些路径及其引用的组件,但版本哈希仍覆盖完整文档。rate_overrides用于降低各自有配额的单个路径的请求速率(GitHub 搜索:30 次/分钟)。执行器还会将带有x-ratelimit-remaining: 0的 403 响应视为速率限制,并休眠至配额重置。- 如果规范未声明基础 URL,
server会提供一个;override_server: true则会替换已声明的服务器(区域镜像)。 - 目标可以指向仓库中的规范文件,而不是 URL。
specs/存放手工编写的 OpenAPI 描述,适用于未发布规范的 API(npm registry、PyPI、Anthropic 模型端点);针对这些文件报告的差异表示“API 与我们的描述不一致”,文件头也会说明这一点。 targets/parked/存放暂时移出的目标(原因请参阅其中的 README)。
范围规则(v1):仅探测 OpenAPI 3.x API 的只读 GET 端点,这些 API 可以是公开的,也可以由单个凭据标头保护。目前不探测写入端点和 JSON 请求正文。如果目标没有正式规范或存在副作用,则不在范围内;discover 会报错并停止。
测试
npm test 会运行所有测试(130 个);npm run test:unit 和 npm run test:integration 会分别运行单元测试和集成测试。
- 单元测试位于
tests/unit,每个阶段对应一个文件:规范解析、测试集、签名、HTTP 执行器(模拟 fetch)、规则、结构规则、交叉引用、向前沿用、验证、差异、文档渲染、脱敏、密钥、贡献内容清理、主机解析,以及插件钩子的辅助函数。 - 集成测试位于
tests/integration:在一次性数据库上,对带有预置异常的 模拟 API(tests/mock-api/server.ts)运行真实管道;通过 stdio 和 HTTP 运行 MCP 服务(开放访问、管理员令牌、每用户密钥);用户请求;贡献;保留策略;不可访问的目标;通过 PGlite 测试 Postgres 通信路径;以及将插件钩子作为子进程,对真实 HTTP 服务运行。 npm run mock-api会手动启动模拟 API,以便进行手动测试。
Postgres 路径测试偶尔会在完整并行运行期间的设置阶段失败,但单独运行时会通过;怀疑代码改动前请重新运行。
目录结构
docs/ spec + stack docs
targets/ one JSON per API under study (parked/ for the ones on hold)
specs/ hand-authored OpenAPI docs for APIs that publish none
drizzle/ generated SQL migrations (npm run db:generate after editing schema.ts)
src/db/ schema.ts (source of truth), client.ts (PGlite or Postgres), queries.ts,
docs.ts (behavior sheets), keys.ts, requests.ts, contributions.ts, retention.ts
src/worker/ pipeline stages: discover, exercise, aggregate/{rules,shape-rules,llm,carry},
crossref, verify, write, diff, pipeline.ts, cli.ts; battery/; signature,
http, redact, target, requests-runner, contribute
src/llm/ provider adapter (worker only, never the server)
src/schemas/ claim.schema.json
src/server/mcp.ts MCP server (stdio and Streamable HTTP), instructions block, /contribute
src/dashboard/ Express + static page (local use)
plugin/ Claude Code plugin: PreToolUse hook, .mcp.json, skill, README
.claude-plugin/ marketplace.json (install source for the plugin)
.github/workflows/ test on push/PR; nightly rules-only and weekly LLM refresh
scripts/ export/import, audits, run helpers
tests/ unit, integration, mock-api, helpers
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。