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:

  1. Build an endpoint that accepts JSON input and returns JSON output, then serve a manifest at /.well-known/ai-tool/<slug>.json.
  2. Register it by calling registerTool on the onchain registry with your manifest URI and its keccak256 hash. The registry assigns a toolId.
  3. 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

TermDescription
ToolHTTPS endpoint with a JSON Schema interface, discoverable via /.well-known/ai-tool/<slug>.json
ManifestJCS-canonicalized JSON describing name, endpoint, inputs, outputs, pricing, and access policy
Access PredicateAn IAccessPredicate contract that gates who can invoke a tool (NFT ownership, subscriptions, traits, composites, or any custom logic)
x402HTTP 402-based pay-per-call protocol using USDC TransferWithAuthorization
EIP-3009 authZero-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_ADDRESS

See 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

StepDescription
1. Initial requestCaller sends a plain POST — no Authorization or X-Payment header.
2. 402 challengeServer 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-PaymentCaller 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 headerCaller replays the request with X-Payment: <base64(PaymentPayload)>.
5. VerifyServer decodes and verifies the signature via pure ecrecover — no RPC needed. Asserts to == operatorAddress (domain binding) and checks TTL.
6. Access checkServer calls tryHasAccess(toolId, callerAddress, data) on the onchain registry. Returns 403 if granted: false.
7. ExecuteHandler 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. ResponseTool 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 42

Agent 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-skill

Then prompt: "Register an NFT-gated tool on Base", "Scaffold a new tool with x402 payments", etc.

Resources

ResourceDescription
Tool SDKTypeScript SDK and CLI to build, register, gate, and call tools
Tool RegistrySolidity contracts, deployed addresses, and supported chains
ERC-8257 SpecificationFull standard
8257.aiInteractive 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 ServerMCP tools for tool discovery: search_tools, get_tool, get_wallet_tools
OpenSea CLICLI commands: opensea tools search, opensea tools list, opensea tools get
Build with AI AgentsIntegrate OpenSea data into AI workflows
ERC-8257 TelegramCommunity discussion