关于 PG1 Sovereign Threat Intelligence
PG1 Sovereign Threat Intelligence 为 AI Agent 和安全工具提供威胁情报检查。它支持单项检查及行动前的综合预检,并以 Ed25519 签名结果,便于离线验证。
主要功能
- 01钱包、域名和主机名检查
- 02npm 与 PyPI 包检查
- 03CVE 与威胁行为者查询
- 04行动前并行预检
- 05Ed25519 签名结果验证
适用场景
- 01付款前检查钱包风险
- 02打开链接前检查域名
- 03安装 npm 或 PyPI 包前筛查
- 04评估漏洞并验证检查结果
MCP 相关
MCP 服务提供预检、钱包和域名检查、包与 CVE 查询、签名验证等工具;部分检查免费,付费调用可通过 x402 使用。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://pg1-ai-agent.vercel.app/api/mcpclaude mcp add --transport http project-gifted1-pg1-threat-intel https://pg1-ai-agent.vercel.app/api/mcp{"mcpServers":{"project-gifted1-pg1-threat-intel":{"type":"http","url":"https://pg1-ai-agent.vercel.app/api/mcp"}}}在 Cursor 中打开{"servers":{"project-gifted1-pg1-threat-intel":{"type":"http","url":"https://pg1-ai-agent.vercel.app/api/mcp"}}}在 VS Code 中打开{"mcpServers":{"project-gifted1-pg1-threat-intel":{"type":"http","url":"https://pg1-ai-agent.vercel.app/api/mcp"}}}{"mcpServers":{"project-gifted1-pg1-threat-intel":{"serverUrl":"https://pg1-ai-agent.vercel.app/api/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
20| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| chain | enum | 否 | 向钱包付款时使用的链(默认为 base)。base | ethereum | arbitrum | optimism | polygon | bsc |
| action | enum | 是 | 你即将执行的操作。pay | open | install | patch | trust_agent |
| target | string | 是 | 你即将对其执行操作的目标:钱包地址、URL、主机名、软件包名称(name 或 name@version)、CVE ID、“vendor product version”,或 Agent URL/域名。 |
| ecosystem | enum | 否 | 安装操作使用的软件包注册表。npm | pypi |
详细介绍
PG1 主权威胁情报 API
为 AI Agent 和安全工具提供的威胁情报 API 和 MCP 服务。
许可证密钥: 新销售暂时暂停,等待数据许可事宜最终敲定。免费层和 x402 仍可使用。
面向 Agent
从免费的单点检查开始。当你希望在采取行动前做出一个决定时,请使用 preflight_check。
今天免费试用付费路径: 每位调用者每天可免费进行 5 次付费调用,无需密钥、账号或付款。付款前,请通过免费的 get_usage_status 工具读取 free_tier_calls_remaining_today(或查看响应标头 X-Free-Tier-Remaining)。
Agent 为何使用 PG1
自主 Agent 会对从未见过的事物采取行动:支付钱包、打开链接、安装软件包、修补 CVE。PG1 会先检查该事物,并以一种机器可读的格式 reasons + status + checks 返回结果,让 Agent 自行决策,也方便人工审查原因。
- 它绝不会说“安全”。 PG1 只知道其数据源记录的内容,因此它能给出的最佳答案是
no_flags:已检查的数据源中未发现问题。未完成的检查会返回unknown,绝不会返回no_flags。 - 免费开始使用。 钱包、域名、主机名和软件包检查始终免费。付费调用每天先提供 5 次免费额度;之后每次通过 x402 在 Base 上以 USDC 收费 0.01 USD,无需账号或密钥。
- 行动前只需一次调用:
preflight_check接收你即将执行的操作(pay、open、install、patch、trust_agent)及其目标,并行运行所有相关检查,并返回一个决策。它采用失败关闭策略:未完成的检查会使结果变为unknown。 - 结果经过签名。 每个结果都附带 Ed25519 签名,签名覆盖请求、结果、数据源、时间戳和 PG1 版本;你可以通过 /.well-known/pg1-signing-key 离线验证,也可以使用免费的
verify_result工具验证。 - 最重要的工具:
preflight_check、check_wallet_sanctions、check_wallet_age、check_hostname_reputation、check_domain_age、check_package、get_cve_details、get_cve_batch、get_threat_actor_profile和get_ioc_context。
不到 30 秒即可连接。将 MCP 服务添加到你的客户端:
{ "mcpServers": { "pg1": { "type": "http", "url": "https://pg1-ai-agent.vercel.app/api/mcp" } } }
或者直接调用:
curl -X POST https://pg1-ai-agent.vercel.app/api/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"check_hostname_reputation","arguments":{"hostname":"example.com"}}}'
A2A Agent 使用 https://pg1-ai-agent.vercel.app/api/a2a(Agent 卡片位于 /.well-known/agent-card.json)。
应调用哪个工具
| 你要做的事 | 调用 | 说明 |
|---|---|---|
| 即将执行的操作(付款、打开、安装、修补、信任某个 Agent) | preflight_check | 想要做出单项决策时,从这里开始。每次调用 0.01 USD,每天有 5 次免费调用(与其他付费工具共享)。并行运行以下检查,并返回一个决策:no_flags(未发现标记)、flagged 或 unknown。默认拒绝:检查未完成时,决策为 unknown,绝不会是 no_flags。 |
| 即将付款的 x402 端点 | check_x402_endpoint | 读取其 402 付款请求:payTo 制裁筛查和钱包年龄、网络和资产合理性、TLS、域名年龄。 |
| 即将信任的另一个 Agent | check_agent_card | 获取其 A2A Agent 卡片:架构有效性、域名年龄和信誉、相似名称。 |
| 托管工作负载的位置(隐私、数据驻留、延迟、正常运行时间、预算) | hosting_advisor | 提供按排名排列的区域和服务商,并附带引用依据、冗余方案和隐私设计指导。付费;不构成法律建议。REST:POST /api/hosting-advisor。 |
| PG1 结果及其签名 | verify_result | 根据 PG1 已发布的密钥检查 Ed25519 签名。始终免费。 |
| 单个 IP、域名、URL 或文件哈希 | get_ioc_context | 没有记录时免费(found: false)。PG1 的授权记录目前仅包含来自 NVD 的 CVE ID,因此 IP、域名、URL 或哈希会返回 found: false;对于域名或主机名,还要运行下面的两项主机名检查。 |
| 多个指标(最多 20 个) | get_ioc_batch | 没有指标被发现时免费(与上述相同,仅包含 CVE 的记录)。请阅读 results 中的每个条目,而不只是批次的 status。 |
| CVE ID | get_cve_details | 多个 ID:使用 get_cve_batch(最多 20 个)。 |
| 厂商和产品,无 CVE ID | get_cve_by_product | 已知遭利用的 CVE 会优先显示。 |
| 即将付款或信任的钱包地址 | check_wallet_sanctions 和 check_wallet_age | 先匹配制裁名单,再检查链上年龄;没有历史记录的钱包会被标记。 |
| 链接、主机名或疑似钓鱼网站 | check_hostname_reputation 和 check_domain_age | 先检查主机名是否在名单中或与其他名称相似,再检查注册时间;注册未满 30 天的域名会被标记。 |
| 安装前检查 npm 或 PyPI 包 | check_package | 对不存在的名称、恶意报告,或热门包的新相似名称进行标记。 |
| 威胁行为者或 APT 名称 | get_threat_actor_profile | MITRE ATT&CK 档案。 |
| 单个公网 IP 和你自己的 AbuseIPDB 密钥 | check_ip_abuse | 将密钥放在 X-AbuseIPDB-Key 中发送;PG1 自己没有密钥。 |
| 要导入的 CVE 列表 | get_threat_indicators | 来自 NVD 的 CVE 记录 STIX 2.1 包:包含 CVE ID 和 NVD 参考,不包含评分或 IP/域名/URL/哈希指标。REST:GET /api/ioc。免费(CVE 记录来自 NIST NVD);不占用每天 5 次付费工具免费调用;无需付款或许可证密钥(运营方的 PG1_FEED_PAID 开关可将其设为付费)。 |
| 剩余免费调用次数 | get_usage_status | 始终免费。 |
| 想要报告的已观察指标 | submit_indicator | 仅需许可证密钥(X-API-KEY);不按调用次数收费。提交内容会经过审核后才会使用。 |
一次付费调用值 0.01 USD 的情况
单项信号使用免费检查。只有在需要免费检查无法提供的信息时才付费:
| 你需要 | 调用 | 0.01 USD 能获得什么 |
|---|---|---|
| 单项信号(此钱包是否受到制裁、此域名是否为新注册) | 免费的 check_* 工具 | 无需付费:始终免费。 |
| 执行操作前做出一次失败即关闭的判断 | preflight_check | 执行操作所需的每项检查(pay 一个钱包:制裁状态和链上存续时间;open 一个链接:主机名信誉和域名存续时间;patch:该产品的 CVE 查询),并行运行后合并为一个带签名的 decision,其中包含每项原因和检查结果。未能完成的检查会标记为 unknown,因此你无需自行编写合并或超时逻辑。 |
| 是否现在修补某个 CVE | get_cve_details(或 get_cve_batch、get_cve_by_product) | cisa_kev.is_known_exploited、KEV 的 required_action、CVSS 和 reasons,其中 CVE_KNOWN_EXPLOITED_KEV 可用于匹配:已知遭利用意味着应优先修补。 |
| IP、域名、URL 或哈希的上下文 | get_ioc_context | 目前 PG1 获许可的记录仅包含 NVD CVE ID,因此这些调用会返回 found: false,且不收费。对于这些信号,请使用免费的主机名、域名和钱包检查。 |
| 了解情况何时变化 | 监控列表(见下文) | 每日重新检查并发送带签名的 webhook,让你不必再手动重复检查。 |
| 应在哪里托管工作负载 | hosting_advisor | 这是规划工具,而非操作前检查:提供按优先级排列的区域和服务商,并附上引用来源。 |
使用监控,而不是重复检查
以下四个目标的费用为 4 x 0.05 = 0.20 USD,可监控 30 天,通过 x402 一次性付费(监控列表没有免费套餐)。PG1 大约每 24 小时使用与 preflight_check 相同的检查重新检查每个项目,并且仅当某个项目的 status 发生变化时才向你的 webhook 发送 POST 请求。
curl -X POST https://pg1-ai-agent.vercel.app/api/watchlists \
-H "Content-Type: application/json" \
-d '{"webhook_url":"https://agent.example.com/pg1","items":[{"kind":"wallet","target":"0x..."},{"kind":"domain","target":"pay.example.com"},{"kind":"package","target":"left-pad","ecosystem":"npm"},{"kind":"cve_product","target":"openssl openssl 3.0"}]}'
首次响应是 402 付款请求;完成付款并重新发送请求后,会收到 201 { id, secret, expires_at, items }。请保管好 secret:它只会显示一次,可用于验证每个 webhook 的 X-PG1-Signature,并验证 GET/DELETE /api/watchlists?id=<id> 请求。每次推送都是一个 watchlist.status_changed 事件,包含项目、previous_status、status 和 reasons。
一次 preflight_check,三种操作
每次调用都会返回一个 decision。这些目标是 PG1 的测试夹具(/docs/testing),因此其中的检查不会查询上游,答案也是固定的;但每次 preflight_check 调用仍会计入每天 5 次的免费调用额度。
{"action":"open","target":"https://pg1-test-flagged.invalid/login"}
{"action":"pay","target":"0x7067312d746573742d6669787475726500000002"}
{"action":"install","target":"_pg1-test-unknown","ecosystem":"npm"}
| 操作 | 运行的检查 | decision | 原因 |
|---|---|---|---|
open + URL | check_hostname_reputation、check_domain_age | flagged | HOSTNAME_PHISHING_LISTED 和 DOMAIN_NEWLY_REGISTERED_30D |
pay + 钱包 | check_wallet_sanctions、check_wallet_age | no_flags | 在已检查的来源中未发现标记。这并不代表该钱包安全。 |
install + 软件包 | check_package | unknown | 软件包查询未能完成,因此该判断失败即关闭。请停止操作或咨询人员。 |
status 的含义
status | 含义 | 应采取的措施 |
|---|---|---|
"no_flags" | 在已检查的来源中未发现标记(见 checks)。PG1 绝不会将目标称为“安全”。 | 按照你自己的策略继续操作。 |
"flagged" | reasons 中至少有一项警告。 | 停止操作,或升级给人员处理。请根据 reasons[].code 匹配,绝不要根据 message 匹配。 |
"unknown" | 某个来源超时、出错或被跳过,因此答案不完整。 | 绝不要将其视为无问题:重试,或失败即关闭。 |
信息性代码(WALLET_DELEGATED、IP_TOR_EXIT_NODE、IP_WHITELISTED、IP_REPORTS_SCORED_ZERO)只报告事实,不会改变 status。所有代码:/docs/reason-codes。
验证结果
PG1 的每个结果都使用 Ed25519 签名,因此 Agent 之后可以离线证明 PG1 曾给出该结果。
- 位置: MCP 的
result._meta["pg1/signature"]、A2A 任务的metadata["pg1.signature"]、REST(/api/preflight、/api/hosting-advisor)顶层的signature。 - 数据块:
{ alg: "EdDSA", kid, request_hash, sources, timestamp, version, sig, jwks_url }。 - 密钥: 位于 /.well-known/pg1-signing-key 的 JWKS(RFC 7517;Ed25519 密钥使用
OKP,RFC 8037),以及位于 /.well-known/jwks.json 的相同文档。根据kid选择密钥;当前生产环境的kid是a3f2fbf9d8188a3c。密钥轮换后旧密钥仍会保留在列表中,因此旧签名仍可验证;遇到未知的kid时,请重新获取 JWKS。 - 从结果中查找密钥: 每个签名数据块都包含
jwks_url,每个带有签名的响应都包含标头Link: <https://pg1-ai-agent.vercel.app/.well-known/pg1-signing-key>; rel="jwks"。jwks_url不属于签名内容:请在验证器中固定 PG1 自己的 URL,而不要信任消息中附带的 URL。 - 验证方式: 使用免费的
verify_result工具、PG1 SDK 离线验证(JavaScript 中的verifyResult,Python 中的verify_result),或使用下面的 10 行代码片段。
签名输入,精确格式。 sig 是对 { request_hash, result, sources, timestamp, version } 的规范 JSON UTF-8 字节进行签名所得的 Ed25519 签名(RFC 8032,纯 Ed25519,不预哈希),编码为不带填充的 base64url(RFC 4648 第 5 节):
request_hash:{ "arguments": <the arguments you sent>, "tool": "<the tool name>" }的规范 JSON UTF-8 字节的 SHA-256 小写十六进制值。这里的工具是 MCP 工具名称、A2A 技能名称,或 REST 的preflight_check/hosting_advisor;缺少参数时按{}处理。重新计算该值以确认签名对应你的请求:签名不能转移到其他请求上。result:原样返回的结果对象(MCP:content[0].text中的 JSON;A2A:工件的数据部分;REST:响应正文),但不包含其自身的signature字段。request_id和test_fixture都属于该对象。sources:结果中checks[].source的去重值,按首次出现的顺序排列。timestamp:PG1 签署该结果的时间,采用带毫秒的 ISO 8601 UTC 格式(2026-10-21T12:00:00.000Z)。version:PG1 的公开版本(server.json)。
规范 JSON。 对象键按 UTF-16 代码单元排序;任何位置都不含空白;数组保持原顺序;字符串和数字按 JavaScript 的 JSON.stringify 原样写入。数字采用可往返还原的最短形式(1e+30、0.002、1e-7;整数不带小数部分)。字符串只转义 "、反斜杠和控制字符(\b \f \n \r \t,其余控制字符写为小写 \u00xx);其他所有字符,包括非 ASCII 字符,都直接写为 UTF-8 字节。对于任何 I-JSON 值,这符合 RFC 8785(JCS),而 PG1 的结果始终是 I-JSON。下面的 Python 代码片段使用 json.dumps(sort_keys=True, separators=(",", ":"), ensure_ascii=False),生成的字节相同,但有两种例外。第一,绝对值小于 0.0001 的非零数字:Python 会写成 4e-05,而 JavaScript 会写成 0.00004。第二,位于基本多文种平面之外的对象键:Python 按码点排序。包含任一情况的结果(例如非常小的 EPSS 分数)会导致该代码片段验证失败;请改用 RFC 8785 库(例如 rfc8785 包)、PG1 Python SDK,或免费的 verify_result 工具。
示例。 signed-result-example.json 是一个真实的测试数据结果(在 FLAGGED 测试钱包上运行 check_wallet_sanctions),其中包含签名。该结果使用文档示例密钥签署(kid 为 pg1-docs-example,公钥位于 signed-result-example-jwks.json),从不使用生产密钥。其签名数据块:
{
"alg": "EdDSA",
"kid": "pg1-docs-example",
"request_hash": "3b139e7fce1af42a65163e87c9c2c4914225a07c13069cf750b0d17fd8c7da73",
"sources": [
"fixture"
],
"timestamp": "2026-10-21T12:00:00.000Z",
"version": "1.20.2",
"sig": "IUs2DSN_FxT8zIuH7m3VQAYxTfwszHMoGFmSfLjxqBq5KNYE-Yzwyq5Ls10_qXLnfmhUM_W6wRlWZTbhR4MJAg",
"jwks_url": "https://pg1-ai-agent.vercel.app/.well-known/pg1-signing-key"
}
在 Node 中离线验证(18+,无依赖;verify-pg1.mjs):
import crypto from 'node:crypto';
const canon = (v) => v === null || typeof v !== 'object' ? JSON.stringify(v) : Array.isArray(v) ? `[${v.map(canon)}]` : `{${Object.keys(v).sort().map((k) => `${JSON.stringify(k)}:${canon(v[k])}`)}}`;
export async function verifyPg1(result, sig, jwksUrl = 'https://pg1-ai-agent.vercel.app/.well-known/pg1-signing-key') {
const { signature, ...clean } = result;
const jwk = (await (await fetch(jwksUrl)).json()).keys.find((k) => k.kid === sig.kid);
if (!jwk || sig.alg !== 'EdDSA') return false;
const signed = canon({ request_hash: sig.request_hash, result: clean, sources: sig.sources, timestamp: sig.timestamp, version: sig.version });
const key = crypto.createPublicKey({ key: { kty: 'OKP', crv: 'Ed25519', x: jwk.x }, format: 'jwk' });
return crypto.verify(null, Buffer.from(signed, 'utf8'), key, Buffer.from(sig.sig, 'base64url'));
}
在 Python 中离线验证(3.8+,pip install cryptography;verify_pg1.py):
import base64, json, urllib.request
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
def verify_pg1(result, sig, jwks_url="https://pg1-ai-agent.vercel.app/.well-known/pg1-signing-key"):
clean = {k: v for k, v in result.items() if k != "signature"}
jwk = next((k for k in json.load(urllib.request.urlopen(jwks_url))["keys"] if k["kid"] == sig["kid"]), None)
if jwk is None or sig["alg"] != "EdDSA": return False
signed = json.dumps({"request_hash": sig["request_hash"], "result": clean, "sources": sig["sources"], "timestamp": sig["timestamp"], "version": sig["version"]}, sort_keys=True, separators=(",", ":"), ensure_ascii=False)
b64 = lambda s: base64.urlsafe_b64decode(s + "=" * (-len(s) % 4))
try: Ed25519PublicKey.from_public_bytes(b64(jwk["x"])).verify(b64(sig["sig"]), signed.encode("utf-8")); return True
except Exception: return False
使用结果及其签名块调用任一验证脚本。对于完整示例,传入示例 JWKS URL:verifyPg1(example.result, example.signature, "https://pg1-ai-agent.vercel.app/docs/signed-result-example-jwks.json") 会返回 true;更改结果中的任意字段都会返回 false。
Watchlist Webhook 使用 HMAC-SHA256 单独签名:X-PG1-Signature: t=<unix>,v1=<hex HMAC(secret, "<t>.<body>")>;应拒绝超过 5 分钟的投递。
免费层和速率限制
| 工具 | 费用 | 无许可证密钥时的限制 |
|---|---|---|
check_wallet_sanctions | 始终免费 | 每位调用者每小时 120 次调用 |
check_domain_age、check_hostname_reputation、check_wallet_age、check_package | 始终免费 | 每位调用者每个工具每小时 60 次调用 |
check_ip_abuse | 始终免费(使用你自己的 AbuseIPDB 配额) | 每位调用者每小时 60 次调用 |
check_x402_endpoint、check_agent_card | 始终免费 | 每位调用者每个工具每小时 60 次调用 |
verify_result | 始终免费 | 无 |
preflight_check、hosting_advisor | 付费:每次调用 0.01 USD | 每位调用者每天有 5 次免费调用,与其他付费工具共享,之后使用 x402 |
get_usage_status | 始终免费 | 无 |
get_ioc_context、get_ioc_batch | 未发现内容时免费;发现内容时付费 | 付费调用优先使用免费层 |
get_threat_indicators、GET /api/ioc(STIX 订阅源) | 免费(来自 NIST NVD 的 CVE 记录);不占用每天 5 次付费工具免费调用的额度(运营方可通过 PG1_FEED_PAID 开关将其设为付费) | 无 |
get_cve_details、get_cve_batch、get_cve_by_product、get_threat_actor_profile | 付费:每次调用 0.01 USD | 每位调用者每天有 5 次免费调用,所有这些工具共用,之后使用 x402 |
submit_indicator | 仅限许可证密钥(不支持 x402,也无免费层) | 无 |
| 测试固定数据(/docs/testing) | 始终免费 | 无限制,且不消耗免费调用次数 |
- 免费层无需请求头。 没有付款且未提供许可证密钥的调用者会自动使用免费层。响应中包含
X-Free-Tier-Limit和X-Free-Tier-Remaining。 - 发送
X-Free-Tier: 0可跳过免费层,直接获取付款质询。 - 在
X-API-KEY中提供许可证密钥即可解除每小时限制,并为付费调用付款。 - 触发速率限制的调用会返回带有
retry_after的rate_limited错误。
两种连接方式
/api/ioc— 简单的 REST GET,返回包含来自 NIST NVD 的 CVE 记录的 STIX 2.1 捆绑包(这是 PG1 目前唯一可以出于商业目的再分发的数据源;暂不包含 IP、域名、URL 或文件哈希指标)。免费(NIST NVD 的 CVE 记录);不占用每天 5 次的付费工具免费调用次数;无需密钥或付款。最适合脚本、curl 和简单集成。/api/mcp— 完整的模型上下文协议服务,包含 20 个工具(单次调用预检、托管顾问、CVE 查询、批量操作、威胁行为者档案、钱包制裁筛查、域名年龄、主机名/钓鱼信誉、钱包年龄/历史记录等)。最适合 Claude、兼容 MCP 的 Agent,以及任何使用 MCP 标准通信的客户端。
发现:/llms.txt(llmstxt.org 格式,供 AI Agent/爬虫使用)和 /openapi.json(/api/ioc 和 /api/health 的 OpenAPI 3.1 规范)。
选择启用:/api/ioc/context?value=<indicator> — get_ioc_context MCP 工具的 REST 镜像,默认禁用。运营方必须设置 ENABLE_REST_IOC_CONTEXT=true,此路由才会响应;否则会返回 404 {"error":"not available"}。不会列入 x402 Bazaar/发现元数据。
付费 MCP 工具可通过 x-api-key 标头接受 Gumroad 许可证密钥,也可通过 PAYMENT-SIGNATURE 标头接受按次支付的 x402 微支付(每次调用 $0.01,x402 v2)。运营方再次将数据源设为付费时(PG1_FEED_PAID=true),/api/ioc 也接受相同方式。
免费额度(每天 5 次调用)
免费额度自动生效:没有许可证密钥且未付款的调用方,在首次收到 402 Payment Required 之前,每天可免费调用付费工具 5 次。无需标头或注册,因此浏览器或 MCP 客户端的首次调用即可直接使用。
每位调用方共用一个计数器(对 IP 加盐哈希,绝不存储 IP 本身),由付费 MCP 工具(/api/mcp)和付费 A2A 技能(/api/a2a)共享:无论通过哪个路由调用,每天总计可免费调用付费工具 5 次。只有调用成功后才计数;HEAD 请求永不计数。每个免费额度响应都会附带 X-Free-Tier-Limit 和 X-Free-Tier-Remaining,get_usage_status 则会显示剩余额度。调用方一旦提供付款信息,就始终会被收费,不会获得免费服务。发送 X-Free-Tier: 0 可跳过免费额度,直接获取付款质询。User-Agent 中包含 x402 扫描器、爬虫或机器人的名称的请求(config/usageProbes.mjs)也会跳过免费额度,因此发现扫描器仍能看到其用于列出付费资源的 402 响应。
**STIX 数据源免费(NIST NVD 的 CVE 记录);不占用每天 5 次的付费工具免费调用次数。**任何人都可以调用 get_threat_indicators 和 GET /api/ioc:不会返回 402,无需许可证密钥,也不会计入每天 5 次的调用次数,即使设置了 X-Free-Tier: 0 或付款标头也不例外(不会收取费用)。运营方可设置 PG1_FEED_PAID=true 将数据源设为付费;此时该数据源会像其他付费工具一样使用免费额度和 x402。
curl "https://pg1-ai-agent.vercel.app/api/ioc"
可选查询参数:?since=<ISO timestamp>、?type=<IPv4|domain|URL|FileHash-MD5|FileHash-SHA1|FileHash-SHA256>、?min_score=<0-100>、?limit=<1-1000>
**置信度分数说明:**如果源记录没有 confidence_score,指标的 confidence 目前会默认设为固定值 50;这些记录的分数尚未经过计算或加权。
例外:get_ioc_context 和 get_ioc_batch(执行操作前的安全检查工具)在结果为 found: false 时始终免费;针对这些特定的“无记录”响应,无需 x-free-tier 标头。只有使用通用免费额度时才需要此标头。
支付 MCP 工具调用费用(x402 v2)
/api/mcp 遵循 x402 v2 MCP transport spec,用于处理付费的 tools/call 请求,因此可通过 MCP 原生字段或 HTTP 标头附加付款信息,具体取决于客户端库的支持情况:
-
params._meta["x402/payment"](推荐用于 MCP 客户端,例如@x402/mcp)——将已签名的 x402 v2PaymentPayload对象直接附加到 JSON-RPC 请求中:{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "get_cve_details", "arguments": { "cve_id": "CVE-2021-44228" }, "_meta": { "x402/payment": { "x402Version": 2, "scheme": "exact", "network": "eip155:8453", "accepted": { /* … */ }, "payload": { /* … */ } } } } } -
PAYMENT-SIGNATURE标头(或X-Payment)——同一已签名负载采用 base64 编码,并附加在 HTTP 传输层,而不是 JSON-RPC 请求中。这是非 MCP 感知型 HTTP 客户端付款的方式。
如果同一请求中同时提供两者,则以 _meta 为准。
未付款的调用不会收到 HTTP 402。 对于没有许可证密钥、没有免费套餐且未付款的付费工具 tools/call 请求,会返回一个常规的 200 OK JSON-RPC 结果,其格式为 MCP 工具错误:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"isError": true,
"structuredContent": { "x402Version": 2, "error": "Payment required", "resource": { /* … */ }, "accepts": [ /* … */ ] },
"content": [{ "type": "text", "text": "{\"x402Version\":2,...}" }]
}
}
为了向后兼容仅读取标头的客户端,同一对象也会以 base64 编码的形式通过 PAYMENT-REQUIRED 响应标头发送。验证或结算失败时,会返回完全相同的格式(仍为 200 OK,isError: true),并由 structuredContent.error 描述出错原因。
付款成功后,工具结果会在 result._meta["x402/payment-response"] 中包含支付服务商的结算回执,并像之前一样设置 PAYMENT-RESPONSE 标头。
安装与连接(MCP 客户端)
要将自主 Agent 连接到 PG1 API,请在连接请求中传入 Gumroad 许可证密钥。
选项 1:通过 Smithery CLI
在终端中运行此命令,并将占位符替换为有效密钥:
smithery mcp add --transport http --id pg1-threat-intel https://pg1-ai-agent.vercel.app/api/mcp --header "x-api-key: YOUR_GUMROAD_LICENSE_KEY"
选项 2:通过 curl 测试免费套餐(无需密钥)
curl -X POST https://pg1-ai-agent.vercel.app/api/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_cve_details",
"arguments": { "cve_id": "CVE-2021-44228" }
}
}'
所有可用的 MCP 工具
向 /api/mcp 调用 "method": "tools/list",即可获取完整架构。概要如下:
| 工具 | 用途 | 来源 | 是否适用免费额度? |
|---|---|---|---|
preflight_check | 在 Agent 付费、打开、安装、修补或信任另一个 Agent 之前调用一次:并行执行所有相关检查,给出一个决策(no_flags、flagged、unknown),默认拒绝 | PG1 自身的以下检查 | 是(每天 5 次免费调用,之后使用 x402)。REST:POST /api/preflight |
check_x402_endpoint | 在向 x402 端点付款之前检查该端点:payTo 制裁筛查和钱包年龄、网络和资产、TLS、域名年龄 | 以下检查,实时执行 | 始终免费(不提供许可证密钥时每小时 60 次调用) |
check_agent_card | 在信任另一个 Agent 之前检查它:A2A 卡片架构、域名年龄和信誉、相似名称 | 以下检查,实时执行 | 始终免费(不提供许可证密钥时每小时 60 次调用) |
verify_result | 根据已发布的密钥验证 PG1 结果的 Ed25519 签名 | /.well-known/pg1-signing-key | 始终免费 |
hosting_advisor | 按排名推荐托管区域和提供商,并附上法律、隐私和延迟方面的引用理由;不构成法律建议 | PG1 筛选并附有引用的精选数据集 | 是(每天 5 次免费调用,之后使用 x402)。REST:POST /api/hosting-advisor |
get_threat_indicators | 包含 CVE 记录(CVE ID 和 NVD 参考;目前尚无 IP/域名/URL/哈希指标)的 STIX 2.1 捆绑包 | NVD(仅限 PG1 可进行商业再分发的来源;见 数据源开关) | 否:免费(来自 NIST NVD 的 CVE 记录);不占用每天 5 次免费付费调用额度(PG1_FEED_PAID 可将其设为付费) |
get_ioc_context | 检查单个指标的安全性 | NVD(见 数据源开关) | 未找到时始终免费 |
get_ioc_batch | 每次调用最多处理 20 个指标 | NVD(见 数据源开关) | 全部未找到时始终免费 |
get_cve_details | 查询 CVE 并补充 NVD、CISA KEV 数据(仅当启用 PG1_SOURCE_EPSS_PAID 时提供 EPSS) | NVD、CISA KEV | 是(每天 5 次免费调用,之后使用 x402) |
get_cve_batch | 每次调用最多处理 20 个 CVE ID | NVD、CISA KEV(EPSS 规则同上) | 是(每天 5 次免费调用,之后使用 x402) |
get_cve_by_product | 按供应商/产品查找 CVE | NVD | 是(每天 5 次免费调用,之后使用 x402) |
get_threat_actor_profile | 提供 APT/威胁行为者档案及 MITRE ATT&CK 信息 | MITRE ATT&CK Enterprise | 是(每天 5 次免费调用,之后使用 x402) |
get_usage_status | 查看剩余的免费额度 | — | 始终免费,无需请求头 |
submit_indicator | 提交观察到的指标以供审核 | — | 否——需要许可证密钥 |
check_wallet_sanctions | 根据制裁名单筛查钱包地址 | OFAC SDN List(美国财政部),每日同步 | 始终免费(不提供许可证密钥时每小时 120 次调用) |
check_domain_age | 通过 RDAP 查询域名注册时长 | RDAP(按顶级域名划分的服务器,通过 IANA 引导注册表解析) | 始终免费 |
check_hostname_reputation | 筛查主机名是否涉及网络钓鱼/仿冒域名 | MetaMask eth-phishing-detect,每日同步 | 始终免费(不提供许可证密钥时每小时 60 次调用) |
check_wallet_age | 通过链上转账历史查询 EVM 地址首次出现在某条链上的时间 | 链上转账历史(按链划分) | 始终免费(不提供许可证密钥时每小时 60 次调用) |
check_ip_abuse | 使用你自己的 AbuseIPDB 密钥,查询单个公网 IP 的滥用置信度评分和举报次数 | AbuseIPDB,实时查询,使用你通过 X-AbuseIPDB-Key 发送的密钥 | PG1 不收费;使用你自己的 AbuseIPDB 额度(不提供许可证密钥时每小时 60 次调用)。见使用自己的 AbuseIPDB 密钥 |
check_package | 安装前检查单个 npm 或 PyPI 软件包:是否存在、年龄、是否被报告为恶意、已知漏洞、相似名称、npm 弃用状态和安装脚本 | npm 公共注册表/PyPI,以及 OSV.dev(OpenSSF Malicious Packages、GitHub Advisory Database、PyPI Advisory Database);见 /docs/attributions | 始终免费(不提供许可证密钥时每小时 60 次调用)。见安装前检查软件包 |
subscribe_alerts 为不可用状态(不在 tools/list 中;调用会返回 not_available,免费)。如需接收提醒,请使用监控列表:POST /api/watchlists,通过 x402 支付每项 0.05 USD,有效期为 30 天;状态每次变更时都会发送签名 Webhook。 |
重要措辞注意事项
check_wallet_sanctions:结果为listed: false,表示截至报告的list_last_synced时间,该地址不在 OFAC SDN 名单上。此结果仅供参考,不构成法律或制裁合规建议,也绝不会表述为“安全”或“干净”。如果制裁数据为空或无法访问,工具会返回错误,而不是返回listed: false。地址验证:工具会先使用(规范化后的)地址查询public.sanctioned_wallets——只要匹配,就始终返回listed: true,即使该地址不符合当前认可的格式。只有在没有匹配项时,工具才会进行格式检查:如果address与制裁名单中任何币种的认可格式都不匹配(EVM:0x+ 40 位十六进制字符;BTC/LTC/BCH/DOGE/DASH/ZEC:base58 或 bech32/CashAddr;TRON;Monero;Solana:base58),工具会返回 MCP 工具错误(isError: true,code: "invalid_address"),而不是返回listed: false——这适用于"hello"这类格式错误的输入,或长度不正确的0x地址。空address始终会在查询前被拒绝,并返回invalid_address。该工具免费使用;未提供 Gumroad 许可证密钥时,每位调用者每小时最多可调用 120 次(按 IP 限制,/api/mcp和/api/a2a共用一个计数器);该小时内第 121 次调用会返回与check_wallet_age相同的rate_limited工具错误,且夹具输入不计入次数。check_domain_age:对于新注册的域名(age_days < 30),工具会将其报告为常见的钓鱼信号,而非恶意意图的证明。查询成功时,工具会返回found: true(并为向后兼容返回available: true——available已弃用,请优先使用found)。查询无法解析时,工具会返回found: false/available: false,并附带reason和reason_code:当 TLD 在 IANA 引导注册表中没有 RDAP 服务器时为"unsupported_tld";RDAP 查询超时时为"timeout";其他失败情况则为"invalid_domain"``/"bootstrap_unavailable"``/"lookup_failed"。工具绝不会猜测域名年龄,也绝不会回退到 WHOIS。get_ioc_context/get_ioc_batch(现有行为):结果为found: false,表示 PG1 的来源中没有记录任何不良信息——这不意味着该指标安全,只表示它不在此数据集中。check_hostname_reputation:接受单个不带修饰的主机名(不接受批量输入、URL/方案/路径/端口/通配符),并将其及其所有父域名与public.phishing_domains(阻止名单/允许名单/模糊匹配名单,由 sovereign-threat-pipeline repo 每日同步)和public.phishing_list_meta进行比对。返回verdict: "allowlisted" | "listed" | "lookalike" | "not_listed"——绝不会返回"safe"或"clean"。允许名单匹配始终优先于阻止名单匹配。"listed"verdict 会报告match_type: "exact"或"parent_domain"。"lookalike"verdict 表示该主机名未被直接列出,但与模糊匹配名单中的已知品牌域名相似——可能是混淆字符/拼写错误构成的字符骨架在存储的容差范围内(默认值为 3),也可能是品牌关键词(至少 5 个字符)与其他词语组合嵌入其中(例如metamask-login.com);此时lookalike_of会设为匹配到的品牌域名。品牌自身的真实域名及其子域名绝不会被标记。如果无法访问钓鱼名单数据或查询超时,工具会返回错误,而不会报告not_listed。格式错误的主机名输入会返回 MCP 工具错误(isError: true,code: "invalid_hostname")。除单个匹配项外,绝不公开名单内容。该工具免费使用;未提供 Gumroad 许可证密钥时,每位调用者每小时最多可调用 60 次;许可证密钥(X-API-KEY)可绕过此限制。check_wallet_age:根据给定链上最早的转入或转出记录,报告 EVM 地址(0x+ 40 位十六进制字符,不区分大小写)首次出现在该链上的时间(默认链为base,也可以是ethereum/arbitrum/optimism/polygon/bsc),并报告该地址是否为合约(is_contract)。地址年龄按链计算:first_seen/age_days仅描述该地址在所请求chain上的历史记录,因此同一地址在一条链上可能已经存在很久,在另一条链上却是全新地址(或found: false)——请检查你关注的每条链。结果为found: false(除is_contract外,其余字段均为null)表示该地址在该链上没有转账记录——这是正常且常见的结果,不是错误,也不能作为该地址安全或不安全的证据;此工具仅报告年龄和历史记录。上游故障或超时会返回 MCP 工具错误(isError: true,code: "upstream_unavailable"),而不会回退到found: false,因为数据源中断绝不能被误读为“全新钱包”。格式错误的address/chain输入会返回 MCP 工具错误(code: "invalid_address"/"invalid_chain")。found结果会永久缓存;found: false结果只缓存 10 分钟。该工具免费使用;未提供 Gumroad 许可证密钥时,每位调用者每小时最多可调用 60 次,与check_domain_age/check_hostname_reputation的限制相同。自 1.14.0 起,缓存结果也计入此限制,因为每次调用仍会执行实时委托检查;许可证密钥仍可让调用者免受此限制。- EIP-7702 委托(
delegated、delegate_address),在 1.14.0 中作为可选字段添加:当该地址在所请求链上的代码恰好为 23 个字节,即0xef0100后接 20 字节委托地址(EIP-7702 委托)时,delegated: true,并将该地址转换为小写后放入delegate_address。当代码为其他任何内容时(空代码、普通合约,或长度不正确但看起来带有此前缀的内容),delegated: false(且delegate_address: null)。delegated: null表示代码检查未完成(超时或上游错误)。工具绝不会猜测为false;年龄结果仍会返回,且status为"unknown"。委托检查始终有自己的checks条目,source: "on-chain code",其result为"ok"、"error"或"timeout",以便查看检查是否完成。委托状态绝不缓存:所有者可以随时添加或移除委托,因此每次调用都会实时检查,包括返回缓存年龄结果的调用;first_seen仍按原样缓存。已委托地址会获得原因代码WALLET_DELEGATED,仅陈述事实,不作判断。此信息仅供参考,不会单独改变status:较早的已委托钱包会返回status: "no_flags",且reasons: [WALLET_DELEGATED];较早的非委托钱包则同样返回status: "no_flags",且reasons: []。status始终与未考虑委托时的结果相同;如果代码检查未完成,则为"unknown"。例如,无论是否委托,查询不完整的较早钱包(WALLET_AGE_PARTIAL)都会返回"unknown";而没有历史记录的钱包无论委托状态如何都会返回"flagged"。is_contract未变更,已委托地址仍会返回true,因此现有集成的行为保持不变。委托状态也按链区分:一条链上的委托状态不能说明另一条链上的情况。
- EIP-7702 委托(
check_package:绝不使用“安全”或“干净”的说法。对于恶意软件包的报告,始终表述为**“报告为恶意”**:来源数据可能包含误报。注册表查询失败时,exists: null(绝不会是false),且status: "unknown"。请参阅安装前检查软件包。check_wallet_sanctions/check_domain_age/check_hostname_reputation/check_wallet_age均声明了outputSchema,并按照 MCP 规范在现有content文本块旁返回匹配的structuredContent对象——支持结构化工具输出的客户端可以直接读取字段,无需解析文本块。
数据源开关
威胁指标数据(get_threat_indicators、get_ioc_context、get_ioc_batch、/api/ioc、/api/ioc/context,以及基于这些数据的聊天和 playground 检查)会在每次查询时统一通过 lib/sourcePolicy.mjs 按上游来源过滤。这些是付费响应,因此只有 PG1 可以转售的数据源才会提供:我们自己的数据、公共领域数据,或条款明确允许商业转售的数据源。
| 变量 | 默认值 | 涵盖范围 |
|---|---|---|
SOURCE_ABUSECH_ENABLED | 始终关闭(已锁定;忽略该变量) | abuse.ch(ThreatFox、URLhaus、MalwareBazaar、Feodo、SSLBL、YARAify)。取得许可前,不会在付费 API 中提供。 |
SOURCE_OTX_ENABLED | 始终关闭(已锁定) | AlienVault OTX。没有商业许可。 |
SOURCE_ABUSEIPDB_ENABLED | 始终关闭(已锁定) | 标记为 AbuseIPDB 的行。PG1 拒绝了 AbuseIPDB 的许可;check_ip_abuse 始终只使用调用方自己的密钥。 |
SOURCE_UNATTRIBUTED_ENABLED | 始终关闭(已锁定) | 没有来源标签的行,以及旧流水线中标记为 Sovereign-Engine-v3.2-*、会隐藏真实数据源的行。没有记录来源就表示未获许可。 |
SOURCE_NVD_ENABLED | 开启 | NIST NVD(美国政府作品,属于公共领域)。 |
SOURCE_BLOCKLIST_DE_ENABLED、SOURCE_PG1_SWARM_ENABLED、SOURCE_SCAMSNIFFER_ENABLED、SOURCE_OTHER_ENABLED | 关闭 | Blocklist.de、PG1-Swarm-* 标签、ScamSniffer,以及任何其他标签。在确认其条款允许商业转售前保持关闭;只有确认后才能设为 true。 |
只有通过代码变更才能重新提供已锁定的数据源;此类变更须在签署许可后进行。
付费 CVE 响应中的 EPSS。 FIRST 将 EPSS 分数提供给“公众免费使用”,但尚未书面确认允许转售,因此付费 CVE 响应(通过 MCP 或 A2A 调用 get_cve_details、get_cve_batch、get_cve_by_product,无论是通过 x402、许可密钥还是免费层付费)都会排除 EPSS,也绝不会为此调用 FIRST:不返回 epss 字段、不进行 EPSS 检查,也不扣除 EPSS 额度。PG1_SOURCE_EPSS_PAID=true 可重新启用;只有在 FIRST 书面确认允许转售后才能设置。免费响应(PG1 聊天)仍会提供 EPSS。
STIX 数据流的价格。 get_threat_indicators 和 /api/ioc 免费(CVE 记录来自 NIST NVD);不占用每天 5 次免费付费调用额度。设置 PG1_FEED_PAID=true 后,它们将变为付费(每次调用 0.01 USD,优先使用共享免费层);同时将 /api/ioc 重新加入 public/.well-known/x402,并在 public/openapi.json 中为其两个操作添加 x-payment-info(node scripts/verify-payment-config.mjs 会检查这一点)。
绝不存储许可密钥。 api_access_logs 会将许可密钥调用方记录为 license:<HMAC>(使用 TELEMETRY_IP_SALT 加盐,并与 IP 哈希进行域分离),将免费层调用方记录为 free-tier:<IP hash>,将免费数据流记录为 free-feed;数据库检查约束会拒绝其他值。
threat_indicators。 旧版 threat_indicators 表(没有 source_id 且 stix_data 中没有任何数据的行)绝不会由付费路由读取;只有运营方自己的聊天上下文和仅供运营方使用的诊断端点会读取该表。tests/phase2-funnel.test.mjs 会对此进行固定验证。
已关闭数据源中的行绝不会出现在任何响应中,无论免费还是付费;如果某个指标仅存在于此类数据源中,则会报告为 found: false。
A2A(Agent2Agent Protocol)
/api/a2a 通过 A2A 和 JSON-RPC 2.0 提供十项始终免费的技能(check_wallet_sanctions、check_domain_age、check_hostname_reputation、check_wallet_age、check_package、check_x402_endpoint、check_agent_card、verify_result、get_usage_status 和 check_ip_abuse;与 /api/mcp 一样,调用该技能需要在 X-AbuseIPDB-Key 标头中提供你自己的密钥),以及六项付费技能:preflight_check、hosting_advisor、get_cve_details、get_cve_batch、get_cve_by_product 和 get_threat_actor_profile(每次调用 0.01 美元)、付费任务(submit_job)和委托工具(build_tool)。如果调用者还有免费调用次数,付费技能就免费提供(自动使用上文所述的共用每日 5 次计数);用完后,则需使用许可密钥(X-API-KEY)或通过 x402 付款。付款遵循 a2a-x402 扩展:未付款的调用会返回状态为 input-required 的任务,其状态消息元数据包含 "x402.payment.status": "payment-required",而 "x402.payment.required" 中包含 x402 v2 PaymentRequired 对象;请在 message.metadata["x402.payment.payload"] 中附上签名后的 PaymentPayload 重新发送消息。只有技能成功后才会结算付款,收据会在 "x402.payment.receipts" 中返回。NVD CVE 信息源和记录查询仍由 /api/mcp 提供。Agent 卡片发布在 /.well-known/agent-card.json。message/send(v0.3 的方法名称)可作为 SendMessage 的别名使用。A2A-Version 标头(或查询参数)用于选择响应格式:1.0 或 0.3(省略时的默认值)。速率限制由 MCP 工具自身执行,且使用相同的计数器:例如,不使用许可密钥时,check_wallet_sanctions 对每位调用者(按 IP)每小时最多允许调用 120 次,该小时内第 121 次调用会返回与 check_wallet_age 相同的 rate_limited 错误。请将技能及其参数作为 DataPart 发送:
curl -X POST https://pg1-ai-agent.vercel.app/api/a2a \
-H "Content-Type: application/json" \
-H "A2A-Version: 1.0" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "SendMessage",
"params": {
"message": {
"role": "user",
"messageId": "1",
"parts": [{ "kind": "data", "data": { "skill": "check_domain_age", "arguments": { "domain": "example.com" } } }]
}
}
}'
使用你自己的 AbuseIPDB 密钥
check_ip_abuse(MCP 工具和 A2A 技能,自 1.16.0 起提供)使用你自己的 AbuseIPDB API 密钥(免费或付费),在 AbuseIPDB 上查询一个公共 IPv4 或 IPv6 地址。该工具在与 AbuseIPDB 达成的协议下运行,条款如下:
- 只能使用你自己的密钥。 在
/api/mcp或/api/a2a的 HTTP 请求标头中通过X-AbuseIPDB-Key发送。它不会作为工具参数传入(参数会进入模型上下文和日志)。PG1 没有自己的 AbuseIPDB 密钥,也不会使用其他密钥:如果没有标头,就不会调用 AbuseIPDB,工具会返回带有代码abuseipdb_key_required的isError: true。 - 结果仅供你使用,且始终注明来源:每个结果都包含
attribution: { "text": "Data from AbuseIPDB", "url": "https://www.abuseipdb.com/check/<ip>" }。 - 仅按密钥缓存:在内存中缓存 15 分钟,键为
sha256(your key) + ip + max_age_in_days。绝不会存入数据库,也绝不会提供给其他人。绝不会存储、记录或返回原始密钥。 - 绝不共享:结果绝不会进入 PG1 的信息源、
get_ioc_context、get_threat_indicators或处理流水线。 - PG1 不收费(无需 x402 付款);查询会计入你自己的 AbuseIPDB 配额。此外,PG1 的常规限制仍然适用:没有 Gumroad 许可密钥时,每位调用者每小时最多调用 60 次。
请从你的 AbuseIPDB 账户获取密钥:https://www.abuseipdb.com/account/api。
curl -X POST https://pg1-ai-agent.vercel.app/api/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "X-AbuseIPDB-Key: $ABUSEIPDB_KEY" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"check_ip_abuse","arguments":{"ip":"8.8.8.8","max_age_in_days":90}}}'
通过 A2A 发起相同调用:
curl -X POST "https://pg1-ai-agent.vercel.app/api/a2a?A2A-Version=1.0" \
-H "Content-Type: application/json" \
-H "X-AbuseIPDB-Key: $ABUSEIPDB_KEY" \
-d '{"jsonrpc":"2.0","id":1,"method":"SendMessage","params":{"message":{"messageId":"abuse-1","role":"ROLE_USER","parts":[{"data":{"skill":"check_ip_abuse","arguments":{"ip":"8.8.8.8"}}}]}}}'
参数:ip(必填,必须且只能是一个公共 IPv4 或 IPv6 地址;私有地址、保留地址、文档示例地址和格式错误的输入都会被拒绝,并返回 invalid_ip,不会调用 AbuseIPDB)以及 max_age_in_days(可选,范围为 1 到 365,默认值为 90)。
结果(也会以 structuredContent 的形式提供;该工具声明了 outputSchema):ip、ip_version、max_age_in_days、abuse_confidence_score(0-100)、total_reports、distinct_reporters、last_reported_at、country_code、usage_type、isp、domain、is_tor、is_whitelisted、cached、note、attribution,以及常见的 reasons、status、checks 和 request_id。status 依据 AbuseIPDB 对报告的判定,不会额外应用 PG1 分数阈值(你可以自行设定 abuse_confidence_score 的阈值):
| 上游答复 | status | 原因 |
|---|---|---|
is_whitelisted 为 true(无论分数或报告数量如何) | "no_flags" | IP_WHITELISTED(信息性):AbuseIPDB 将该地址标记为已列入白名单,不会将针对该地址的报告计入 |
未列入白名单,abuse_confidence_score 大于 0 | "flagged" | IP_ABUSE_REPORTED,包含分数、报告数量和报告者数量 |
| 未列入白名单,分数为 0,时间范围内有报告 | "no_flags" | IP_REPORTS_SCORED_ZERO(信息性):报告确实存在,但 AbuseIPDB 给出的分数为 0 |
| 时间范围内没有报告 | "no_flags" | 无 |
| 缺少分数或报告数量 | "unknown" | 无 |
IP_TOR_EXIT_NODE 为信息性标记,可与以上任一情况同时出现。abuse_confidence_score 是 AbuseIPDB 对该地址具有恶意的 0-100 置信度;分数为 0 并不能证明该地址无害,PG1 也绝不会将结果称为“安全”或“干净”。如果时间范围内有报告,checks[0].data_as_of 就是 last_reported_at。
错误(MCP isError: true,带有 code;A2A JSON-RPC 错误 -32000,带有 error.data.code):
| 代码 | 情况 | 是否调用 AbuseIPDB? |
|---|---|---|
abuseipdb_key_required | 没有 X-AbuseIPDB-Key 标头 | 否 |
invalid_abuseipdb_key | AbuseIPDB 返回 401/403,或标头不能作为密钥(包含空格、控制字符,或长度超过 256 个字符) | 仅第一种情况 |
abuseipdb_rate_limited | AbuseIPDB 返回 429(你的 AbuseIPDB 配额已用尽)。AbuseIPDB 若提供 retry_after(秒)和 Retry-After 响应标头,则会原样传递 | 是 |
upstream_unavailable | AbuseIPDB 返回 5xx、答复无法读取,或 5 秒内没有答复 | 是 |
invalid_ip | 不是恰好一个公网 IPv4/IPv6 地址 | 否 |
invalid_max_age | max_age_in_days 不是 1 到 365 之间的整数 | 否 |
rate_limited | 未提供许可证密钥的调用者,每小时 PG1 调用次数上限为 60 次 | 否 |
浏览器:X-AbuseIPDB-Key 仅在 /api/mcp 和 /api/a2a 的 CORS Access-Control-Allow-Headers 中。聊天和 Playground 均不会提供此工具。
安装前检查软件包
check_package(MCP 工具、A2A 技能、聊天工具和 Playground 检查,自 1.17.0 起提供)是一项安装前检查,用于检查一个 npm 或 PyPI 软件包,面向即将安装或推荐软件包的 AI Agent。该工具免费(每位调用者每小时 60 次,无需许可证密钥),且不会调用任何 AI 模型。
参数:ecosystem("npm" 或 "pypi")、name(一个软件包;npm 名称可以带作用域,如 @scope/name),以及可选的 version(一个精确版本;不提供时会检查最新版本)。
信号均来自经过许可证审查的公开来源(完整列表和许可证见 /docs/attributions):
| 信号 | 字段 | 来源 |
|---|---|---|
| 软件包(及版本)是否存在? | exists、version_exists | npm 公共注册表 / PyPI |
| 发布时间 | first_published、age_days、latest_version、latest_published | npm 公共注册表 / PyPI |
| 被报告为恶意 | reported_malicious、malicious_reports(MAL- ID) | OpenSSF Malicious Packages(Apache-2.0),通过 OSV.dev |
| 该版本的已知漏洞 | vulnerabilities(仅含 id、severity、cvss_vector) | GitHub Advisory Database、PyPI Advisory Database(CC-BY 4.0),通过 OSV.dev |
| 模仿热门软件包的名称 | lookalike_of、lookalike_pattern(separator、confusable、affix、edit_distance) | PG1 自有热门名称列表 |
| 仅限 npm:已弃用、安装脚本 | deprecated、deprecation_message、install_scripts | npm 公共注册表 |
状态遵循 PG1 的常规规则:
"flagged":版本被报告为恶意(PACKAGE_REPORTED_MALICIOUS)、软件包或请求的版本不存在(PACKAGE_NOT_FOUND、PACKAGE_VERSION_NOT_FOUND),或者软件包首次发布距今不足 30 天 且 名称看起来像热门软件包(PACKAGE_NEW_LOOKALIKE)。"unknown":任一查询未能完成:注册表查询失败时返回exists: null,绝不会返回false;OSV 查询失败时返回reported_malicious: null。"no_flags":其他情况。仅名称相似、仅为新软件包、已知漏洞、弃用状态和安装脚本都是仅供参考的信息,不会单独触发标记。绝不会使用“安全”或“无问题”这样的判定。
仅显示 /docs/attributions 中所列数据库的安全公告;OSV 返回的其他内容均计入 vulnerabilities_omitted。绝不使用特定发行版(例如 Ubuntu)的数据。注册表响应缓存 1 小时,OSV 响应(其中包含恶意状态)按软件包缓存 15 分钟;查询使用较短超时时间,每次请求只查询一个软件包,绝不进行批量爬取。输入不会被存储:遥测只记录工具名称、结果、延迟,以及经过加盐处理的调用者哈希值。
curl -X POST https://pg1-ai-agent.vercel.app/api/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"check_package","arguments":{"ecosystem":"npm","name":"lodash","version":"4.17.21"}}}'
在聊天中让 PG1 执行检查
已登录的操作员可以用普通措辞让 PG1 聊天执行上述只读工具:“检查这个钱包 0x…”、“这个域名有多老”、“这个主机名是否是仿冒域名”、“你对 CVE-2021-44228 了解多少”。聊天模型会将只读 MCP 工具作为原生函数提供(由与 tools/list 相同的工具列表和架构生成,并按角色筛选),每条消息最多运行 5 个工具(相互独立时并行运行),然后根据结果生成答复。每次调用都会运行 MCP 客户端调用的同一处理程序,绝不会向 /api/mcp 发送 HTTP 请求。
- 可运行的工具:
check_wallet_sanctions、check_domain_age、check_hostname_reputation、check_wallet_age、get_ioc_context、get_ioc_batch、get_cve_details、get_cve_batch、get_cve_by_product、get_threat_actor_profile。绝不运行submit_indicator(会写入数据)、get_threat_indicators(付费批量数据源,并非检查)、get_usage_status(调用者自己的配额)或check_ip_abuse(仅当请求标头中包含调用者自己的 AbuseIPDB 密钥时才会运行;聊天没有该密钥,PG1 自己也没有 AbuseIPDB 密钥)。聊天执行的操作不会写入数据、产生费用或更改状态。 - 操作员免费使用,与许可证持有者一样:不受 PG1 速率限制,但每个上游数据源自身的超时和缓存规则仍然适用,并且每次调用都有独立的超时时间(10 s)。每次调用都会记录一个
request_id,上游失败或超时会像 MCP 一样记录到对应的错误日志中。工具列表和限制是按角色配置的策略(lib/chatTools.mjs),因此未来的访客角色也可在匿名速率限制下免费使用check_*工具。 - 如实答复: 回复会引用每项结果的
status(flagged、no_flags、unknown)和reasons;no_flags绝不代表“安全”。无论模型写了什么,失败、超时或返回unknown的检查都会在回复末尾注明,并附上其request_id和代码。 - 追踪记录和卡片: 实时追踪记录会为每次调用显示一行(例如“已检查钱包年龄 · 0x12ab…9f3c · 无标记”,并显示耗时;失败时使用错误颜色)。回复下方会为每项结果显示一张卡片:工具名称(普通措辞)、状态标签、关键字段、原因、带
data_as_of的检查、request_id,以及带复制按钮的 Raw JSON 展开器(标题中的地址会缩短,展开器中则显示完整地址)。 - 语音: 开启语音回复后,执行过检查的回复会朗读简短摘要(每项检查的状态和主要原因),绝不朗读地址、哈希或 JSON。
- 无需调用上游的演示: 以下固定数据也可在聊天中使用,例如“检查这个钱包 0x7067312d746573742d6669787475726500000001”或“pg1-test-clean.invalid 有多老”;卡片会标记为“fixture”。

