关于 Sato Kit
Sato Kit 是用于准备和执行链上操作的工具包,提供策略预检、交易模拟和哈希链式收据日志。它面向需要将未签名意图交给签名器执行的 Agent 开发者;密钥投入使用后,策略预检不会继续执行强制控制。
主要功能
- 01准备未签名意图
- 02执行前说明策略拒绝原因
- 03模拟交易
- 04记录哈希链式收据
- 05提供 EVM 和 Solana 操作
适用场景
- 01签名前预检链上操作
- 02查看交易模拟结果
- 03保存可验证的操作收据日志
MCP 相关
它包含本地 stdio MCP 服务。默认配置提供链上读取、兑换、x402 准备、执行、状态和操作发现等 8 个工具;`--toolsets all` 可加入其他已注册操作。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
8收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| abi | object | 否 | contract_read 的一个 ABI 函数片段;stateMutability 必须为 view 或 pure。 |
| abi.name | string | 是 | |
| abi.type | enum | 是 | function |
| abi.inputs | array | 是 | |
| abi.outputs | array | 是 | |
| abi.stateMutability | enum | 是 | view | pure |
| args | array | 否 | contract_read 的参数;整数使用十进制字符串。 |
| kind | enum | 是 | native_balance | erc20_balance | erc20_allowance | block_number | contract_read |
| chain | enum | 是 | 链名称。ethereum | sepolia | base | base-sepolia | arbitrum | arbitrum-sepolia | optimism | optimism-sepolia | polygon |
| owner | string | 否 | 用于 erc20_balance 和 erc20_allowance 的持有者。 |
| token | string | 否 | 用于 erc20_balance 和 erc20_allowance 的 ERC-20 合约。 |
| address | string | 否 | 用于 native_balance 的账户。 |
| spender | string | 否 | 用于 erc20_allowance 的支出方。 |
| contract | string | 否 | 用于 contract_read 的合约。 |
详细介绍
@satohub/kit
0.1.1 预览版。
Sato Kit 为 Agent 已在使用的工具(viem、signers、x402)提供了 prepare -> execute
契约:操作会准备一个未签名的意图,策略预检会说明任何拒绝原因,随后模拟交易,而
execute({ intent_id }) 会将其交给你的签名器,并追加一行哈希链式的 sato.receipt/v1。
它不是什么:它不是钱包、托管方、Agent 框架,也不提供任何保证。 它不会持有资金,也不附带密钥。
- 默认使用分叉网络。 策略的
network默认为fork;要使用主网,必须明确选择加入。 - 预检与强制执行。 Kit 的策略检查会在返回意图前运行,并说明哪条规则拒绝了请求以及原因。一旦密钥投入使用,它就不会强制执行任何规则。强制执行由签名器负责(例如,根据同一文件编译出的 CDP 策略)。
scan.payto_changed。policy.json的scan区块会记录payto_changed(caution|refuse|off),但只有实现了该功能的宿主才会强制执行。satohub-core中的离线防护(scanRecipient)目前不会强制执行此项:x402 的 payTo 值发生变化时,需要知道收款方之前的值,而离线检查并未获得该值。- 兑换不依赖特定平台。 接受任何平台。Sato Swap 是标记为默认的平台,每次响应都会披露其费用,并同时提供不含 Sato 费用的报价;
venue: "direct"则会完全跳过 Sato。
契约(sato.action/v1、sato.policy/v1、sato.receipt/v1)位于 src/spec(参见 VENDORED.md)。
安装
npm install @satohub/kit viem
npx -y @satohub/[email protected] --help
需要 Node 20 或更高版本。viem 是对等依赖;以下各框架 SDK 均为可选对等依赖,仅在使用其子路径时才需安装。
明确的限制
- 仅预检,不强制执行。
evaluatePreflight会在返回意图前运行,并列出每条拒绝规则、其限值和观测值。一旦密钥投入使用,Kit 就不会强制执行任何规则:强制执行由签名器负责(根据同一policy.json编译出的 CDP、Privy 或 Turnkey 策略、OWS 的策略引擎,或 Safe 的所有者)。viemLocalSigner仅会强制执行其主网拒绝规则。 - x402 执行范围。
x402.prepare会读取 x402 资源要求支付的内容,并返回经过定价和策略检查的意图。execute不会发送 x402 付款:它仅发送 EVM 交易、EIP-712 类型化数据(Safe 提案)和 Solana 交易。请通过你的 x402 客户端付款。 - AgentKit 自身的分析调用。 AgentKit 的
@CreateAction装饰器会在每次调用时向cca-lite.coinbase.com发送调用事件。通过fromAgentKitProvider使用的操作仍会进行此调用;Kit 既不会阻止,也不会额外发送此调用。 - 未知价格会拒绝。 如果无法读取 USD 价值,
max_usd_*规则会以unknown_price为由拒绝,而不是猜测。 - 模拟结果不作保证。 模拟通过仅表示链在该区块返回了什么结果。
操作参考
由已注册的描述符生成,使用命令 node scripts/gen-actions-doc.mjs(在
npm run build 之后);如果此表与注册表不一致,test/readme-actions.test.ts 会失败。
“custody”是描述符对三个 sato.custody/v1 问题给出的回答。toolset 表示该工具是否包含在默认 MCP 配置中,还是仅在使用 --toolsets all 时包含。
已注册操作
| 操作 ID | 工具名称 | 类型 | 效果 | 密钥托管 | 链 | 工具集 |
|---|---|---|---|---|---|---|
chain.read | chain_read | 读取 | read | 读取密钥:否;密钥离开:否;转移资金:从不 | ethereum, sepolia, base, base-sepolia, arbitrum, arbitrum-sepolia, optimism, optimism-sepolia, polygon | default, all |
swap.quote | swap_quote | 读取 | quote | 读取密钥:否;密钥离开:否;转移资金:从不 | ethereum, base, arbitrum, optimism, polygon | default, all |
swap.prepare | swap_prepare | 准备 | quote, sign, broadcast | 读取密钥:否;密钥离开:否;转移资金:需经批准 | ethereum, base, arbitrum, optimism, polygon | default, all |
x402.prepare | x402_prepare | 准备 | sign, pay | 读取密钥:否;密钥离开:否;转移资金:需经批准 | base, base-sepolia, ethereum, sepolia, polygon, arbitrum, optimism, solana, solana-devnet | default, all |
erc8004.lookup | erc8004_lookup | 读取 | read | 读取密钥:否;密钥离开:否;转移资金:从不 | ethereum, base, arbitrum, optimism, polygon | all |
tx.simulate | tx_simulate | 读取 | simulate | 读取密钥:否;密钥离开:否;转移资金:从不 | ethereum, sepolia, base, base-sepolia, arbitrum, arbitrum-sepolia, optimism, optimism-sepolia, polygon | all |
token.approvals.list | token_approvals_list | 读取 | read | 读取密钥:否;密钥离开:否;转移资金:从不 | ethereum, sepolia, base, base-sepolia, arbitrum, arbitrum-sepolia, optimism, optimism-sepolia, polygon | all |
token.approvals.revoke | token_approvals_revoke | 准备 | sign, broadcast | 读取密钥:否;密钥离开:否;转移资金:需经批准 | ethereum, sepolia, base, base-sepolia, arbitrum, arbitrum-sepolia, optimism, optimism-sepolia, polygon | all |
erc8004.register | erc8004_register | 准备 | sign, broadcast | 读取密钥:否;密钥离开:否;转移资金:需经批准 | ethereum, base, arbitrum, optimism, polygon | all |
bridge.quote | bridge_quote | 读取 | quote | 读取密钥:否;密钥离开:否;转移资金:从不 | ethereum, base, arbitrum, optimism, polygon | all |
bridge.prepare | bridge_prepare | 准备 | quote, sign, broadcast | 读取密钥:否;密钥离开:否;转移资金:需经批准 | ethereum, base, arbitrum, optimism, polygon | all |
safe.info | safe_info | 读取 | read | 读取密钥:否;密钥离开:否;转移资金:从不 | ethereum, sepolia, base, base-sepolia, arbitrum, optimism, polygon | all |
safe.propose | safe_propose | 准备 | sign | 读取密钥:否;密钥离开:否;转移资金:需经批准 | ethereum, sepolia, base, base-sepolia, arbitrum, optimism, polygon | all |
solana.read | solana_read | 读取 | read | 读取密钥:否;密钥离开:否;转移资金:从不 | solana, solana-devnet | all |
solana.transfer | solana_transfer | 准备 | sign, broadcast | 读取密钥:否;密钥离开:否;转移资金:需经批准 | solana, solana-devnet | all |
solana.swap.quote | solana_swap_quote | 读取 | quote | 读取密钥:否;密钥离开:否;转移资金:从不 | solana | all |
solana.swap.prepare | solana_swap_prepare | 准备 | quote, sign, broadcast | 读取密钥:否;密钥离开:否;转移资金:需经批准 | solana | all |
元工具
| 工具名称 | 类型 | 效果 | 工具集 |
|---|---|---|---|
execute | 执行 | sign, broadcast | default, all |
status | 元 | read | default, all |
actions_search | 元 | read | default, all |
actions_describe | 元 | read | default, all |
默认 MCP 配置文件中的工具按以下顺序排列:chain_read, swap_quote, swap_prepare, x402_prepare, execute, status, actions_search, actions_describe。
从 AgentKit 提供方(fromAgentKitProvider)获取的操作不在此表中:它们会根据你传入的提供方在运行时构建,并归入工具集 all。
入口
| 导入 | 提供内容 |
|---|---|
@satohub/kit | createKit、coreActions、工具接口、配置加载器,以及下文所有内容的重新导出 |
@satohub/kit/spec | 随附的契约:sato.action/v1、sato.policy/v1、sato.receipt/v1、ID 规则、描述符 lint |
@satohub/kit/policy | evaluatePreflight;编译器 compileCdpPolicy、compilePrivyPolicy、compileTurnkeyPolicy |
@satohub/kit/signers | viemLocalSigner、owsSigner、cdpSigner、solanaLocalSigner、humanApprove |
@satohub/kit/intent | 意图存储、HMAC 意图 ID(loadOrCreateIntentSecret、verifyIntentId) |
@satohub/kit/receipts | 哈希链式 sato.receipt/v1 日志 |
@satohub/kit/actions | 所有核心操作、描述符和构建器 |
@satohub/kit/ai-sdk | 面向 Vercel AI SDK 的 satoKitTools(kit, opts) |
@satohub/kit/agentkit | satoKitActionProvider(kit, opts) 和 fromAgentKitProvider(provider, { chain }) |
@satohub/kit/claude-agent-sdk | createSatoKitSdkServer(kit, opts) + requireApprovalHook() |
@satohub/kit/openai-agents | satoKitOpenAITools(kit, opts) |
@satohub/kit/langchain | satoKitLangChainTools(kit, opts) |
@satohub/kit/eliza | satoKitElizaPlugin(kit, opts)(兼容性适配器,见下文) |
@satohub/kit/mcp | 本地 MCP 服务(stdio) |
@satohub/kit/cli | 作为函数使用的 sato-kit CLI |
@satohub/kit/sato-os | attachToSatoOs、proposeIntent |
@satohub/kit/goat | fromGoatPlugin(plugin, { chain }) — 使用现有 GOAT 插件,并享有 kit 的保障 |
签名器
viemLocalSigner— 使用此进程中的密钥。默认用于 fork/testnet;除非设置allowMainnet: true(不建议),否则会拒绝 mainnet 链 ID。generate: true会生成一次性内存密钥。owsSigner— 对 Open Wallet Standard 账户的结构化适配器;由 OWS 的策略引擎执行策略。参见src/signers/OWS.md。cdpSigner— 对 Coinbase CDP 服务端账户的结构化适配器;由 CDP 执行其策略。将编译后的策略作为nativePolicy传入,可随签名器携带该策略(适配器不会注册策略)。solanaLocalSigner— 仅用于 devnet 和测试的本地 Solana 签名;会拒绝任何非 devnet 负载和 mainnet-beta RPC,且没有 mainnet 切换选项。humanApprove(signer, approve)— 包装任意签名器,使其在签名前都需由人员批准摘要。
策略编译器
compileCdpPolicy、compilePrivyPolicy 和 compileTurnkeyPolicy 会将一个 sato.policy/v1 转换为提供商原生策略文档。每项结果都会列出无法编译的内容(not_compiled)及原因,因此提供商无法表达的规则绝不会被静默丢弃。
CLI
sato-kit read <action> --input '<json>' run a read-only action
sato-kit prepare <action> --input '<json>' build an intent; nothing is signed
sato-kit execute --intent <intent_id> hand one prepared intent to the signer
sato-kit mcp [--toolsets default|all] local MCP server over stdio
sato-kit doctor check config, Sato Status and template drift
配置从工作目录读取:policy.json(缺失时使用默认策略,网络为 fork)、.sato/(意图、意图密钥、回执)、各链对应的 SATO_RPC_URL_<CHAIN>,以及本地签名器所需的 SATO_SIGNER=viem-local-fork(仅限 fork 网络)。
MCP 服务
npx -y @satohub/[email protected] mcp 会运行 stdio MCP 服务(注册表名称为 ai.satohub/kit)。默认配置包含上文列出的八个工具;--toolsets all 会添加所有其他已注册操作。会进行签名的工具在 _meta 中包含 anthropic/requiresUserInteraction。
Sato 状态
status 和 sato-kit doctor 会读取模板仓库发布的每晚按操作生成的结果(sato.action-status/v1)。无法读取该文件时,回答会明确说明;不会填入任何内容。
推荐的 .gitignore
默认情况下,文件意图存储和意图 HMAC 密钥位于 .sato/ 下(intents/、intent.key,权限模式为 0600)。请勿将它们纳入版本控制:
.sato/
许可证:MIT。随附的 Onchain Action Descriptor 代码(dist/spec)采用 Apache-2.0 许可证,版权所有 2026 Prime Signal LLC:参见 LICENSE-ODA 和 NOTICE。
sato-kit doctor:模板漂移
在由 create-sato-agent 创建的仓库中(包含 sato.create.json),doctor
还会将 sato.create.json 和 sato.lock.json 发送至
https://satohub.ai/api/create/drift(超时时间为 3 秒),并打印返回的变更:通过检查的较新模板版本、已固定软件包的已存储 Sato Check 配置中的托管方变更,或未通过上游模板检查的已固定软件包版本。此操作只读,不会创建问题(生成的 sato-drift.yml 工作流会执行此操作)。使用 --json 时,结果位于 result.drift 下,state 为 checked、unavailable(带有 reason)或 not_applicable;如果检查没有返回结果,则不会填入任何内容。
宿主适配器:信封与错误代码
@satohub/kit/ai-sdk(satoKitTools(kit, opts))、@satohub/kit/agentkit
(satoKitActionProvider(kit, opts))、@satohub/kit/claude-agent-sdk
(createSatoKitSdkServer(kit, opts) + requireApprovalHook())、
@satohub/kit/openai-agents(satoKitOpenAITools(kit, opts),带有 needsApproval 的 OpenAI Agents SDK 函数工具)、@satohub/kit/langchain
(satoKitLangChainTools(kit, opts),其 func 会以 JSON 字符串形式返回信封的 LangChain JS DynamicStructuredTool)和 @satohub/kit/eliza(satoKitElizaPlugin(kit, opts))均基于与本地 MCP 服务(sato-kit mcp)相同的工具接口构建。选项:
{ toolsets?, actions?, policy?, signerKind?, fetch?, statusTimeoutMs? }
(AgentKit、LangChain 和 elizaOS 还接受 approve;这些宿主都没有审批步骤,因此没有它就会拒绝 execute)。
@satohub/kit/eliza 是面向现有 elizaOS 1.x
Agent 的轻量兼容适配器,不是受支持的框架:没有任何 Sato 模板依赖 elizaOS,如果 elizaOS 某个版本导致它无法正常工作,就会移除该子路径,而不会修复它。
其操作会从 options.parameters(然后是
message.content.parameters)读取参数。每个适配器工具都会返回一个信封:
{ ok: true, tool, result }{ ok: false, tool, error: { code, message, refusals? }, intent? }
错误代码:unknown_tool、invalid_input、policy_refused、
approval_required、approval_denied、not_configured、error。策略拒绝会列出每条 { rule, limit, observed }。execute 接受 { intent_id },且不接受其他内容;每个宿主都会在运行前征求人员批准。
在 MCP 服务上,被拒绝的 prepare 是一个普通结果,其
structuredContent.policy.refusals 会列出每条规则;调用失败时会设置 isError,并在 _meta["ai.satohub/error"] 中携带详细信息。
使用现有的 AgentKit 提供程序(@satohub/kit/agentkit)
fromAgentKitProvider(provider, { chain }) 会将 AgentKit ActionProvider 的每个操作转换为 kit 操作。读取操作(名称以 get_/check_/list_… 开头的操作,或你通过 reads 传入的名称)会变成读取操作。其他所有操作都会通过一个捕获型钱包调用提供程序自己的 invoke();该钱包会记录交易,而不会发送交易。记录的这笔交易会变成普通意图——先进行模拟和策略预检,再由你使用自己的签名者通过 execute(intent_id) 发送一次。
import { erc20ActionProvider } from "@coinbase/agentkit";
import { fromAgentKitProvider } from "@satohub/kit/agentkit";
const { actions, not_consumable } = fromAgentKitProvider(erc20ActionProvider(), { chain: "base" });
const kit = createKit({ ...opts, actions: [...coreActions(), ...actions] });
- 如果某个操作尝试发送多笔交易,或签署消息、类型化数据或原始交易,系统会拒绝该操作并说明原因。没有任何内容被发送,因此也不会出现部分完成的情况。
- 无法转换为可移植形式的架构会连同 lint 给出的原因列在
not_consumable中,而不会被转换为工具。名称中包含 amount 的字符串若没有 pattern,则会收窄为十进制 pattern,并列在consumed[].tightened中。 - 已转换操作的 USD 价值未知,因此
max_usd_*上限会因unknown_price拒绝该操作;max_per_trade会读取捕获交易中的 ERC-20 数量或原生币金额。 - AgentKit 自身的
@CreateAction装饰器会在每次调用时向cca-lite.coinbase.com发送调用分析事件;kit 不会阻止或添加此事件。 - 已转换的操作会出现在工具集
"all"下,也可通过actions_search/actions_describe使用;默认 MCP 配置文件保持不变。
使用现有的 GOAT 插件(@satohub/kit/goat)
await fromGoatPlugin(plugin, { chain }) 的工作方式与 fromAgentKitProvider 类似:读取操作会作为读取操作运行;写入操作会通过一个捕获型钱包运行插件自己的工具,该钱包会记录唯一一笔交易,而不会发送交易;这笔交易会变成普通意图(模拟、预检,然后由你使用自己的签名者通过 execute(intent_id) 发送一次)。如果涉及消息或类型化数据签名、paymaster 请求或多笔交易,系统会拒绝操作并说明原因。GOAT 上游近期没有更新;如果安装中有两份 @goat-sdk/core,GOAT 自己的钱包查找可能会找不到该钱包——请确保只保留一份。
安全提案
safe.propose 会构建供 Safe 所有者签署的 SafeTx;策略预检会应用于其中的调用。如果意图指定了 Safe Transaction Service 目标,execute 会签名并提交该提案,回执中包含 safe_tx_hash;如果没有目标,回执中则包含签名 typed_data_signature。对于 Safe 托管网关,请将 safeTxService: { apiKey } 传给 createKit(或选择读取 SAFE_API_KEY);该密钥仅会作为 Authorization: Bearer … 发送到 api.safe.global 或你配置的源,且绝不会记录日志或写入回执。
Solana
Solana 操作需要 Solana RPC(在 createKit 中设置 solanaRpc)。solanaLocalSigner 仅适用于 devnet,并且需要在 kit 同级位置安装 @solana/kit 8 或更高版本(npm i @solana/kit@^8);它没有声明为对等依赖,因此使用旧版 @solana/kit 的安装(例如通过 AgentKit 安装)仍能正常解析。
与 Base MCP(Coinbase Wallet MCP)配合使用
Base MCP 现由 https://wallet-mcp.coinbase.com 提供服务,使用你的 Base Account 进行签名。kit 的
Base MCP 插件会先在你的 shell 中运行策略预检和模拟,然后将未签名的调用交给 Base
MCP,供你在 Base Account 中批准。这是一个自定义插件:Base 不会列出、维护或认可它。
在带有 shell 的执行环境中(此处展示 Claude Code;Base 的安装步骤也涵盖 Codex 和 Cursor):
claude mcp add --transport http base-mcp https://wallet-mcp.coinbase.com
npx skills add base/skills --skill base-mcp
curl -fsSL -o .claude/skills/base-mcp/plugins/sato-kit.md \
https://raw.githubusercontent.com/satohubai/sato-hub-integrations/main/channels/base-mcp/sato-kit.md
然后编写自己的 policy.json(插件文件提供了一个起始示例;如果没有该文件,默认策略会拒绝所有主网请求),设置 SATO_RPC_URL_BASE,并按名称请求插件:
“使用 Sato Kit 插件,在 Base 上将 5 USDC 兑换为 WETH。”只有在你指定插件名称时,Base 才会将请求路由到插件。仅支持聊天的界面(Claude.ai、ChatGPT)无法运行 kit,插件会说明这一点并停止。
不包含:Stripe MPP
尚未实现 mpp.prepare。其客户端(mppx)尚未达到 1.0 版本,小版本更新可能引入破坏性变更;其支付方式也无法映射为一笔由该工具包的签名器执行签名的未签名交易。原因和来源:docs/mpp-research.md。
Sato OS 交接(@satohub/kit/sato-os)
在实时模式下,Agent 可以将准备好的意图发送到可自托管的 Sato OS,由用户在其中批准并签名,而不是在本地签名。attachToSatoOs({ baseUrl, name, goal, walletAddresses, chains }) 会关联 Agent,并将其作用域令牌存储在 .sato/sato-os.json 中(权限模式为 0600,已加入 gitignore;绝不会返回或打印)。proposeIntent(prepared, { baseUrl, token }) 会通过 Sato OS 的 sato_os_create_action_proposal 工具提交意图(未签名的载荷、摘要、策略判定、模拟结果、费用披露),并返回 { proposal_id, status }。遭拒或已过期的意图绝不会被发送。这条路径不会进行签名或广播。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。