mcpField
A
Autopia

Autopia

远程服务
maydaytrey.github.io开发工具01 周前更新

关于 Autopia

Autopia 实测带有 OpenAPI 规范的 HTTP API,并保存可复现、带版本的发现结果,供 AI Agent 和 Claude Code 使用。它重点记录文档与实际行为的差异,包括错误、分页和认证。

主要功能

  1. 01依据 OpenAPI 规范探测 API
  2. 02复现并验证每项发现
  3. 03生成带版本的行为说明
  4. 04记录规范差异与未注明规则
  5. 05比较不同 API 版本的发现

适用场景

  1. 01检查 API 的实际错误行为
  2. 02定位分页和认证方面的特殊表现
  3. 03在 Agent 调用前查阅已验证的行为
  4. 04审查版本之间的行为变化

MCP 相关

Autopia 通过 MCP 服务提供已验证的 API 行为知识库,供 AI Agent 查询。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://autopia-mcp.onrender.com/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

全部服务地址
Streamable HTTPhttps://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_URLPostgres 连接字符串;未设置时,使用 ./data/pglite 中的嵌入式 PGlite
GITHUB_TOKENgithub-rest 目标的凭据(细粒度、仅公开读取的令牌即可)
AUTOPIA_MCP_TOKENHTTP MCP 服务的管理员令牌(每位用户的密钥无需此令牌即可使用)
AUTOPIA_MCP_OPEN设为 1 可在不提供任何凭据的情况下开放 /mcp;仅用于测试,切勿用于部署
AUTOPIA_MCP_PORTHTTP 服务端口,默认值为 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 控制台中设有自己的支出限额):

  1. 停止提供服务,保留进程: 在 Render 服务的环境变量中设置 AUTOPIA_OFFLINE=1。除 /healthz 外,所有请求都会返回 503 和 retry-after,且不会打开数据库。静态网站仍会继续提供表单。移除该变量即可恢复。
  2. 停止托管服务: npm run kill 通过 API 暂停 Render Web 服务和 Neon 计算端点(需要在 .env 中设置 RENDER_API_KEY 和 NEON_API_KEY;服务和端点会自动发现)。npm run revive 会恢复两者;npm run kill:status 会显示状态。如果没有密钥,命令会改为打印控制面板中的操作步骤。
  3. 停止支出: 在 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

评论

支持 Markdown

第一次接触 MCP?

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

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