8004-MCP - Agent Registry Protocol
Multi-chain MCP server for ERC-8004 Agent Registry. Query agents, reputation, and feedback across Solana + EVM chains.
⚡ First Time Setup (IMPORTANT)
1. Check System Health
await client.callTool({ name: 'health_check', arguments: {} });
// Returns: { server: 'ok', chains: {...}, walletStore: 'not_initialized', ... }
2. Initialize Wallet Store (One-Time)
The wallet store encrypts all your wallets with a single master password.
// ⚠️ SAVE THIS PASSWORD - Cannot be recovered if lost!
await client.callTool({ name: 'wallet_store_init', arguments: {
password: 'YourSecureMasterPassword123!'
}});
// Returns: { initialized: true, message: 'Wallet store created' }
3. Create a Wallet
await client.callTool({ name: 'wallet_create', arguments: {
name: 'my-eth-wallet',
chainType: 'evm' // or 'solana'
}});
// Returns: { name: 'my-eth-wallet', address: '0x...', chainType: 'evm' }
4. Fund Your Wallet
Use faucet_info on testnet, or agent_register({ estimateCost: true }) if you need an execution estimate.
// Get faucet info (testnet) or ask owner (mainnet)
const funding = await client.callTool({ name: 'faucet_info', arguments: {
chain: 'eth' // or 'sol', 'base'
}});
// Returns faucet URLs and wallet address
⚠️ Important for Agents:
- Faucets require captchas - you can't use them directly
- Ask your owner to fund your wallet
- On mainnet: no faucets, must ask owner for real funds
5. On New Sessions - Unlock Store
await client.callTool({ name: 'wallet_store_unlock', arguments: {
password: 'YourSecureMasterPassword123!'
}});
// Now all write operations work
Common Issues
| Symptom | Cause | Solution |
|---|---|---|
STORE_NOT_INITIALIZED |
First run | Call wallet_store_init |
STORE_LOCKED |
New session | Call wallet_store_unlock |
INVALID_PASSWORD |
Wrong password | Check password (no recovery!) |
| Timeout on wallet ops | Store locked | Unlock first |
INSUFFICIENT_BALANCE |
Empty wallet | Ask owner to fund (see below) |
Requesting Funds from Owner
As an agent, you cannot use faucets directly (captchas). Ask your owner:
// 1. Get your wallet address
const info = await client.callTool({ name: 'faucet_info', arguments: { chain: 'eth' }});
// 2. Ask owner to fund this exact wallet
// Optional: use agent_register({ estimateCost: true }) first if you need an estimate
// 3. Wait for owner to send funds, then proceed with agent_register
Quick Start (MCP Client)
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
const client = new Client(
{ name: 'my-agent', version: '1.0.0' },
{ capabilities: {} }
);
await client.connect(new StdioClientTransport({
command: 'node',
args: ['/absolute/path/to/8004-mcp/dist/index.js'],
env: { ...process.env, NETWORK_MODE: 'testnet', SOLANA_CLUSTER: 'devnet' }
}));
// Ready - use client.callTool()
Global ID Format
| Chain | Format | Example |
|---|---|---|
| Solana | sol:<pubkey> |
sol:HHCVWcqs... |
| Ethereum | eth:<chainId>:<tokenId> |
eth:11155111:738 |
| Base | base:<chainId>:<tokenId> |
base:84532:42 |
Core Tools
Read Operations (No wallet needed)
agent_search
Search agents across chains.
await client.callTool({ name: 'agent_search', arguments: {
query: 'trading bot', // Search name/description
// Omit `chain` for default cross-chain discovery across all deployed chains
chain: 'eth', // Optional: sol, eth, base, poly, bsc, monad, all
limit: 20, // Default: 20, max: 100
offset: 0, // Pagination offset
// Advanced filters (EVM only):
hasMcp: true, // Has MCP endpoint
hasA2a: true, // Has A2A endpoint
active: true, // Active agents only
x402support: true, // Supports x402 payments
mcpTools: ['web-search'], // Has specific MCP tools
a2aSkills: ['translation'] // Has specific A2A skills
}});
// Returns: { results: IAgentSummary[], total, hasMore, offset, limit }
For priority discovery flows, prefer calling agent_search without chain first, then narrow to a specific chain only if you need to scope or compare results.
cache_search
Fast fuzzy search (FTS5). Use for partial name matches.
await client.callTool({ name: 'cache_search', arguments: {
query: 'Upsense', // Partial match works
chain: 'all',
limit: 20
}});
agent_get
Get agent details by ID.
await client.callTool({ name: 'agent_get', arguments: {
id: 'eth:11155111:738' // Global ID
}});
// Returns: IAgent with name, description, owner, endpoints, metadata
agent_exists
Check if agent exists.
await client.callTool({ name: 'agent_exists', arguments: {
id: 'sol:HHCVWcqs...'
}});
// Returns: { exists: boolean }
reputation_get
Get reputation summary.
await client.callTool({ name: 'reputation_get', arguments: {
id: 'sol:HHCVWcqs...'
}});
// Returns: { averageScore, totalFeedbacks, trustTier (Solana only) }
feedback_list
List feedbacks for an agent.
await client.callTool({ name: 'feedback_list', arguments: {
id: 'sol:HHCVWcqs...',
limit: 20,
minScore: 50 // Optional filter
}});
leaderboard_get
Top agents by reputation.
await client.callTool({ name: 'leaderboard_get', arguments: {
chain: 'sol',
limit: 10
}});
solana_atom_stats_get
ATOM reputation metrics (Solana only).
await client.callTool({ name: 'solana_atom_stats_get', arguments: {
asset: 'HHCVWcqs...' // Solana pubkey (no sol: prefix)
}});
// Returns: { qualityScore, trustTier, uniqueClients, fastEma, slowEma }
solana_integrity_verify
Verify indexer data integrity (Solana only).
await client.callTool({ name: 'solana_integrity_verify', arguments: {
asset: 'HHCVWcqs...'
}});
// Returns: { status: 'valid' | 'syncing' | 'corrupted' }
Write Operations (Wallet required)
Wallet Store Setup (Master Password)
// 1. Initialize store (one-time) - SAVE THE MASTER PASSWORD!
await client.callTool({ name: 'wallet_store_init', arguments: {
password: 'MySecureMaster123!'
}});
// 2. Create wallets (stored in encrypted store)
await client.callTool({ name: 'wallet_create', arguments: {
name: 'my-solana',
chainType: 'solana' // or 'evm'
}});
// 3. On new session, unlock store with master password
await client.callTool({ name: 'wallet_store_unlock', arguments: {
password: 'MySecureMaster123!'
}});
// 4. Now write operations work (all wallets unlocked)
feedback_give
Submit feedback for an agent.
await client.callTool({ name: 'feedback_give', arguments: {
id: 'sol:HHCVWcqs...',
value: "85.00", // Metric value
score: 85, // Optional quality score 0-100
tag1: 'uptime', // Category tag
tag2: 'day', // Period tag
comment: 'Great agent', // Optional
skipSend: false // true = dry-run (returns unsigned tx)
}});
agent_register
Register new agent on-chain. Use estimateCost: true if you need a cost estimate before sending.
await client.callTool({ name: 'agent_register', arguments: {
chain: 'eth', // or 'sol', 'base', etc.
name: 'My Agent',
description: 'Does cool stuff',
tokenUri: 'https://example.com/agent.json', // Optional: your hosted metadata
// If no tokenUri: 8004-mcp uploads via the Studio backend endpoint automatically
}});
Dry-Run Mode (skipSend)
Test write operations without funds or broadcasting:
// Returns unsigned transaction, no funds needed
const preview = await client.callTool({ name: 'feedback_give', arguments: {
id: 'sol:HHCVWcqs...',
value: "85.00",
score: 85,
tag1: 'uptime',
skipSend: true // Dry-run
}});
// preview.content[0].text contains: { unsigned: true, transaction: "base64...", message: "..." }
Supported on: feedback_give, agent_register, agent_transfer, agent_uri_update, feedback_revoke, solana_validation_request, solana_validation_respond
Note: agent_register({ skipSend: true }) is supported on Solana only. EVM registration does not support skipSend.
Network Configuration
// Check current network
await client.callTool({ name: 'network_get', arguments: {} });
// Switch to mainnet
await client.callTool({ name: 'network_set', arguments: { mode: 'mainnet' } });
// Switch to testnet (default)
await client.callTool({ name: 'network_set', arguments: { mode: 'testnet' } });
| Network | Solana | Ethereum | Base |
|---|---|---|---|
| testnet | devnet | Sepolia (11155111) | Base Sepolia (84532) |
| mainnet | mainnet-beta | Mainnet (1) | Base (8453) |
x402 Protocol
Payment-linked reputation.
// 1. Build identity for 402 response
const identity = await client.callTool({ name: 'x402_identity_build', arguments: {
agentId: 'sol:HHCVWcqs...'
}});
// 2. Parse payment proof from response header
const proof = await client.callTool({ name: 'x402_proof_parse', arguments: {
paymentResponse: 'base64-encoded-header...'
}});
// 3. Submit feedback with proof
await client.callTool({ name: 'x402_feedback_submit', arguments: {
agentId: 'sol:HHCVWcqs...',
value: 90,
tag1: 'x402-resource-delivered',
tag2: 'exact-svm',
proofOfPayment: proof.proofOfPayment
}});
Error Codes
| Error | Cause | Solution |
|---|---|---|
STORE_LOCKED |
Write op without unlock | Call wallet_store_unlock with master password |
STORE_NOT_INITIALIZED |
No wallet store | Call wallet_store_init first |
INVALID_PASSWORD |
Wrong master password | Check password (cannot recover if lost) |
AGENT_NOT_FOUND |
Invalid ID | Verify global ID format |
INSUFFICIENT_BALANCE |
Wallet empty | Fund wallet address |
PROVIDER_NOT_AVAILABLE |
Chain not initialized | Check network_get |
OASF Standards
// List valid skill slugs
await client.callTool({ name: 'oasf_list_skills', arguments: {} });
// List valid domain slugs
await client.callTool({ name: 'oasf_list_domains', arguments: {} });
// List feedback tags
await client.callTool({ name: 'oasf_list_tags', arguments: {} });
All Tools Reference
Agent Operations
agent_get- Get agent by IDagent_exists- Check existenceagent_search- Search with filtersagent_list_by_owner- List by owner addressagent_register- Register new agent (write)agent_transfer- Transfer ownership (write)agent_uri_update- Update metadata URI (write)agent_metadata_set- Set on-chain metadata (Solana, write)
Feedback Operations
feedback_give- Submit feedback (write)feedback_read- Read single feedbackfeedback_list- List feedbacksfeedback_revoke- Revoke feedback (write)feedback_response_append- Respond to feedback (write)
Reputation Operations
reputation_get- Get summaryleaderboard_get- Top agents
Collection Operations
collection_get- Get collection detailscollection_list- List collectionscollection_agents- List agents in collectioncollection_base_get- Get base registrycollection_create- Create collection (Solana, write)collection_uri_update- Update collection URI (Solana, write)
collection_get, collection_list, and collection_base_get are currently Solana-only. collection_list fetches the full set first and then applies limit/offset.
Wallet Store (Master Password)
wallet_store_init- Initialize store with master passwordwallet_store_unlock- Unlock all wallets with master passwordwallet_store_lock- Lock store (secure wipe)wallet_store_status- Get store statuswallet_store_change_password- Change master passwordwallet_store_migrate- Migrate legacy wallets
Wallet Operations
wallet_list- List wallets in storewallet_info- Wallet detailswallet_create- Create new wallet (requires unlocked store)wallet_import- Import private key (requires unlocked store)wallet_delete- Delete wallet (requires unlocked store)wallet_security- Configure auto-lock timeout
Cache Operations
cache_search- Fast FTS5 searchcache_refresh- Force refreshcache_stats- Cache statisticscache_sync_status- Sync status
Solana-Specific
solana_atom_stats_get- ATOM metricssolana_atom_stats_initialize- Init ATOM account (write)solana_trust_tier_get- Trust tiersolana_enriched_summary_get- Combined metricssolana_agent_wallet_get- Get operational walletsolana_sign- Sign with agent walletsolana_verify- Verify signaturesolana_validation_request- Request validation (write)solana_validation_respond- Respond to validation (write)solana_validation_read- Read validationsolana_validation_wait- Wait for responsesolana_validation_pending_get- Archived compatibility shim, not a supported live indexer readsolana_integrity_verify- O(1) integrity checksolana_integrity_verify_deep- Deep verification
EVM-Specific
evm_agent_wallet_set- Set operational wallet (write)evm_agent_wallet_unset- Remove operational wallet (write)
x402 Protocol
x402_identity_build- Build agent identityx402_proof_parse- Parse payment proofx402_feedback_build- Build feedback filex402_feedback_submit- Submit with proof (write)
Configuration & Health
config_get- Current configconfig_set- Update configconfig_reset- Reset to defaultsnetwork_get- Network statusnetwork_set- Switch networkhealth_check- System health (server, chains, wallet store, cache)faucet_info- Testnet faucet URLs and funding info
OASF Standards
oasf_list_skills- Valid skill slugsoasf_list_domains- Valid domain slugsoasf_list_tags- Feedback tagsoasf_validate_skill- Validate skilloasf_validate_domain- Validate domainoasf_validate_tag- Validate tag
Crawler
crawler_fetch_mcp- Fetch MCP capabilitiescrawler_fetch_a2a- Fetch A2A agent cardcrawler_is_alive- Health check
IPFS
ipfs_configure- Override the Studio MCP upload endpoint settings (optional)ipfs_add_json- Store JSON (max 100KB)ipfs_add_registration- Store registration fileipfs_add_image- Store image data (max 512KB)ipfs_get_registration- Retrieve registration
Note: automatic uploads use the Studio MCP upload endpoint by default.
ipfs_configureis only needed if you want to override that behavior, andPINATA_JWTremains supported as an advanced env override.
Claude Code Integration
This section is for Claude Code / AI assistants using 8004-MCP tools.
Intent Mapping
| User Says | Tool | Notes |
|---|---|---|
| "find agents", "search for X" | agent_search or cache_search |
Use cache_search for partial names |
| "agent details", "info on X" | agent_get |
Pass global ID |
| "is X reliable?", "reputation" | reputation_get |
Returns score + trust tier |
| "top agents", "best agents" | leaderboard_get |
Chain optional |
| "reviews for X", "feedback" | feedback_list |
|
| "my wallets" | wallet_list |
|
| "switch to mainnet" | network_set |
mode: 'mainnet' |
| "OASF skills/domains/tags" | oasf_list_* |
DO NOT use web search for:
- Agent registry queries (use 8004 tools)
- Reputation/feedback lookups
- OASF standards
- x402 protocol
Search Strategy
- Exact name known →
agent_searchwithnameQuery - Partial name →
cache_search(fuzzy FTS5) - By capabilities →
agent_searchwithhasMcp,hasA2a,mcpTools, etc. - By owner →
agent_searchwithowner
Write Operation Flow
- Check
wallet_store_status- is store initialized and unlocked? - If not initialized:
wallet_store_init(save master password!) - If locked:
wallet_store_unlockwith master password - If no wallet:
wallet_createfor needed chain - Execute write operation
- Report transaction hash on success