chain-signer
Provides Bitcoin wallet functionality for AI agents, including key generation (burner), key restoration, local transaction signing, and balance checks.
Provides Solana wallet functionality for AI agents, including key generation (burner), key restoration, local transaction signing, and balance checks.
chain-signer
A security suite for AI agents — the seatbelt that catches the dangerous thing BEFORE it happens. Three guards, each callable on its own (and as MCP tools), pairing with any wallet or identity stack:
preflight(tx)— decode an unsigned transaction and flag drains before signing (unlimited/large approval, approve-all, token & NFT transferFrom, proxy upgrade, on-chain permit, on-chain Permit2 approve/permit/transferFrom, approvals hidden in multicall incl. Uniswap router batches and Multicall3 aggregate/aggregate3/aggregate3Value (the batch helper on every EVM chain), approvals wrapped in ERC-4337/smart-account execute/executeBatch, Gnosis Safe multiSend/execTransaction and DSProxy execute, drains routed through the Uniswap Universal Router (Permit2 permit/transferFrom commands incl. sub-plans), 1inch AggregationRouter v5 swap() with redirected output or zero slippage, 0x ExchangeProxy transformERC20() with zero slippage, EIP-7702 account delegation, will-revert).inspect_typed_data(td)— catch permit-phishing in an EIP-712 message before the agent signs it (ERC-2612, Uniswap Permit2 incl. SignatureTransfer + witness variants, DAI-style permits) and Seaport orders that give assets away — zero consideration, proceeds routed to a third party, or hidden in a BulkOrder tree.check_action(action, policy)— enforce allow/forbid + value/recipient limits before the agent acts.
All three fail safe and are guards, not guarantees. Also bundled: a non-custodial multi-chain wallet (burner, balance, send, swap) — the agent holds its own key and signs locally. No MetaMask, no account, no custody.
from chain_signer import assert_safe
assert_safe(tx) # raises if the tx is a drain/unlimited-approval/revert — review before signingInstall
pip install chain-signer
export ETHERSCAN_API_KEY=... # for live balance reads + broadcast (Etherscan v2)Bitcoin/Solana support is optional: pip install "chain-signer[all]".
Related MCP server: actiongate
Quickstart (10 seconds — offline, no key, no funds, no network)
pip install chain-signerfrom chain_signer import preflight
spender = "0x" + "22" * 20
tx = {"to": "0x" + "33" * 20, "data": "0x095ea7b3" + spender[2:].rjust(64, "0") + "f" * 64, "value": 0}
print(preflight(tx)) # ok=False — flags unlimited_approval before you'd ever signThat's the wedge: the drain gets flagged before you'd ever sign it — no key, no funds, no network.
Bundled wallet (optional — the guards pair with any wallet)
from chain_signer import burner, send_ether
from chain_signer.balance import get_balance
w = burner() # fresh throwaway wallet; the agent owns w.private_key
print(w.address, get_balance(w)) # live on-chain balance
send_ether(w, "0x...recipient", 0.001) # auto nonce+gas, signed locally, broadcastFull runnable demos are in the repo: examples/agent_safety_demo.py (all three guards stop three
real attacks) and examples/quickstart.py (wallet) — clone to run them, or just import as above.
Safety preflight (the wedge)
Before an agent signs, hand the unsigned tx to preflight() — it decodes the calldata and returns
the risks, or use assert_safe() to hard-stop on a HIGH flag. Offline, no network, never raises.
from chain_signer import preflight, assert_safe
# an unlimited-allowance approve() to a spender — the classic drain setup
tx = {"to": token, "data": "0x095ea7b3" + spender_padded + "f"*64, "value": 0}
report = preflight(tx)
# {'decoded': {...}, 'ok': False,
# 'risk_flags': [{'code': 'unlimited_approval', 'severity': 'HIGH',
# 'detail': 'approve() grants an effectively-unlimited allowance ...'}]}
assert_safe(tx) # raises ValueError on a HIGH flag; pass force=True to override
assert_safe(tx, sim=my_simulator) # optional: also flag will-revert via your simulation hookWhat it flags today: unlimited/large approval, increaseAllowance, setApprovalForAll,
ERC-20 transferFrom + ERC-721/1155 safeTransferFrom (token & NFT drains), ERC-777 authorizeOperator/operatorSend
(operator-grant + operator-pull drains), on-chain ERC-2612 and DAI-style permit,
on-chain Permit2 approve/permit/transferFrom (single and batch — the dominant approval router:
unlimited uint160 allowance + drain pull) plus Permit2 SignatureTransfer permit(Witness)TransferFrom
(the one-shot signed-permit pull intent/filler protocols use), proxy upgradeTo/upgradeToAndCall, approvals hidden inside multicall (all router
variants, nested) and Multicall3 aggregate/aggregate3/aggregate3Value (the canonical batch
helper deployed at one address on every EVM chain), approvals wrapped in ERC-4337/smart-account execute/executeBatch, Gnosis Safe
multiSend/execTransaction, or DSProxy execute(target,data)/execute(code,data) (decoded and recursed),
drains routed through the Uniswap Universal Router
(execute(commands,inputs) — Permit2 permit/transferFrom commands, batch and EXECUTE_SUB_PLAN),
EIP-7702 account delegation (the "wallet upgrade" drainer), large native value,
opaque calldata, malformed calls, and will-revert (with a sim hook).
Honest limits (read these): this is STATIC analysis — it decodes calldata and matches known drain
patterns. It is NOT a transaction simulator: it won't catch a novel/obfuscated drain it can't decode
(those get a low-severity "unknown" flag, not a block), and simulation-based scanners go deeper there.
Safety coverage is EVM-only today (no Solana/Bitcoin tx analysis). And it is not yet field-proven at
scale. A first-line guard for known patterns — not a guarantee. Pair it with simulation + human
review for high-value actions.
Signed-message inspector (the off-chain half)
A drain doesn't need a transaction. A dApp can ask the agent to sign an EIP-712 message —
most dangerously a permit granting an unlimited token allowance, which preflight (a tx check)
can't see. inspect_typed_data() catches it before the agent signs:
from chain_signer import inspect_typed_data
report = inspect_typed_data(typed_data) # the EIP-712 object you're about to sign
# ok=False, risk_flags=[{'code': 'unlimited_permit_signature', 'severity': 'HIGH', ...}]Covers all three major permit shapes: ERC-2612, Uniswap Permit2 (PermitSingle/PermitBatch, plus
SignatureTransfer and the witness variants intent protocols use), and DAI-style (allowed: true),
plus Seaport marketplace orders that hand assets over for nothing — zero consideration, proceeds
routed to a third party while your asset leaves, or the same giveaway buried in a BulkOrder merkle tree.
Offline, never raises.
Guarded signer (screen + sign in one call)
inspect_typed_data only protects when the agent remembers to call it first — sign_typed_data
alone will happily sign a permit-phishing message. guarded_sign_typed_data() composes the two so
signing is screened by default: it inspects, then refuses to sign a HIGH-risk drain.
from chain_signer import guarded_sign_typed_data, SignatureBlocked
sig = guarded_sign_typed_data(wallet, domain, types, message, "Permit") # raises SignatureBlocked on a drainOn a clean message the signature is byte-identical to sign_typed_data; pass force=True to override.
Action-policy gate (inspect what the agent DOES)
Identity tells you who the agent is; it doesn't stop a bad action. check_action() enforces a
policy on a proposed tool call before it runs — fail-safe (denies on unreadable input):
from chain_signer import check_action
policy = {"forbid_tools": ["bridge"], "max_value_wei": 10**18, "allow_recipients": [trusted_addr]}
r = check_action({"tool": "send", "args": {"to": addr, "value_wei": 5*10**18}}, policy)
# {'allowed': False, 'violations': [{'code': 'value_over_limit', ...}]}All three guards are exposed as MCP tools (preflight, inspect_signature, check_action) — any
agent runtime (Claude, Cursor, …) can call them directly, read-only, no key.
What's caught and what isn't — the honest threat-coverage map: docs/THREAT-COVERAGE.md.
What you get
preflight(tx)/assert_safe(tx)— decode an unsigned tx and flag drain patterns before signing.inspect_typed_data(td)— flag permit-phishing in an EIP-712 message before the agent signs it.guarded_sign_typed_data(w, domain, types, message, primary_type)— screen then sign; refuses a drain.check_action(action, policy)— enforce allow/forbid + value/recipient limits before the agent acts.burner()— a fresh wallet for a one-off task; discard it when done.restore(key)— reload a wallet later from its exported private key (same key → same address).send_ether(w, to, amount)— send in ETH (not wei); nonce, gas, and broadcast handled for you.get_balance(w)— live balance from the chain (Etherscan v2 indexer, not a flaky public RPC).swap(...)— token swaps via 0x/Paraswap.Optional Solana + Bitcoin wallets via the
[all]extra.
Non-custodial guarantee
The private key is generated/loaded locally, used only to sign, and never logged, returned, or stored by this library. You hold the key; we never touch your funds. That is the whole design.
Handling the key (read this)
w.private_key is the keys to the wallet. Treat it like a password:
NEVER log it, print it in production, or write it into notes/memory/chat. Anyone who has it controls the funds.
For a burner holding a few dollars this is low-stakes by design — but the rule still holds.
To reuse a wallet later, store the key in a secret manager / env var, then
restore(key).Better:
export_encrypted(w, password)gives a password-protected keystore dict to store at rest;load_encrypted(keystore, password)brings the wallet back. Never store the raw key if you can store the keystore.
Signing idiom (note for web3.py users)
The wallet does not expose sign_transaction / sign_message methods. Signing is done by
function helpers you pass the wallet to — e.g. send_ether(w, to, amount) signs and broadcasts,
and sign_message(w, "text") returns an EIP-191 signature for auth / sign-in flows
(recoverable via eth_account Account.recover_message).
CLI on PATH
pip install may warn that the chain-signer script dir isn't on your PATH. The library works
regardless; to use the CLI directly, add that dir to PATH or run python -m chain_signer ....
Tool surface (for any AI / MCP / CLI)
chain_signer.mcp_server exposes list_tools() and call_tool(name, arguments). CLI:
python -m chain_signer list
python -m chain_signer call create_wallet '{"chain":"evm"}'Responsible use
General-purpose, non-custodial tooling. You are responsible for using it within the laws and terms of service that apply to you. Not intended or marketed for any restricted or prohibited trading in your jurisdiction.
Notes
Balances/broadcast use the Etherscan v2 indexer (authoritative), never a free public RPC.
Low-level building blocks (
tx.send,call_contract, explicit nonce/gas) remain available for advanced use.
Pay an x402 API in one call
from chain_signer import burner, sign_x402_payment
w = burner()
payload = sign_x402_payment(w, token=USDC, to=PAY_TO, value=1000, valid_before=EXPIRES, chain_id=8453)
# -> {"signature", "authorization"} ready for the x402 payment header. Signed locally, no prompt.Builds + signs the EIP-3009 authorization x402 expects (the "exact" scheme). Your agent pays a paid API by itself — no password prompt, no signup, no custody.
Sign typed data (EIP-712) — for agent payments / x402
from chain_signer import burner, sign_typed_data
w = burner()
sig = sign_typed_data(w, domain, types, message) # EIP-712; for x402 / EIP-3009 authorizationsYour agent can authorize a payment by signing typed data locally — no password prompt, no signup.
Run as an MCP server
chain-signer is also a Model Context Protocol (MCP) server, so MCP-aware agents can use it directly:
pip install chain-signer
chain-signer-mcp # speaks MCP over stdio (JSON-RPC 2.0)Exposes 9 tools. The three security guards (the wedge): preflight, inspect_signature,
check_action. Plus the non-custodial wallet: create_wallet, get_balance, send, call_contract, swap, bridge.
Wire it into any MCP client (Claude Desktop, Cursor, etc.) by adding it to the client's
mcpServers config:
{
"mcpServers": {
"chain-signer": {
"command": "chain-signer-mcp",
"env": { "ETHERSCAN_API_KEY": "your-key-for-live-balance-and-broadcast" }
}
}
}That's all — the agent can now screen every tx, signature, and action through the guards before it
acts, and (optionally) hold its own wallet to read balances, send, and swap as native tools.
(ETHERSCAN_API_KEY is optional; needed only for live balance reads and broadcasting.)
Available Tools
9 toolsbridgeA
Move value across chains via LI.FI; signs the route tx with the owner's key.
| Name | Required | Description | Default |
|---|---|---|---|
| gas | No | Gas limit. | |
| nonce | Yes | Account nonce for this transaction. | |
| amount | Yes | Amount to bridge (base units). | |
| chain_id | No | EVM chain id (137 = Polygon). | |
| to_chain | Yes | Destination chain. | |
| to_token | Yes | Token address on the destination chain. | |
| from_chain | Yes | Source chain. | |
| from_token | Yes | Token address on the source chain. | |
| integrator | No | chain-signer | |
| private_key | Yes | The caller's own private key. Used transiently to sign; never stored (non-custodial). | |
| max_fee_per_gas | Yes | EIP-1559 max fee per gas (wei). | |
| max_priority_fee_per_gas | Yes | EIP-1559 priority fee per gas (wei). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description must fully disclose behavioral traits. It mentions signing with the owner's key but does not discuss side effects like gas consumption, slippage, or revert behavior. The presence of gas and fee parameters in the schema implies consumption, but the description does not confirm.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, direct sentence with no superfluous words. It efficiently conveys the tool's core function and a key behavioral aspect.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex tool with 12 parameters and no output schema, the description is minimal. It does not explain the return value, error handling, or how LI.FI routing works. However, it gives the essential purpose, making it usable for basic tasks.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is high (92%), so most parameters are already explained. The description adds value by stating that the signed route uses the owner's key, but it does not delve into each parameter beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's primary action: 'Move value across chains via LI.FI'. It also mentions signing with the owner's key. This distinguishes it from siblings like swap and send, which are likely same-chain operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for cross-chain bridging, but does not explicitly state when to use this tool versus alternatives like swap or send. No exclusions or conditions are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
call_contractB
Sign and post a call to any contract/app function.
| Name | Required | Description | Default |
|---|---|---|---|
| gas | No | Gas limit. | |
| args | No | Positional arguments for the function. | |
| chain | No | Which chain family to act on. | evm |
| nonce | Yes | Account nonce for this transaction. | |
| value | No | Native value to attach (wei). | |
| chain_id | No | EVM chain id (137 = Polygon). | |
| contract | Yes | Target contract address. | |
| private_key | Yes | The caller's own private key. Used transiently to sign; never stored (non-custodial). | |
| max_fee_per_gas | Yes | EIP-1559 max fee per gas (wei). | |
| function_signature | Yes | e.g. 'transfer(address,uint256)'. | |
| max_priority_fee_per_gas | Yes | EIP-1559 priority fee per gas (wei). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. 'Sign and post a call' implies a mutation (transaction submission), which is transparent. However, it does not disclose side effects like nonce increment, gas consumption, or potential failure modes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that conveys the core action with no wasted words. It is front-loaded and efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having 11 parameters (6 required) and no output schema, the description fails to explain return values, error handling, prerequisites (e.g., wallet funding), or the overall transaction lifecycle. The complexity is high but the description is too sparse.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with each parameter having a clear description in the schema. The tool description adds no extra meaning beyond what the schema already provides, so a baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool signs and posts a call to any contract/app function, which is a specific verb-resource pair. It distinguishes from siblings like swap or bridge that are more specialized, though it could be more explicit about the blockchain context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives such as swap, send, or bridge. The description lacks context about prerequisites or when not to use it, leaving the agent without decision support.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_actionA
SAFETY: enforce a policy on a proposed agent action (tool call) BEFORE it runs. policy supports forbid_tools/allow_tools, max_value_wei, allow_recipients. Returns {allowed, violations}. Fail-safe: denies on unreadable input. The 'inspect what the agent DOES' gate, not just who it is.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | Proposed action: {tool, args}. | |
| policy | No | Rules: forbid_tools[], allow_tools[], max_value_wei, allow_recipients[]. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Without annotations, the description carries full burden. It discloses key behaviors: safety enforcement, supported policy rules, return format, and a fail-safe that denies on unreadable input. No mention of rate limits or auth, but the critical behavioral traits are covered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences with no waste. Each sentence serves a distinct purpose: purpose/policy support, return format, fail-safe and role context. Front-loaded with 'SAFETY' for quick identification.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description explains the return format. It covers purpose, policy details, fail-safe behavior, and role as a pre-execution gate. It does not clarify the optionality of the policy parameter or provide examples, but overall it is sufficiently complete for agent use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (both parameters described). The description repeats schema content with slight context (e.g., 'action' as proposed action with tool and args; 'policy' as rules with arrays). This adds minimal value beyond the schema, meeting the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it is a safety tool that enforces policy on a proposed agent action before execution, with specific supported policies and return format. It distinguishes itself from sibling tools which perform blockchain operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use: before running an agent action to enforce safety policies. It does not explicitly state when not to use or mention alternatives, but the purpose is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_walletA
Create or restore a non-custodial wallet; returns the address and the private key (caller keeps the key).
| Name | Required | Description | Default |
|---|---|---|---|
| chain | No | Which chain family to act on. | evm |
| testnet | No | Use the chain's testnet. | |
| private_key | No | Optional: restore an existing wallet from its key; omit to generate a fresh one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses that the tool returns the private key and is non-custodial, but does not mention authentication needs, rate limits, or potential side effects like overwriting an existing wallet.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Extremely concise single sentence that front-loads the action and includes essential return information with no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers main behavior and return values, which compensates for missing output schema. Lacks details on error conditions or warnings about handling sensitive private key data.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but description adds beyond schema by explaining that private_key is for restore and that the tool returns address and private key, providing context not in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Create or restore a non-custodial wallet' with a specific verb and resource, and distinguishes from sibling tools like get_balance and send by focusing on wallet lifecycle.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implied usage (create vs restore) but lacks explicit guidance on when to choose this tool over alternatives or prerequisites like requiring caller to store key.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_balanceB
Read a wallet/address balance from the live chain (read-only).
| Name | Required | Description | Default |
|---|---|---|---|
| chain | No | Which chain family to act on. | evm |
| token | No | Optional token/mint address; omit for the native coin. | |
| address | Yes | Address to read the balance of. | |
| testnet | No | ||
| decimals | No | Token decimals for formatting. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Only discloses 'read-only' behavior. With no annotations provided, description carries full burden but omits details on error handling, rate limits, or response characteristics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence with no fluff. Every word serves purpose. Efficiently communicates the core function.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having 5 parameters and no output schema, description provides no return format details, error behavior, or parameter relationships. Incomplete for an agent to invoke reliably.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 80%, so parameters are mostly documented in schema. Description adds no extra meaning beyond stating the action, meeting baseline but not exceeding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states verb 'Read', resource 'wallet/address balance', and scope 'from the live chain (read-only)'. It effectively distinguishes from sibling tools like 'send' or 'swap'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives. Lacks context about prerequisites, limitations, or exclusions. Agent receives no decision-support.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
inspect_signatureA
SAFETY: inspect an EIP-712 typed-data message the agent is about to SIGN and flag permit-phishing (ERC-2612, Uniswap Permit2, DAI-style permits granting an unlimited/large allowance). Catches the off-chain drain a transaction check can't see. Returns {decoded, risk_flags, ok}. Read-only; takes no key.
| Name | Required | Description | Default |
|---|---|---|---|
| typed_data | Yes | EIP-712 typed data: {types, domain, primaryType, message}. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description bears the burden of behavioral disclosure. It correctly states the tool is read-only and takes no key, and lists return fields. However, it does not detail potential limitations or error conditions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with a clear safety prefix, concise and front-loaded. Every sentence provides essential information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description explains the return format and the purpose. It covers the necessary context for a tool with one required parameter and specific safety checks.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with a clear description of the typed_data parameter. The description adds context about it being an EIP-712 message and the phishing checks, which adds value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool inspects EIP-712 typed-data messages before signing, specifically to flag permit-phishing. The verb 'inspect' and resource are specific, and the tool is distinct from siblings like call_contract or swap.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description advises using this tool before signing to catch off-chain drains. It implies when to use but does not explicitly list alternatives or when-not scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
preflightA
SAFETY: decode an UNSIGNED EVM transaction and flag drain patterns (unlimited/large approval, approve-all, token & NFT transferFrom, proxy upgrade, on-chain permit, approvals hidden in multicall, opaque calldata) BEFORE signing. Returns {decoded, risk_flags, ok}. Read-only; takes no key.
| Name | Required | Description | Default |
|---|---|---|---|
| tx | Yes | Unsigned tx: {to, data (hex calldata), value}. | |
| max_value | No | Optional: flag native value above this (wei). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It clearly states it's read-only, takes no key, and returns {decoded, risk_flags, ok}. It lists specific patterns flagged. It does not mention error handling or rate limits, but the essential behavioral traits are transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence plus a returns statement. It is front-loaded with 'SAFETY:' and every word adds value. No redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (nested object, no output schema), the description covers the purpose, safety aspects, and return structure. It could mention chain compatibility but is substantially complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so both parameters have descriptions. The tool description does not add meaning beyond the schema; it only states 'takes no key' which is behavioral. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool decodes unsigned EVM transactions and flags drain patterns. It uses specific verbs ('decode' and 'flag') and resource ('unsigned EVM transaction'). It distinguishes from siblings like 'inspect_signature' and 'check_action' by emphasizing pre-signing safety.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says to use BEFORE signing and that it's read-only with no key needed. This implies when to use (pre-signing) and that it's safe. It doesn't explicitly state when not to use alternatives, but the context is strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sendA
Sign and post a native-coin transfer with the caller's own key. EVM one-call: omit nonce/gas and they are auto-fetched + broadcast (or supply them to control the tx). Solana uses lamports; Bitcoin uses amount_btc.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Recipient address. | |
| gas | No | Gas limit. | |
| chain | No | Which chain family to act on. | evm |
| nonce | No | Account nonce for this transaction. | |
| chain_id | No | EVM chain id (137 = Polygon). | |
| lamports | No | Solana: amount to send in lamports. | |
| value_wei | No | EVM: amount to send in wei. | |
| amount_btc | No | Bitcoin: amount to send in BTC. | |
| private_key | Yes | The caller's own private key. Used transiently to sign; never stored (non-custodial). | |
| max_fee_per_gas | No | EIP-1559 max fee per gas (wei). | |
| max_priority_fee_per_gas | No | EIP-1559 priority fee per gas (wei). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses that the tool signs with the caller's private key and broadcasts the transaction. Also notes non-custodial nature in the parameter description. Covers chain-specific behaviors well but could be more explicit about transaction irreversibility.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences: first defines the core action, second provides chain-specific usage details. Front-loaded with the key purpose. No fluff, every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 11 parameters and multi-chain support, the description covers essential behavior and usage patterns. Lacks details on return values or error states, but output schema is absent and tool action is straightforward. Sufficient for an agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with per-parameter descriptions, so baseline is 3. The description adds value by explaining how to use parameters in context (e.g., omit nonce/gas for auto-fetch on EVM, which parameter to use for each chain), going beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Sign and post a native-coin transfer', specifying the action and resource. It distinguishes from sibling tools like 'call_contract' or 'swap' by focusing on native coin transfers across multiple chains.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance for EVM (omit nonce/gas for auto-fetch, or supply for control), and specifies which parameter to use for Solana (lamports) and Bitcoin (amount_btc). No explicit when-not-to-use or alternatives mentioned, but context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
swapB
Swap tokens via a DEX aggregator with our built-in fee; non-custodial.
| Name | Required | Description | Default |
|---|---|---|---|
| gas | No | Gas limit. | |
| chain | No | Which chain family to act on. | evm |
| nonce | Yes | Account nonce for this transaction. | |
| chain_id | No | EVM chain id (137 = Polygon). | |
| buy_token | Yes | Token address to buy. | |
| sell_token | Yes | Token address to sell. | |
| private_key | Yes | The caller's own private key. Used transiently to sign; never stored (non-custodial). | |
| sell_amount | Yes | Amount of sell_token (base units). | |
| fee_recipient | No | Optional address to receive the integrator fee. | |
| max_fee_per_gas | Yes | EIP-1559 max fee per gas (wei). | |
| max_priority_fee_per_gas | Yes | EIP-1559 priority fee per gas (wei). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description bears full burden. It mentions 'non-custodial' and 'built-in fee' but omits key behaviors like transaction signing, broadcasting, potential failures, gas implications, or finality. Unclear how the tool executes the swap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence with no superfluous content. It front-loads the core function and key attributes, earning its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (11 parameters, private key, transaction execution), the description lacks essential context. No mention of return value, transaction submission, or supported chains. Insufficient for safe invocation without additional documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, setting baseline at 3. The description adds minor context (built-in fee, non-custodial) beyond the schema, but does not explain parameter semantics in depth or clarify optional parameters like fee_recipient.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool swaps tokens via a DEX aggregator, distinct from siblings like 'send' or 'bridge'. It specifies the resource (tokens) and method (DEX aggregator), with added context on fees and custody.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for token swapping but provides no explicit guidance on when to use versus alternatives or when not to use. No mention of prerequisites or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
9 tool updates
v0.5.31- First observed
bridge - First observed
call_contract - First observed
check_action - First observed
create_wallet - First observed
get_balance - First observed
inspect_signature - First observed
preflight - First observed
send - First observed
swap
TDQS
Scored across 9 tools
Each tool targets a distinct operation: bridging, contract calls, policy enforcement, wallet creation, balance checks, signature inspection, transaction preflight, native sends, and token swaps. No two tools have overlapping purposes; safety tools are clearly separated from execution tools.
Most tools follow a verb_noun pattern (e.g., call_contract, create_wallet), but bridge, send, and swap are single verbs, and preflight is a noun. The naming is clear and readable despite minor inconsistency.
Nine tools is well-scoped for a chain-signing server. It covers wallet management, native and token transfers, contract interactions, bridging, and safety checks without being excessive or minimal.
The tool surface covers core signing workflows (send, swap, bridge, call_contract) and adds critical safety mechanisms (check_action, inspect_signature, preflight). Minor gaps like missing transaction history or plain message signing do not hinder the primary purpose.
Maintenance
Related MCP Connectors
DeFi safety layer for AI agents: wallet safety, token risk, tx decode/simulate. 20 tools.
Read-only crypto safety: token honeypot checks, EIP-712 signature decode, approval scans.
Solana pre-trade safety for agents: rug check, honeypot sell-sim, drainer scan, tx preflight.
Pay-per-call safety checks for AI agents: screen a crypto address or URL before you transact.
Related MCP Servers
- AlicenseAqualityDmaintenanceSafety layer for autonomous DeFi agents. Scans contracts for exploit patterns, simulates transactions, blocks honeypots.410 npm1MIT
- AlicenseNot gradedqualityDmaintenancePre-execution safety layer for autonomous agent wallets. Risk scoring, transaction simulation, and policy enforcement via MCP.MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to analyze Ethereum wallets, simulate transactions, and draft transfers with deterministic policy and risk scoring, requiring human approval before on-chain execution.7 npmISC
- AlicenseNot gradedqualityCmaintenanceSecurity layer for AI agents that evaluates transaction intents and returns verdicts (ALLOW/WARN/DENY) using deterministic rules, on-chain checks, and simulation.4 npmMIT