响应元数据(reasons、status、checks、request_id)
每个 MCP 工具和每个免费 A2A 技能都会在现有输出中额外添加四个字段——仅作增补,不会重命名或重新定义任何现有字段:
reasons:[{ code, message }]。包含下方永久列表中的零个或多个机器可读代码。没有需要标记的内容时为空。代码只会添加,不会删除或重命名。status:当reasons包含真正的警告代码时为"flagged";否则,当reasons包含不完整代码,或任何答案所需的数据源超时、出错或被跳过时为"unknown"(绝不会错误地报告为"no_flags");其他情况为"no_flags"。reasons中列出的两类代码并非警告。信息性代码(WALLET_DELEGATED、IP_TOR_EXIT_NODE、IP_WHITELISTED、IP_REPORTS_SCORED_ZERO)用于报告事实,不会影响status。不完整代码(目前只有WALLET_AGE_PARTIAL)表示某项检查未完成,因此会使status变为"unknown",而不是"flagged"。对于check_wallet_age,这意味着:只有存在WALLET_NO_HISTORY时才为"flagged";否则,如果有任何检查未完成(WALLET_AGE_PARTIAL或delegated: null),则为"unknown";否则为"no_flags"。(submit_indicator保留其原有的status字段,该字段表示提交生命周期状态,而非此处的状态值——它只会新增reasons/checks/request_id。)checks:[{ source, result, checked_at, data_as_of }]——本次调用查询的每个数据源各有一条记录。result为"ok" | "timeout" | "error" | "skipped"之一。source始终是通用标签(例如"制裁名单"、"域名注册记录"、"链上转账历史")——绝不会使用供应商名称。checked_at是本次请求执行检查的时间;data_as_of表示底层数据的时效,或在不适用时为null。对于check_wallet_age,缓存结果中的"on-chain transfer history"条目的data_as_of为最初查询该年龄的时间(新查询则为null),而"on-chain code"条目对应实时委托检查。request_id:用于标识本次特定调用的 UUID,也会作为/api/mcp和/api/a2a的X-Request-Id响应标头发送。该字段位于工具结果(以及structuredContent)中;对于 JSON-RPC 错误,则位于error.data中——绝不会出现在 JSON-RPC 信封的顶层,因为顶层只包含jsonrpc、id和result/error。如果调用失败并被写入服务器错误日志,同一个request_id也会附加到该日志条目中。
check_wallet_sanctions、check_domain_age、check_hostname_reputation 和 check_wallet_age 也会在其 outputSchema 中将这四个字段声明为可选属性(绝不会加入 required,且其架构的其他部分保持不变)。它们还会声明一个可选布尔属性 test_fixture,该属性仅出现在针对 测试你的集成 中所述 fixture 输入的响应中(且值为 true)。check_wallet_age 还会声明两个可选的委托属性:delegated(boolean | null)和 delegate_address(string | null);它们不在 required 中(参见上文 check_wallet_age 说明)。
原因代码
| 代码 | 含义 |
|---|---|
WALLET_SANCTIONED | 地址与制裁名单中的条目匹配。 |
DOMAIN_NEWLY_REGISTERED_30D | 域名注册时间不足 30 天。 |
HOSTNAME_PHISHING_LISTED | 主机名或其父域名位于网络钓鱼屏蔽名单中。 |
HOSTNAME_LOOKALIKE | 主机名很可能是知名品牌域名的仿冒或拼写混淆域名。 |
WALLET_NO_HISTORY | 未发现该地址在此链上的链上转账记录。 |
WALLET_AGE_PARTIAL | 未能及时检查内部转账;该钱包可能比显示的时间更早。(不完整:会将 status 设为 "unknown",而非 "flagged"。) |
CVE_KNOWN_EXPLOITED_KEV | 该 CVE 已列入已知遭利用漏洞目录。 |
IOC_FOUND_IN_THREAT_FEED | 威胁指标源中至少有一条与该指标匹配的记录。 |
WALLET_DELEGATED | 此地址当前在此链上有 EIP-7702 委托:其代码指向一个委托合约。(仅供参考:不会单独改变 status。) |
IP_ABUSE_REPORTED | 根据已检查的报告时间窗口内的报告,该 IP 地址的滥用置信度评分高于 0。 |
IP_TOR_EXIT_NODE | 该 IP 地址是 Tor 出口节点。(仅供参考:不会单独改变 status。) |
IP_WHITELISTED | 滥用报告来源已将该 IP 地址列入白名单,因此不会将针对它的报告计入统计。(仅供参考:不会单独改变 status。) |
IP_REPORTS_SCORED_ZERO | 已检查的报告时间窗口内有针对该 IP 地址的滥用报告,但其滥用置信度评分为 0。(仅供参考:不会单独改变 status。) |
权威来源:lib/reasonCodes.mjs。
尚未覆盖: /api/ioc REST 信息流和 /api/ioc/context 目前尚未提供 reasons/status/checks/request_id。
测试你的集成
每个可以标记某项内容的 MCP 工具都有 3 个固定的虚构测试输入,它们始终返回相同的答案:一个 FLAGGED、一个 CLEAN 和一个 UNKNOWN。少数工具还多提供一个值得测试的第二种情况:check_wallet_age 的 DELEGATED、check_hostname_reputation 的 LOOKALIKE(仿冒名称,而非已列出的主机名)、check_package 的 MISSING(一个不存在的软件包,例如助手编造的名称),以及 get_ioc_batch / get_cve_batch 的 MIXED(一个已标记条目和一个未标记条目,以便检查你是否逐个读取条目,而非只看批次状态)。使用这些输入测试集成的正常流程、“已标记”流程以及跳过/重试流程,无需花费任何费用,也不依赖实时数据。
-
始终免费,适用于所有调用方:无需许可证密钥、
x-free-tier标头、x402 付款,也不消耗速率限制额度。付费工具也适用。 -
响应结构与真实响应一致:包含
reasons、status、checks和request_id,以及test_fixture: true。每个checks[]条目都包含source: "fixture"。对于错误格式的 UNKNOWN,test_fixture: true位于error.data(JSON-RPC 错误)中,或位于code旁边(isError 工具结果)。 -
UNKNOWN 与该工具在真实上游故障时返回的结果完全一致,因此你可以测试跳过流程。对于
check_wallet_age,这会返回upstream_unavailableisError 结果,绝不会是found: false。 -
对于
check_domain_age,始终先检查status,再检查found:found: false且status: "unknown"表示查询未完成,并不表示该域名是新注册的。 -
仅匹配精确值。 唯一的规范化处理是工具本身已有的处理:将
0x地址或主机名转换为小写、将 CVE id 转换为大写、将域名/URL 缩减为可注册域名。其他任何输入都会被视为真实输入,即使只差一个字符也一样,因此www.pg1-test-flagged.invalid会被当作真实主机名进行查询。 -
所有值均为保留值或合成值,因此不可能属于真实目标:
.invalid域名(RFC 2606/6761)、文档用途 IP 地址范围(RFC 5737192.0.2.0/24、198.51.100.0/24、203.0.113.0/24;RFC 38492001:db8::/32)、CVE-0000-*id(CVE 计划始于 1999 年),以及以十六进制拼出pg1-test-fixture的0x地址。 -
check_wallet_age没有年龄阈值。其 FLAGGED 测试输入是一个没有历史记录的钱包(found: false、WALLET_NO_HISTORY),CLEAN 测试输入是一个具有固定first_seen时间的旧钱包。其 DELEGATED 测试输入是一个启用了 EIP-7702 委托的旧钱包:delegated: true、合成的delegate_address(同样以十六进制拼出pg1-test-fixture),以及原因WALLET_DELEGATED,状态为status: "no_flags",因为该代码仅提供信息。与真实答案一样,它包含两个checks条目(转账历史,然后是委托检查),二者的source都是"fixture",result都是"ok"。其他测试输入的delegated均为false。chain是可选的,会原样返回;不受支持的链仍会返回invalid_chain错误。 -
check_package使用以_开头的名称,npm 和 PyPI 都不接受这类名称,因此测试输入不可能对应真实软件包;实时路径会将它们拒绝为invalid_package_name。这 3 个名称在"ecosystem": "npm"或"pypi"下均可使用,不会调用上游,其数据为合成数据(报告 idMAL-0000-0001不可能被签发)。version是可选的,会原样返回。 -
check_ip_abuse使用文档用途 IPv4 地址,实时路径会将其拒绝为invalid_ip(它们是保留地址,绝非公网地址),因此测试输入不可能变成真实查询。测试输入会在密钥检查之前得到响应:无需X-AbuseIPDB-Key标头,也不会调用上游。其数据为合成数据,attribution.text会说明这一点。max_age_in_days是可选的,会原样返回。
测试输入表
| 工具 | Fixture | 参数 | 预期结果 |
|---|---|---|---|
check_wallet_sanctions | FLAGGED | {"address":"0x7067312d746573742d6669787475726500000001"} | listed: true,status "flagged",reason WALLET_SANCTIONED |
check_wallet_sanctions | CLEAN | {"address":"0x7067312d746573742d6669787475726500000002"} | listed: false,status "no_flags" |
check_wallet_sanctions | UNKNOWN | {"address":"0x7067312d746573742d6669787475726500000003"} | HTTP 503,JSON-RPC 错误 -32003 "制裁数据暂时不可用,请重试。" |
check_domain_age | FLAGGED | {"domain":"pg1-test-flagged.invalid"} | found: true,age_days 3,newly_registered: true,status "flagged",reason DOMAIN_NEWLY_REGISTERED_30D |
check_domain_age | CLEAN | {"domain":"pg1-test-clean.invalid"} | found: true,registration_date 2000-01-01,status "no_flags" |
check_domain_age | UNKNOWN | {"domain":"pg1-test-unknown.invalid"} | found: false,reason_code "timeout",status "unknown"(真实注册信息查询超时会返回此结果) |
check_hostname_reputation | FLAGGED | {"hostname":"pg1-test-flagged.invalid"} | verdict "listed"(match_type "exact"),status "flagged",reason HOSTNAME_PHISHING_LISTED |
check_hostname_reputation | CLEAN | {"hostname":"pg1-test-clean.invalid"} | verdict "not_listed",status "no_flags" |
check_hostname_reputation | UNKNOWN | {"hostname":"pg1-test-unknown.invalid"} | HTTP 503,JSON-RPC 错误 -32003 "钓鱼域名列表暂时不可用,请重试。" |
check_hostname_reputation | LOOKALIKE | {"hostname":"pg1-test-lookalike.invalid"} | verdict "lookalike",lookalike_of pg1-test-brand.invalid,status "flagged",reason HOSTNAME_LOOKALIKE |
check_wallet_age | FLAGGED | {"address":"0x7067312d746573742d6669787475726500000001"} | found: false(无转账历史),status "flagged",reason WALLET_NO_HISTORY |
check_wallet_age | CLEAN | {"address":"0x7067312d746573742d6669787475726500000002"} | found: true,first_seen 2023-09-01T00:00:00.000Z,status "no_flags" |
check_wallet_age | UNKNOWN | {"address":"0x7067312d746573742d6669787475726500000003"} | isError: true,code "upstream_unavailable",status "unknown"(绝不会是 found: false) |
check_wallet_age | DELEGATED | {"address":"0x7067312d746573742d6669787475726500000004"} | found: true,is_contract: true,delegated: true,delegate_address 0x7067312d746573742d66697874757265de1e9a7e,reason WALLET_DELEGATED(仅供参考),status "no_flags" |
get_ioc_context | FLAGGED | {"value":"192.0.2.1"} | found: true,status "flagged",reason IOC_FOUND_IN_THREAT_FEED(免费,无需付款) |
get_ioc_context | CLEAN | {"value":"198.51.100.1"} | found: false,status "no_flags" |
get_ioc_context | UNKNOWN | {"value":"203.0.113.1"} | HTTP 503,JSON-RPC 错误 -32603 "威胁数据暂时不可用,请重试。" |
get_ioc_batch | FLAGGED | {"values":["2001:db8::1"]} | total_found 1,status "flagged",reason IOC_FOUND_IN_THREAT_FEED(免费,无需付款) |
get_ioc_batch | CLEAN | {"values":["2001:db8::2"]} | total_found 0,status "no_flags" |
get_ioc_batch | UNKNOWN | {"values":["2001:db8::3"]} | HTTP 503,JSON-RPC 错误 -32003 "威胁数据暂时不可用,请重试。" |
get_ioc_batch | MIXED | {"values":["2001:db8::1","2001:db8::2"]} | total_requested 2,total_found 1(第一个 found,第二个 found: false),status "flagged"(免费,无需付款) |
get_cve_details | FLAGGED | {"cve_id":"CVE-0000-0001"} | cisa_kev.is_known_exploited: true,status "flagged",reason CVE_KNOWN_EXPLOITED_KEV(免费,无需付款) |
get_cve_details | CLEAN | {"cve_id":"CVE-0000-0002"} | cisa_kev.is_known_exploited: false,status "no_flags" |
get_cve_details | UNKNOWN | {"cve_id":"CVE-0000-0003"} | exploit-score 和 KEV 检查为 "error",exploit score 为 null,status "unknown" |
get_cve_batch | FLAGGED | {"cve_ids":["CVE-0000-0001"]} | 一条列入 KEV 的结果,status "flagged",reason CVE_KNOWN_EXPLOITED_KEV(免费,无需付款) |
get_cve_batch | CLEAN | {"cve_ids":["CVE-0000-0002"]} | 一条未列入 KEV 的结果,status "no_flags" |
get_cve_batch | UNKNOWN | {"cve_ids":["CVE-0000-0003"]} | exploit-score 和 KEV 检查为 "error",status "unknown" |
get_cve_batch | MIXED | {"cve_ids":["CVE-0000-0001","CVE-0000-0002"]} | 两条结果,第一条列入 KEV,第二条未列入,status "flagged"(免费,无需付款) |
get_cve_by_product | FLAGGED | {"vendor":"pg1-test.invalid","product":"flagged"} | 一条列入 KEV 的 CVE,status "flagged",reason CVE_KNOWN_EXPLOITED_KEV(免费,无需付款) |
get_cve_by_product | CLEAN | {"vendor":"pg1-test.invalid","product":"clean"} | total_found 0,status "no_flags" |
get_cve_by_product | UNKNOWN | {"vendor":"pg1-test.invalid","product":"unknown"} | exploit-score 和 KEV 检查为 "error",status "unknown" |
check_ip_abuse | FLAGGED | {"ip":"192.0.2.1"} | abuse_confidence_score 100,total_reports 42,未列入白名单,status "flagged",reason IP_ABUSE_REPORTED(合成数据;无需密钥标头,不会调用上游) |
check_ip_abuse | CLEAN | {"ip":"198.51.100.1"} | abuse_confidence_score 0,total_reports 0,status "no_flags"(没有报告;分数为 0 并不能证明该地址无害) |
check_ip_abuse | UNKNOWN | {"ip":"203.0.113.1"} | isError: true,code "upstream_unavailable",status "unknown"(真实查询超时会返回此结果) |
check_package | FLAGGED | {"ecosystem":"npm","name":"_pg1-test-flagged"} | exists: true,age_days 3,reported_malicious: true(MAL-0000-0001),status "flagged",reasons PACKAGE_REPORTED_MALICIOUS 和 PACKAGE_NEWLY_PUBLISHED(仅供参考)(合成数据,不会调用上游;"pypi" 也可用) |
check_package | CLEAN | {"ecosystem":"npm","name":"_pg1-test-clean"} | exists: true,first_published 2026-01-01,reported_malicious: false,无漏洞,status "no_flags" |
check_package | UNKNOWN | {"ecosystem":"npm","name":"_pg1-test-unknown"} | exists: true,但恶意报告和漏洞检查均 "timeout",reported_malicious: null,status "unknown"(真实查询超时会返回此结果) |
check_package | MISSING | {"ecosystem":"npm","name":"_pg1-test-missing"} | exists: false,status "flagged",reason PACKAGE_NOT_FOUND(不存在的名称,例如助手编造的名称) |
get_threat_indicators(没有目标输入的批量信息源)、get_threat_actor_profile 和 get_usage_status(没有可用于标记的原因代码),以及 submit_indicator(写入操作,其 status 是生命周期状态,而非判定结果)均没有 fixtures。 |
**A2A:**六个带 fixtures 的免费技能(check_wallet_sanctions、check_domain_age、check_hostname_reputation、check_wallet_age、check_ip_abuse、check_package)在 /api/a2a 上接受相同的 fixtures。结果会以已完成的 Task 返回。类似 isError 的 UNKNOWN 会以 JSON-RPC 错误 -32000 返回,详情位于 error.data 中。类似 503 的 UNKNOWN 会以 HTTP 503 返回,且 JSON-RPC 错误为 -32010。这与该端点上真实故障产生的响应格式相同。
**不在范围内:**REST 端点(/api/ioc 和 /api/ioc/context)没有 fixtures。发送到这些端点的 fixture 值会像其他任何值一样进行查询。
示例
通过 MCP 返回 FLAGGED,不需要密钥:
curl -X POST https://pg1-ai-agent.vercel.app/api/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"check_hostname_reputation","arguments":{"hostname":"pg1-test-flagged.invalid"}}}'
通过 MCP 返回 UNKNOWN,用于测试你的跳过路径(upstream_unavailable isError 结果):
curl -X POST https://pg1-ai-agent.vercel.app/api/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"check_wallet_age","arguments":{"address":"0x7067312d746573742d6669787475726500000003"}}}'
付费工具的 FLAGGED fixture,不需要密钥仍可免费使用:
curl -X POST https://pg1-ai-agent.vercel.app/api/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_cve_details","arguments":{"cve_id":"CVE-0000-0001"}}}'
无效输入消息
无效输入会保留原有错误代码(大多数工具使用 JSON-RPC -32602;格式错误的 get_cve_details id 使用 -32004;或者使用工具自身的 invalid_address / invalid_hostname / invalid_chain isError 代码)。消息会说明哪里有误、预期格式是什么,提供一个有效示例,并以 request_id 结尾。不会回显你的原始输入。例如:
address is not a valid EVM address. Expected: '0x' followed by exactly 40 hex characters (case-insensitive). Example: 0x7067312d746573742d6669787475726500000002. request_id: 9cf7345b-f8d6-46f7-8e45-0da5e25a002d
PG1 Studio 影片配音(运营者)
每部影片的配音单独选择;不需要环境变量。
/voices(仅限已登录的运营者)会列出账户中的配音,并附上简短说明(口音、年龄、性别、用途),同时标明每个配音是否获准用于客户项目:内置(预制)配音和账户自行创建的配音均获准;从共享配音库添加的配音则一律不获准。/film ... --voice "<name or id>"和/film director ... --voice "<name or id>"用于选择配音(Director Mode 下的旁白配音)。优先精确匹配 id,然后匹配名称(不区分大小写,并会去除首尾空格)。输入未知名称时会给出最接近的三个名称;名称被多个配音共用时会列出各自的 id;用于客户影片的配音若未获准,则会被拒绝。这些情况都会在创建或消耗任何资源之前停止。- 不带
--voice的 Director Mode 会根据影片方案(年龄、性别、语气、口音),从账户的配音中为旁白和所有有台词的角色选角,并将阵容保存到影片中(director.cast)。重试和重新生成会沿用该阵容;影片不会重新选角。若阵容中的某个配音已不在账户中,则仅为该角色启用备用配音,影片会继续制作。 - 备用顺序:若影片没有选定配音或选角配音,则使用
PG1_FILM_VOICE_ID(可选),前提是该配音仍在账户中(客户影片还必须获准);否则使用FALLBACK_PREMADE_VOICE中指定的预制配音(lib/film/voices.mjs,一款男性英国口音配音),其 id 会通过名称从账户的配音列表中查询。配音缺失或无效都不会导致影片失败。
致谢
- Frits(x402 Doctor):发现了支付门控顺序错误并确认修复,因此 PG1 现在默认会返回正确的 x402 支付挑战。
check_package的数据来源和许可证(OpenSSF Malicious Packages、GitHub Advisory Database、PyPI Advisory Database、Go Vulnerability Database、RustSec,通过 OSV.dev;npm 公共注册表和 PyPI)列于 /docs/attributions,该页面由lib/attributions.mjs生成。check_hostname_reputation的阻止名单/许可名单/模糊名单数据来源于 MetaMask eth-phishing-detect,依据 Don't Be A Dick (DBAD) Public License 使用。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。