Agent Tool Registry (ERC-8257)
Build, register, and gate AI agent tools onchain using the ERC-8257 Tool Registry.
ERC-8257 defines a permissionless onchain registry for AI agent tools. Any developer can register a tool, gate access with an onchain predicate (NFT ownership, subscriptions, allowlists, or custom logic), and optionally charge per call using x402 micropayments, all without a centralized platform.
How It Works
A tool is an HTTPS endpoint with a JSON Schema interface, discoverable through a .well-known manifest. The lifecycle:
- Build an endpoint that accepts JSON input and returns JSON output, then serve a manifest at
/.well-known/ai-tool/<slug>.json. - Register it by calling
registerToolon the onchain registry with your manifest URI and its keccak256 hash. The registry assigns atoolId. - Gate it (optional) by attaching an access predicate contract that controls who can invoke the tool, or leave it as
address(0)for open access.
+-----------------+ +---------------------+ +-----------+
| PUBLISHER |---->| TOOL REGISTRY |<----| AGENT |
| | | | | |
| serves manifest | | | | discovers |
| + handler | | creator | | verifies |
| | | metadataURI | | checks |
| | | manifestHash | | access |
| | | accessPredicate | | invokes |
+-----------------+ +---------------------+ +-----------+
Agents discover tools by reading the registry, verify the manifest hash, check access via the predicate, and invoke the endpoint.
Key Concepts
| Term | Description |
|---|---|
| Tool | HTTPS endpoint with a JSON Schema interface, discoverable via /.well-known/ai-tool/<slug>.json |
| Manifest | JCS-canonicalized JSON describing name, endpoint, inputs, outputs, pricing, and access policy |
| Access Predicate | An IAccessPredicate contract that gates who can invoke a tool (NFT ownership, subscriptions, traits, composites, or any custom logic) |
| x402 | HTTP 402-based pay-per-call protocol using USDC TransferWithAuthorization |
| EIP-3009 auth | Zero-value USDC TransferWithAuthorization signature for authenticating callers |
Quick Start
The @opensea/tool-sdk handles the whole lifecycle: scaffold, deploy, register, gate, and call tools.
# 1. Scaffold a new tool (generates manifest, handler, adapter, and .well-known route)
npx @opensea/tool-sdk init my-tool --runtime vercel
cd my-tool && npm install
# 2. Edit src/manifest.ts and src/handler.ts with your logic
# 3. Deploy
npx @opensea/tool-sdk deploy
# 4. Register onchain (configure a wallet provider, see the SDK README)
# Supports: Privy, Turnkey, Fireblocks, Bankr, or a local private key
# 4a. Open access (no gate)
npx @opensea/tool-sdk register \
--metadata https://my-tool.vercel.app/.well-known/ai-tool/my-tool.json \
--network base
# 4b. NFT-gated access
npx @opensea/tool-sdk register \
--metadata https://my-tool.vercel.app/.well-known/ai-tool/my-tool.json \
--network base \
--nft-gate 0xCOLLECTION_ADDRESSSee the Tool SDK README for the full CLI reference, handler examples, adapter setup (Vercel, Cloudflare, Express), wallet providers, and predicate configuration.
Access Control
Access control is extensible: any contract that implements IAccessPredicate can gate a tool:
interface IAccessPredicate {
function hasAccess(uint256 toolId, address account, bytes calldata data) external view returns (bool);
function name() external view returns (string memory);
}The Tool Registry repo includes reference predicate implementations for common access patterns: NFT ownership (ERC-721/1155), subscriptions, trait gating, pay-per-call (x402), and composite logic. See the repo for deployed addresses and supported chains.
Tool Invocation Flow
Both free (predicate-gated) and paid (x402) tools use a unified 402 challenge-response pattern. The caller never pre-computes auth — the server tells it what to sign.
CALLER TOOL SERVER
| |
| 1. POST /tool (no auth) |
|-------------------------------->|
| |
| 2. 402 + PaymentRequirements |
|<--------------------------------|
| |
| 3. Sign X-Payment (EIP-3009) |
| |
| 4. POST /tool + X-Payment hdr |
|-------------------------------->|
| |
| 5. Verify signature (ecrecover)|
| 6. Check access predicate |
| 7. Execute handler |
| |
| 8. 200 + tool output |
|<--------------------------------|
| |
Step-by-step
| Step | Description |
|---|---|
| 1. Initial request | Caller sends a plain POST — no Authorization or X-Payment header. |
| 2. 402 challenge | Server returns 402 with a body containing accepts: [{ scheme, network, payTo, maxAmountRequired, asset }]. For free tools maxAmountRequired is "0"; for paid tools it is the USDC price. |
| 3. Sign X-Payment | Caller signs an EIP-3009 TransferWithAuthorization (EIP-712 typed data in the USDC domain) using payTo and maxAmountRequired from the challenge. The signature is wrapped into a PaymentPayload and base64-encoded. |
| 4. Retry with header | Caller replays the request with X-Payment: <base64(PaymentPayload)>. |
| 5. Verify | Server decodes and verifies the signature via pure ecrecover — no RPC needed. Asserts to == operatorAddress (domain binding) and checks TTL. |
| 6. Access check | Server calls tryHasAccess(toolId, callerAddress, data) on the onchain registry. Returns 403 if granted: false. |
| 7. Execute | Handler runs if access is granted. For paid tools, the x402 facilitator settles payment onchain after the predicate check passes — if access is denied, no funds move. |
| 8. Response | Tool output returned as JSON. |
X-Payment payload structure
{
"x402Version": 1,
"scheme": "exact",
"network": "base",
"payload": {
"signature": "0x...",
"authorization": {
"from": "0xCALLER",
"to": "0xOPERATOR",
"value": "0 (free) or amount in base units (paid)",
"validAfter": "0",
"validBefore": "1749158400",
"nonce": "0x<random-32-bytes>"
}
}
}The to field is always the payTo address from the 402 challenge — the tool operator for free tools, or the payment recipient for paid tools. This prevents cross-tool signature replay.
Combined predicate + payment
Tools that require both an access predicate and x402 payment use the SDK's paidPredicateGate — a single gate that resolves identity and payment in one 402 round trip. The 402 challenge advertises the real USDC price (not zero). The caller's X-Payment signature for the real amount simultaneously proves identity (via the recovered from address) and authorizes payment. The onchain predicate is checked before the facilitator settles, so if the caller lacks access a 403 is returned and no funds move.
Usage Reporting
After a tool invocation completes, the Tool SDK reports usage to the OpenSea API before returning the response. The report is awaited so it survives serverless runtimes (Vercel, Lambda) where the function freezes once the response flushes. Errors are caught — a failed report never turns a successful tool call into a failure.
POST https://api.opensea.io/api/v2/tools/usage
x-api-key: <tool-service-api-key>
The report includes an ERC-8257 composite key (tool_chain_id, tool_registry_address, tool_onchain_id) and one of two verification types depending on the invocation path:
Free tools (predicate-gated)
{
"verification_type": "eip3009_authorization",
"tool_chain_id": 8453,
"tool_registry_address": "0x...",
"tool_onchain_id": "42",
"latency_ms": 120,
"eip3009": {
"caller_address": "0xCALLER",
"signature": "0x...",
"from": "0xCALLER",
"to": "0xOPERATOR",
"value": "0",
"valid_after": "0",
"valid_before": "1749158400",
"nonce": "0x..."
}
}The caller's original zero-value EIP-3009 signature from the X-Payment header is forwarded as-is — the tool server never re-signs.
Paid tools (x402)
{
"verification_type": "x402_settlement",
"tool_chain_id": 8453,
"tool_registry_address": "0x...",
"tool_onchain_id": "42",
"latency_ms": 250,
"x402": {
"caller_address": "0xCALLER",
"tx_hash": "0x...",
"chain_id": 8453
}
}The settlement transaction hash from the x402 facilitator is included, enabling onchain payment verification.
The usage reporter has a 5-second timeout. If the report fails or times out, the tool invocation still succeeds — errors are logged but never propagated to the caller.
REST API: Tool Endpoints
The OpenSea API provides endpoints for discovering and retrieving registered tools, returning enriched data including NFT collection details (name, image, floor price) for predicate-gated tools.
List tools
List all registered tools with optional sorting and filtering:
curl "https://api.opensea.io/api/v2/tools?sort_by=newest&limit=10" \
-H "x-api-key: YOUR_API_KEY"See the List Tools API reference for all parameters and the full response schema.
Search tools
Find tools by keyword, tags, access type, creator, or chain:
curl "https://api.opensea.io/api/v2/tools/search?query=nft&limit=10" \
-H "x-api-key: YOUR_API_KEY"See the Search Tools API reference for all parameters and the full response schema.
Get a tool
Retrieve a specific tool by its registry chain, registry address, and tool ID:
curl "https://api.opensea.io/api/v2/tools/{chain}/{registry_address}/{tool_id}" \
-H "x-api-key: YOUR_API_KEY"See the Get Tool API reference for the full response schema.
Don't have an API key yet? See Instant API Key to grab one for free.
MCP & CLI
The Tool Registry endpoints are also available through the MCP Server (search_tools, get_tool, get_wallet_tools) and the CLI:
# CLI: search, list, or get tools
opensea tools search --query "nft" --access-type open
opensea tools list --sort-by newest --limit 10
opensea tools get 8453 0xRegistryAddr 42Agent Skill
The OpenSea Agent Skill includes a dedicated sub-skill for building and registering tools. If you're using an AI coding assistant (Claude Code, Cursor, Windsurf, etc.):
npx skills add ProjectOpenSea/opensea-skillThen prompt: "Register an NFT-gated tool on Base", "Scaffold a new tool with x402 payments", etc.
Resources
| Resource | Description |
|---|---|
| Tool SDK | TypeScript SDK and CLI to build, register, gate, and call tools |
| Tool Registry | Solidity contracts, deployed addresses, and supported chains |
| ERC-8257 Specification | Full standard |
| 8257.ai | Interactive overview and walkthrough |
| List Tools [Beta] | List all registered tools with sorting and filtering |
| Search Tools [Beta] | Discover registered tools by keyword, tags, access type, or chain |
| Get Tool [Beta] | Retrieve a specific tool with enriched NFT collection data |
| OpenSea MCP Server | MCP tools for tool discovery: search_tools, get_tool, get_wallet_tools |
| OpenSea CLI | CLI commands: opensea tools search, opensea tools list, opensea tools get |
| Build with AI Agents | Integrate OpenSea data into AI workflows |
| ERC-8257 Telegram | Community discussion |
