# Chain Daddy (npm · @chaindaddy/mcp)

Search tokens, check registrations, and run a Chain Daddy creator store from your agent.

- Trust score: 81/100 (high trust)
- Change this week: +3
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-10-23

## Components

- remote · `api.chaindaddy.io`: 77/100, [markdown](https://verifymcp.io/servers/io-chaindaddy-mcp/api.md), [page](https://verifymcp.io/servers/io-chaindaddy-mcp/api)
- npm · `@chaindaddy/mcp`: 81/100 (this document), [markdown](https://verifymcp.io/servers/io-chaindaddy-mcp/chaindaddy-mcp.md), [page](https://verifymcp.io/servers/io-chaindaddy-mcp/chaindaddy-mcp)

## Channel facts

- Registry: `npm`
- Package: `@chaindaddy/mcp`
- Version: `0.6.16`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-10-23.

- **Supply Chain Security**: 98/100
  - No malware found by supply-chain analysis.
  - No known CVEs affecting this package version or its production dependencies.
  - No install/post-install scripts declared.
  - 37 of 115 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 71/100
  - Repository check failed: no source repository is declared.
  - Cryptographically verified build provenance (signed, bound to opencrown/chaindaddy-mcp).
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 1 days ago).
  - Security-disclosure policy not yet verified: we couldn't inspect the source repository.
- **Schema Quality & AI Usability**: 67/100
  - 75% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (good).
  - Context-footprint check failed: tool/resource definitions use about 9861 tokens (~186/item across 53 items; 50 tools + 3 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 61/100
  - Stability check failed: the tool surface changed between 0.6.0 and 0.6.16: 3 tool removals, 0 breaking changes, 0 additions.
- **Tool Coverage**: 94/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 78% of tool parameters carry a description.
  - Structured output schemas are declared (2% of tools); any adoption earns full credit.
- **Tool Safety**: 96/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - 6 of 7 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "deploy_token" implies "deploy" and declares readOnlyHint instead, contradicting what its own name says it does.
  - An AI judge read all 52 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### How do I install the Chain Daddy MCP server?

Chain Daddy runs locally as an npm package, launched with npx -y @chaindaddy/mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add io-chaindaddy-mcp -- npx -y @chaindaddy/mcp
```

### Cursor

```json
{
  "mcpServers": {
    "io-chaindaddy-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@chaindaddy/mcp"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "io-chaindaddy-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@chaindaddy/mcp"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add io-chaindaddy-mcp -- npx -y @chaindaddy/mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "io-chaindaddy-mcp": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "@chaindaddy/mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add io-chaindaddy-mcp --command npx --arg -y --arg @chaindaddy/mcp
```

### Hermes

```yaml
mcp_servers:
  io-chaindaddy-mcp:
    command: "npx"
    args: ["-y", "@chaindaddy/mcp"]
```

### Netclaw

```json
{
  "McpServers": {
    "io-chaindaddy-mcp": {
      "Transport": "stdio",
      "Command": "npx",
      "Arguments": [
        "-y",
        "@chaindaddy/mcp"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add io-chaindaddy-mcp -t stdio -c npx -a -y @chaindaddy/mcp
```

### Other

```json
{
  "mcpServers": {
    "io-chaindaddy-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@chaindaddy/mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-10-22 (score 81, +15)

- [security improvement] Malware scan: unverified → pass

### 2026-10-21 (score 66, −14)

- [security regression] Malware scan: pass → unverified
- [functional] Package version: 0.6.2 → 0.6.16

### 2026-10-19 (score 80, +1)

No change was recorded against any check on this day. Stability & Change Management went from 44 to 48.

### 2026-10-17 (score 79, +1)

No change was recorded against any check on this day. Stability & Change Management went from 38 to 41.

### 2026-10-15 (score 78, +1)

No change was recorded against any check on this day. Stability & Change Management went from 31 to 34.

### 2026-10-13 (score 77, +1)

No change was recorded against any check on this day. Stability & Change Management went from 24 to 28.

### 2026-10-11 (score 76, +2)

No change was recorded against any check on this day. Stability & Change Management went from 8 to 21.

### 2026-10-07 (score 74, +1)

No change was recorded against any check on this day. Stability & Change Management went from 0 to 8.

## MCP tools (50)

### `get_auth_nonce` (~52 tokens)

Get sign-in nonce

Step 1 of authentication. Fetches a server-issued nonce the caller must embed in the SIWE/SIWS message before signing.

Params: none
Returns: {nonce: string}
Errors: API_ERROR

### `authenticate` (~195 tokens)

Sign in with a wallet signature

Step 2 of authentication. Exchanges a signed SIWE/SIWS message for a session bound to a backend JWT. Call get_auth_nonce first and embed the nonce in the message.

Params: wallet_address (string), chain_type ('evm'|'solana'), signed_message (string), signature (string)
Returns: {session_token: string, expires_at: string}
Errors: INVALID_SIGNATURE, INVALID_ADDRESS, UNSUPPORTED_CHAIN, JWT_EXCHANGE_FAILED

Input parameters:

- `chain_type` (string, required): Chain type: 'evm' or 'solana'
- `signature` (string, required): The signature of the message (hex for EVM, base58 for Solana)
- `signed_message` (string, required): The SIWE or SIWS message that was signed. Must include the server-issued nonce from get_auth_nonce.
- `wallet_address` (string, required): Wallet address (0x... for EVM, base58 for Solana)

### `get_session` (~91 tokens)

Get session status

Get the current session status for a session token. Returns authentication state, wallet, chain type, and expiry.

Params: session_token (string)
Returns: {authenticated: true, wallet: string, chain_type: 'evm'|'solana', expires_at: string} or {authenticated: false}
Errors: none (always returns a result)

Input parameters:

- `session_token` (string, required): Session token from authenticate

### `search_symbol` (~76 tokens)

Search a ticker

Search for a crypto ticker symbol across all supported chains. Returns availability status, existing tokens, market data, and crown ownership.

Input parameters:

- `chain` (string): Optional: Filter to specific chain
- `symbol` (string, required): The ticker symbol to search (1-20 alphanumeric chars, e.g., 'PEPE', 'DOGE')

### `get_token` (~56 tokens)

Get token details

Get detailed information about a token on a specific chain including crown status, market data, and metadata.

Input parameters:

- `chain` (string, required): The chain to query
- `symbol` (string, required): The ticker symbol (e.g., 'PEPE')

### `get_crown` (~78 tokens)

Get a token registration

Get detailed information about a specific crown by ID.

Params: crown_id (string)
Returns: {symbol, chain, owner, manager, heartbeat_score, status, metadata, days_in_grace, penalty_deadline}
Errors: CROWN_NOT_FOUND, API_ERROR

Input parameters:

- `crown_id` (string, required): Crown ID (token ID or identifier)

### `list_crowns` (~129 tokens)

List token registrations

List crowns with optional filters. All params optional.

Params: owner (string?), chain (string?), status (string?)
Returns: {crowns: [{symbol, chain, owner, manager, heartbeat_score, status, metadata, days_in_grace, penalty_deadline}]}
Errors: API_ERROR

Input parameters:

- `chain` (string): Filter by chain (e.g., 'arb', 'sol', 'base')
- `owner` (string): Filter by owner wallet address
- `status` (string): Filter by status (e.g., 'claimed', 'inactive', 'grace_period')

### `get_pricing` (~296 tokens)

Get pricing

Get what an order costs, as the order will charge it. mode 'create' (default): a new token on each chain, its registration included. mode 'claim': registering a token that already exists on each chain (free for an OG token when symbol and address are given). All params optional. Two or more chains take the 10% multi-chain bundle discount, already subtracted from total_usd.

Params: chains (string[]?), mode ('create'|'claim'?), symbol (string?), address (string?), bundle_type (string?), wallet_address (string?)
Returns: {items: [{chain, type, fee_usd, gas_estimate}], discounts: [{type, description, amount_usd}], total_usd: number}
Errors: API_ERROR

Input parameters:

- `address` (string): With mode 'claim': the token's contract or mint address, so an OG token shows as free
- `bundle_type` (string): Label for the bundle discount line only; the discount itself follows the number of chains
- `chains` (array): Chains to get pricing for (e.g., ['arb', 'sol'])
- `mode` (string): 'create' (default) prices a new token; 'claim' prices registering a token that already exists
- `symbol` (string): Token symbol for pricing context
- `wallet_address` (string): Accepted for compatibility; pricing does not depend on the wallet

### `get_deployments` (~71 tokens)

Find tokens a wallet can register

Find the tokens a wallet made on a chain (deployed, owns, or launched) that are not registered yet, and how it qualifies for each. Useful for finding tokens you can claim.

Input parameters:

- `address` (string, required): Wallet address (0x...)
- `chain` (string, required): Chain to search

### `check_eligibility` (~74 tokens)

Check registration eligibility

Check if a wallet is eligible to claim a crown for a specific token. Verifies deployer, owner, admin, or majority holder status.

Input parameters:

- `chain` (string, required): Chain where token exists
- `token_address` (string, required): Token contract address
- `wallet_address` (string, required): Wallet to check eligibility for

### `check_heartbeat` (~41 tokens)

Check token health

Get heartbeat status and activity score for a crown. Score below 60% means at-risk of reclaim.

Input parameters:

- `crown_id` (number, required): Crown token ID

### `export_listing` (~54 tokens)

Export listing data

Generate listing data formatted for aggregator platforms (CMC, CoinGecko, DEX Screener, TokenList).

Input parameters:

- `crown_id` (number, required): Crown token ID
- `format` (string, required): Export format for the listing data

### `get_holders` (~116 tokens)

Get holder stats

Get holder concentration and adversarial-label stats for a crown. Sourced from /api/v2/registration/{id}/holders; data refreshes daily.

Params: crown_id (number)
Returns: text report with totalHolders, top10/50/100/200 concentration, walletsForHalf, and Mobula label counts (snipers/bundlers/insiders/sandwich) plus suspiciousRatio.
Errors: CROWN_NOT_FOUND, NO_DATA, API_ERROR

Input parameters:

- `crown_id` (number, required): Crown token ID

### `get_recommendations` (~49 tokens)

Get page recommendations

Get AI-powered recommendations for optimizing crown profile, heartbeat, and listing readiness.

Input parameters:

- `crown_id` (number, required): Crown token ID
- `focus` (string): Optional: Focus area for recommendations

### `update_profile` (~398 tokens)

Update token page profile

Update crown profile metadata via PUT /api/v2/registration/{id}/profile?chain={chain}. Requires a session bound to a backend JWT (run authenticate first) and the session wallet must own or manage the crown on that chain.

Params: crown_id (string), chain (string; required, a token id names a different crown on every chain), description (string?), tags (string[]?), category ('meme'|'gaming'|'defi'|'nft'|'social'|'utility'?) [NOT FORWARDED — no backend route exposes category on the profile endpoint], website (string?), socials ({twitter?, telegram?, discord?}?), logo_url (string?), session_token (string)
Returns: {updated_fields: string[]}
Errors: NO_SESSION, SESSION_EXPIRED, NO_JWT, NOT_OWNER, NO_FIELDS, API_ERROR

Input parameters:

- `category` (string): Project category. ACCEPTED but NOT forwarded — the profile endpoint does not expose this field today; the input is preserved here for API stability.
- `chain` (string, required): Chain of the crown (e.g. 'base', 'arbitrum', 'solana'). Required: a token id names a different crown on every chain, and the role check and write happen on this one.
- `crown_id` (string, required): Crown ID (token ID)
- `description` (string): Token/project description
- `logo_url` (string): Logo image URL
- `session_token` (string, required): Session token from authenticate (must have been issued post-JWT-bridge, i.e. after fix/mcp-siwe-jwt-bridge)
- `socials` (object): Social links: {twitter, telegram, discord}. twitter maps to the backend `xdotcom` field.
- `tags` (array): Descriptive tags (e.g., ['meme', 'dog', 'community'])
- `website` (string): Project website URL

### `create_order` (~156 tokens)

Create an order

Create a pending order with one or more actions. Returns order details with pricing and gas estimates. Order expires after 5 minutes.

Params: actions (array of {type, params}), session_token (string), idempotency_key (string?)
Returns: {order_id, summary, total_cost, gas_estimates, expires_at, idempotency_key}
Errors: NO_SESSION, SESSION_EXPIRED, INVALID_ACTIONS, VALIDATION_ERROR

Input parameters:

- `actions` (array, required): Array of order actions to execute
- `idempotency_key` (string): Idempotency-Key for this write. Omit to generate one; reuse the returned idempotency_key to retry safely
- `session_token` (string, required): Session token from authenticate

### `confirm_order` (~149 tokens)

Confirm and execute an order

Confirm and execute a pending order. Triggers all actions in the order. Cannot be undone.

Params: order_id (string), session_token (string), idempotency_key (string?)
Returns: {results: [{action, status, tx_hash?, error?}], idempotency_key}
Errors: NO_SESSION, SESSION_EXPIRED, ORDER_NOT_FOUND, ORDER_EXPIRED, ORDER_ALREADY_CONFIRMED

Input parameters:

- `idempotency_key` (string): Idempotency-Key for this write. Omit to generate one; reuse the returned idempotency_key to retry safely
- `order_id` (string, required): Order ID from create_order
- `session_token` (string, required): Session token from authenticate

### `cancel_order` (~91 tokens)

Cancel an order

Cancel a pending order. Only works on orders that have not been confirmed.

Params: order_id (string), session_token (string)
Returns: {cancelled: true}
Errors: NO_SESSION, SESSION_EXPIRED, ORDER_NOT_FOUND, ORDER_EXPIRED, ORDER_ALREADY_CONFIRMED

Input parameters:

- `order_id` (string, required): Order ID from create_order
- `session_token` (string, required): Session token from authenticate

### `deploy_token` (~217 tokens)

Build a token creation action

Deploy a single token on a single chain. Validates parameters and returns an order action spec for inclusion in create_order.

Params: name (string), symbol (string), chain (string), supply (number), decimals (number), mintable (boolean), burnable (boolean), session_token (string)
Returns: {order_action_spec: {type, params}}
Errors: NO_SESSION, SESSION_EXPIRED, VALIDATION_ERROR, RATE_LIMITED

Input parameters:

- `burnable` (boolean, required): Whether tokens can be burned
- `chain` (string, required): Target chain (e.g., 'arb', 'sol', 'base', 'polygon', 'bsc', 'eth')
- `decimals` (number, required): Token decimals (0-18)
- `mintable` (boolean, required): Whether additional tokens can be minted
- `name` (string, required): Token display name
- `session_token` (string, required): Session token from authenticate
- `supply` (number, required): Total token supply
- `symbol` (string, required): Token symbol (1-10 uppercase alphanumeric)

### `list_launch_venues` (~239 tokens)

List Chain Daddy's launch options

Chain Daddy's launchpad and what it pays, per chain. The launchpad (chaindaddy-launchpad) creates the token with its own locked trading pool, on EVM chains and on Solana (Meteora DBC): nothing up front, and the token's registration is free. Every economics field is basis points of trade volume (100 = $1 per $100 traded); show both traderFeeBps (what traders pay) and creatorBps (what reaches the creator). For a plain token with no pool, Chain Daddy's token factory (chaindaddy-classic, a one-time fee, registration included) is the other option. Recommend the launchpad unless the person wants a plain token.

Params: chain_id (number?) — narrow to one chain (EVM chain id; Solana mainnet 900900), session_token (string?) — a signed-in session sees its own plan's rates
Returns: {venues: [...], sort, generatedAt}
Errors: API_ERROR

Input parameters:

- `chain_id` (number): Only this chain
- `session_token` (string): Optional session token from authenticate

### `claim_crown` (~237 tokens)

Build a registration claim action

Claim a crown for a specific token on a specific chain. Requires verified ownership. Returns an order action spec for inclusion in create_order.

Params: symbol (string), chain (string), token_address (string), verification_method ('deployer'|'mint_authority'|'owner'|'majority_holder'), session_token (string)
Returns: {order_action_spec: {type: 'claim_crown', params: {symbol, chain, token_address, verification_method, wallet}}}
Errors: NO_SESSION, SESSION_EXPIRED, INVALID_CHAIN, INVALID_VERIFICATION_METHOD

Input parameters:

- `chain` (string, required): Chain where the token exists (e.g., 'arb', 'sol', 'base', 'polygon', 'bsc', 'eth')
- `session_token` (string, required): Session token from authenticate
- `symbol` (string, required): Token symbol to claim crown for (e.g., 'PEPE')
- `token_address` (string, required): Token contract/mint address on the specified chain
- `verification_method` (string, required): Method used to verify ownership: 'deployer', 'mint_authority', 'owner', or 'majority_holder'

### `generate_listing` (~118 tokens)

Generate an aggregator listing

Generate a listing for one aggregator format using crown data.

Params: crown_id (string), format ('coingecko'|'coinmarketcap'|'dexscreener'|'tokenlist')
Returns: {listing_data: object, missing_fields?: string[]}
Errors: CROWN_NOT_FOUND, INVALID_FORMAT, API_ERROR

Input parameters:

- `crown_id` (string, required): Crown ID to generate listing for
- `format` (string, required): Listing format: 'coingecko', 'coinmarketcap', 'dexscreener', or 'tokenlist'

### `find_inactive` (~123 tokens)

Find inactive registrations

Find inactive crowns that are eligible for reclaim. All params optional.

Params: symbol (string?), chain (string?), min_market_cap (number?)
Returns: {inactive_crowns: [{symbol, chain, owner_address, last_activity, heartbeat_score, reclaim_cost}]}
Errors: API_ERROR

Input parameters:

- `chain` (string): Filter by chain (e.g., 'arb', 'sol', 'base')
- `min_market_cap` (number): Minimum market cap filter in USD
- `symbol` (string): Filter by symbol (e.g., 'DOGE')

### `search_symbols` (~150 tokens)

Search tickers with filters

Search for symbols across all supported chains. Returns availability, market data, and crown status.

Params: query (string), chain (string?), status (string?)
Returns: {results: [{symbol, chain, chain_name, status, token_address, market_cap, volume_24h, liquidity, crown_owner}]}
Errors: API_ERROR

Input parameters:

- `chain` (string): Filter by chain (e.g., 'arb', 'sol', 'base')
- `query` (string, required): Search query (symbol or partial match, e.g., 'DOGE', 'PEP')
- `status` (string): Filter by status (e.g., 'available', 'unclaimed', 'claimed', 'inactive')

### `iap_open_store` (~385 tokens)

Open a creator store

Open (or re-open) the creator store for a token page. Idempotent per token page. Needs a Developer plan or Developer Beta membership, and the manager role on the token page.

Params: page (the token page's symbol or address, e.g. 'FLUXGP' or 'chaindaddy.io/FLUXGP/base') OR chain_key (string, e.g. 'base') with crown_id (number, the token page's registration id); session_token?, idempotency_key?
Returns: {ok, idempotency_key, store: {id, chainId, chainKey, crownId, symbol, tokenAddress, tokenDecimals, tokenOrigin, feeBps, payoutAddress, status, live, …}}
Errors: NO_CREDENTIALS, NO_SESSION, NO_JWT, IAP_PLAN_REQUIRED, INVALID_PARAMS, PAGE_NOT_FOUND, PAGE_AMBIGUOUS (the symbol has several pages; the message lists them), HTTP_403, HTTP_404

Input parameters:

- `chain_key` (string): Chain key of the token page, e.g. 'base', 'solana' (with crown_id; or with page, to pick one of a symbol's pages)
- `crown_id` (integer): Registration id of the token page (with chain_key)
- `idempotency_key` (string): Idempotency-Key for this write. Omit to generate one; reuse the returned idempotency_key to retry safely
- `page` (string): The token page, instead of chain_key and crown_id: its symbol ('FLUXGP') or its address ('chaindaddy.io/FLUXGP/base')
- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)

### `iap_list_stores` (~187 tokens)

List creator stores

List the creator stores you manage, optionally filtered to one token page. Each entry's id is the store_id the other iap_ tools take.

Params: page? (the token page's symbol or address), chain_key?, crown_id?, session_token?
Returns: {entries: Store[]}
Errors: NO_CREDENTIALS, IAP_PLAN_REQUIRED, PAGE_NOT_FOUND, PAGE_AMBIGUOUS

Input parameters:

- `chain_key` (string)
- `crown_id` (integer)
- `page` (string): The token page, instead of chain_key and crown_id: its symbol ('FLUXGP') or its address ('chaindaddy.io/FLUXGP/base')
- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)

### `iap_list_skus` (~145 tokens)

List store items

List a store's SKUs, including drafts and archived ones.

Params: store_id, session_token?
Returns: {entries: Sku[]} (price is base units of the SKU's currency — currency, currencyAddress, currencySymbol, currencyDecimals; null = not for sale)
Errors: NO_CREDENTIALS, IAP_PLAN_REQUIRED, HTTP_404

Input parameters:

- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)
- `store_id` (string, required): Store id (from iap_open_store or iap_list_stores)

### `iap_create_sku` (~435 tokens)

Create a store item

Create a SKU. Types: consumable (a balance: coins, boosts), non_consumable (owned once: skins, cars), timed (expiry extended by durationSeconds × quantity: season pass), unlock (never sold; held while `rule` holds). No price = reward-only. Price in base units (`price`) or in dollars (`priceUsdMicros`, with optional per-unit `minPrice`/`maxPrice` bounds in base units), never both. `currency` is what the buyer pays in: 'token' (default; recommended with priceUsdMicros — a steady dollar price, paid in the creator's token), 'native' or 'usdc'. GET /api/v2/iap/config lists each chain's currencies. `grants` makes a bundle. `splits` pays up to 2 more wallets (3 on a launchpad token) a share of each sale. New SKUs are drafts unless status is 'active'. Store key scope: catalog:write.

Params: store_id, sku ({sku, type, name, currency?, price?, priceUsdMicros?, minPrice?, maxPrice?, grants?, splits?, durationSeconds?, rule?, maxSupply?, maxPerWallet?, maxAppSpend?, saleStartsAt?, saleEndsAt?, status?, metadata?, description?, imageUrl?, sortOrder?}), session_token?, idempotency_key?
Returns: {ok, idempotency_key, sku: Sku}
Errors: NO_CREDENTIALS, IAP_PLAN_REQUIRED, HTTP_400 (validation), HTTP_409 (sku key taken)

Input parameters:

- `idempotency_key` (string): Idempotency-Key for this write. Omit to generate one; reuse the returned idempotency_key to retry safely
- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)
- `sku` (object, required)
- `store_id` (string, required): Store id (from iap_open_store or iap_list_stores)

### `iap_update_sku` (~231 tokens)

Update a store item

Update a SKU's fields (partial). Set status 'active' to put a draft on sale, 'archived' to take it off. Setting `price` clears a dollar price (and its bounds); setting `priceUsdMicros` clears a fixed price. Changing `currency` needs `price` or `priceUsdMicros` in the same patch when the SKU has a fixed price, and clears the bounds. Store key scope: catalog:write.

Params: store_id, sku_key, patch (any SKU fields except the key), session_token?
Returns: {ok, sku: Sku}
Errors: NO_CREDENTIALS, IAP_PLAN_REQUIRED, HTTP_400, HTTP_404

Input parameters:

- `patch` (object, required)
- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)
- `sku_key` (string, required)
- `store_id` (string, required): Store id (from iap_open_store or iap_list_stores)

### `iap_list_orders` (~212 tokens)

List store orders

List a store's orders, newest first. Statuses: pending (awaiting payment), paid (seen on chain, confirming), confirmed (items granted, receipt issued), expired, refunded. A stray or duplicate payment never changes an order; it shows up as an order.mismatch / order.duplicate_payment event (iap_list_events). Store key scope: orders:read.

Params: store_id, status?, wallet?, cursor?, limit?, session_token?
Returns: {entries: Order[], nextCursor}
Errors: NO_CREDENTIALS, IAP_PLAN_REQUIRED

Input parameters:

- `cursor` (string)
- `limit` (integer)
- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)
- `status` (string)
- `store_id` (string, required): Store id (from iap_open_store or iap_list_stores)
- `wallet` (string)

### `iap_create_order` (~572 tokens)

Create a store order

Create an order for a user — the white-label path: your server sells from your app's own store with a store key (scope orders:write). The order locks the price, payees and a deadline (about 20 minutes) and carries `payment`: EVM {kind:'evm', chainId, checkout, order:{orderId, token, payees, amounts, deadline}, total, permit, calls?: [{to, data, value}] to send in order, permitTypedData?} or Solana {kind:'solana', cluster, transaction (base64 unsigned), reference, staticKey, memo}. The user's wallet pays; your client then posts the tx hash to /api/v2/iap/orders/{id}/submit, and the order turns confirmed at confirmation depth (poll iap_get_order or take the iap.order.confirmed webhook).

Params: store_id, sku, quantity?, wallet (the user's wallet; required with a store key), app_account_token? (your own account id, echoed in the receipt), session_token?, idempotency_key?
Returns: {ok, idempotency_key, order: Order}
Errors: NO_CREDENTIALS, IAP_PLAN_REQUIRED (store not live), HTTP_400, HTTP_404 (sku), HTTP_409 (sold out / per-wallet cap / rule not met), PRICE_UNAVAILABLE (a dollar-priced SKU paid in the token or the coin whose live price cannot be read reliably right now — stale, still warming up, or moving more than 15%; retry in a minute). The order carries currency (address), currencyKind ('token'|'native'|'usdc'), currencySymbol and currencyDecimals; `amount` is the exact locked amount in that currency. Paid in the chain's coin, `calls` holds only the pay call with value = total, and permit is null. A dollar-priced order also carries priceUsdMicros and usdPerToken (the dollar price of one whole unit of the currency; 1 for usdc).

Input parameters:

- `app_account_token` (string): Your app's account id for the user; echoed in the receipt
- `idempotency_key` (string): Idempotency-Key for this write. Omit to generate one; reuse the returned idempotency_key to retry safely
- `quantity` (integer)
- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)
- `sku` (string, required)
- `store_id` (string, required): Store id (from iap_open_store or iap_list_stores)
- `wallet` (string): User wallet that receives the items; required with a store key

### `iap_get_order` (~205 tokens)

Get a store order

Get one order: its locked quote, status, on-chain payment (txHash, payer, confirmations) and the signed receipt once confirmed. With store_id it reads the store's admin view (store key scope orders:read); without it, GET /api/v2/iap/orders/{id} (the buyer's own order, or any order of the store key's store) — what an app polls until status is 'confirmed'.

Params: order_id (0x + 64 hex), store_id?, session_token?
Returns: Order
Errors: NO_CREDENTIALS, IAP_PLAN_REQUIRED, HTTP_404

Input parameters:

- `order_id` (string, required)
- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)
- `store_id` (string): Store id (from iap_open_store or iap_list_stores)

### `iap_open_test_store` (~232 tokens)

Open a test store

Get or create the TEST store behind one of your live stores: same token page, a copy of its catalog at creation, and orders that are paid with iap_test_pay instead of on chain (no money, no fee). Mint its keys with iap_create_store_key on the returned store id; they start cd_iap_test_. Needs account credentials (a session or CHAINDADDY_API_KEY) with manager role on the token page. Available where test mode is on (GET /api/v2/iap/config → testMode).

Params: store_id (the live store), session_token?
Returns: {ok, store: Store} with mode 'test'
Errors: NO_CREDENTIALS, IAP_PLAN_REQUIRED, HTTP_404 (TEST_MODE_DISABLED where test mode is off)

Input parameters:

- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)
- `store_id` (string, required): Store id (from iap_open_store or iap_list_stores)

### `iap_test_pay` (~244 tokens)

Pay a test order

Pay a TEST store's pending order with no chain and no money: it confirms at once through the same path a real payment takes, so the items are granted, the receipt is issued (claim livemode: false, the test store's storeId) and the iap.order.confirmed webhook goes to the test store's own webhook with livemode false. Repeating it returns the confirmed order. Use a test store key (cd_iap_test_…, scope orders:write, via CHAINDADDY_IAP_KEY) or a session that manages the store.

Params: order_id (0x + 64 hex), session_token?
Returns: {ok, order: Order} with status 'confirmed'
Errors: NO_CREDENTIALS, HTTP_403 (scope), HTTP_404 (unknown order, or TEST_MODE_DISABLED), HTTP_409 (LIVE_ORDER: a live order is paid on chain; ORDER_EXPIRED)

Input parameters:

- `order_id` (string, required)
- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)

### `iap_refund_order` (~245 tokens)

Record a refund

Record a refund for a confirmed order: marks it refunded, revokes its items and its receipt. Chain Daddy never holds the buyer's tokens — send the refund yourself from the payout wallet, then pass its transaction hash here.

Params: store_id, order_id, refund_tx_hash?, note?, session_token?, idempotency_key?
Returns: {ok, idempotency_key, order: Order}
Errors: NO_CREDENTIALS, IAP_PLAN_REQUIRED, HTTP_404, HTTP_409 (not refundable in its status)

Input parameters:

- `idempotency_key` (string): Idempotency-Key for this write. Omit to generate one; reuse the returned idempotency_key to retry safely
- `note` (string)
- `order_id` (string, required)
- `refund_tx_hash` (string): Your refund transfer's transaction hash / signature
- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)
- `store_id` (string, required): Store id (from iap_open_store or iap_list_stores)

### `iap_get_entitlements` (~220 tokens)

Get item holdings

What a wallet holds in a store (owned items plus live unlocks), or — with sku — who owns a SKU. Pass exactly one of wallet or sku. Store key scope: entitlements:read.

Params: store_id, wallet?, sku?, cursor? (owners list only), session_token?
Returns: {storeId, wallet, entitlements: [{sku, type, name, quantity, expiresAt, source: 'ledger'|'unlock', firstGrantedAt}]} or {entries: [{wallet, quantity, expiresAt}], nextCursor}
Errors: INVALID_PARAMS, NO_CREDENTIALS, IAP_PLAN_REQUIRED

Input parameters:

- `cursor` (string)
- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)
- `sku` (string)
- `store_id` (string, required): Store id (from iap_open_store or iap_list_stores)
- `wallet` (string)

### `iap_grant` (~228 tokens)

Grant items

Grant items to a wallet (a reward, a make-good, a server-side award). Items are off-chain and non-transferable. Store key scope: entitlements:write.

Params: store_id, wallet, sku, quantity, reason?, session_token?, idempotency_key?
Returns: {ok, idempotency_key, entitlement: Entitlement}
Errors: NO_CREDENTIALS, IAP_PLAN_REQUIRED, HTTP_400, HTTP_404 (unknown sku)

Input parameters:

- `idempotency_key` (string): Idempotency-Key for this write. Omit to generate one; reuse the returned idempotency_key to retry safely
- `quantity` (integer, required)
- `reason` (string)
- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)
- `sku` (string, required)
- `store_id` (string, required): Store id (from iap_open_store or iap_list_stores)
- `wallet` (string, required)

### `iap_consume` (~221 tokens)

Consume items

Consume units of a consumable a wallet holds (the user spent a credit). Atomic: fails without change when the wallet holds fewer. Store key scope: entitlements:write.

Params: store_id, wallet, sku, quantity, session_token?, idempotency_key?
Returns: {ok, idempotency_key, entitlement: Entitlement}
Errors: INSUFFICIENT_QUANTITY (409), NO_CREDENTIALS, IAP_PLAN_REQUIRED, HTTP_404

Input parameters:

- `idempotency_key` (string): Idempotency-Key for this write. Omit to generate one; reuse the returned idempotency_key to retry safely
- `quantity` (integer, required)
- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)
- `sku` (string, required)
- `store_id` (string, required): Store id (from iap_open_store or iap_list_stores)
- `wallet` (string, required)

### `iap_revoke` (~211 tokens)

Revoke items

Take items back from a wallet. Omit quantity to revoke all of that SKU. Store key scope: entitlements:write.

Params: store_id, wallet, sku, quantity?, reason?, session_token?, idempotency_key?
Returns: {ok, idempotency_key, entitlement: Entitlement}
Errors: NO_CREDENTIALS, IAP_PLAN_REQUIRED, HTTP_404

Input parameters:

- `idempotency_key` (string): Idempotency-Key for this write. Omit to generate one; reuse the returned idempotency_key to retry safely
- `quantity` (integer)
- `reason` (string)
- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)
- `sku` (string, required)
- `store_id` (string, required): Store id (from iap_open_store or iap_list_stores)
- `wallet` (string, required)

### `iap_create_drop` (~283 tokens)

Create a drop

Create a drop (a reward of items). Modes: claim (a link holders claim from), push (delivered to a recipient list when activated), award (your server awards it with iap_award, caps enforced). Audience is a rule (e.g. holders of at least X tokens). Drops start as drafts; activate with iap_set_drop_status. Store key scope: drops:write.

Params: store_id, drop ({name, mode, items: [{sku, quantity}], audience?, allowlistOnly?, maxClaims?, perWalletLimit?, startsAt?, endsAt?, description?, imageUrl?}), session_token?, idempotency_key?
Returns: {ok, idempotency_key, drop: Drop} (drop.slug is the claim link id)
Errors: NO_CREDENTIALS, IAP_PLAN_REQUIRED, HTTP_400

Input parameters:

- `drop` (object, required)
- `idempotency_key` (string): Idempotency-Key for this write. Omit to generate one; reuse the returned idempotency_key to retry safely
- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)
- `store_id` (string, required): Store id (from iap_open_store or iap_list_stores)

### `iap_set_drop_status` (~201 tokens)

Set drop status

Set a drop's status. Activating a push drop starts delivery to its recipients.

Params: store_id, drop_id, status ('draft'|'active'|'paused'|'ended'), session_token?, idempotency_key?
Returns: {ok, idempotency_key, drop: Drop}
Errors: NO_CREDENTIALS, IAP_PLAN_REQUIRED, HTTP_404, HTTP_409

Input parameters:

- `drop_id` (string, required)
- `idempotency_key` (string): Idempotency-Key for this write. Omit to generate one; reuse the returned idempotency_key to retry safely
- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)
- `status` (string, required)
- `store_id` (string, required): Store id (from iap_open_store or iap_list_stores)

### `iap_add_drop_recipients` (~217 tokens)

Add drop recipients

Add wallets to a drop's recipient list (push drops, or an allowlist). Pass wallets, or csv text with one wallet per line.

Params: store_id, drop_id, wallets?, csv?, session_token?, idempotency_key?
Returns: {ok, idempotency_key, added: number, invalid: string[]}
Errors: INVALID_PARAMS, NO_CREDENTIALS, IAP_PLAN_REQUIRED, HTTP_404

Input parameters:

- `csv` (string)
- `drop_id` (string, required)
- `idempotency_key` (string): Idempotency-Key for this write. Omit to generate one; reuse the returned idempotency_key to retry safely
- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)
- `store_id` (string, required): Store id (from iap_open_store or iap_list_stores)
- `wallets` (array)

### `iap_award` (~223 tokens)

Award a drop

Award an award-mode drop to a wallet (the user reached a milestone). The drop's caps and window are enforced. Store key scope: rewards:award.

Params: store_id, drop_id, wallet, session_token?, idempotency_key? (use one per milestone so a retry never awards twice)
Returns: {ok, idempotency_key, …award result}
Errors: NO_CREDENTIALS, IAP_PLAN_REQUIRED, HTTP_404, HTTP_409 (cap reached / drop not active)

Input parameters:

- `drop_id` (string, required)
- `idempotency_key` (string): Idempotency-Key for this write. Omit to generate one; reuse the returned idempotency_key to retry safely
- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)
- `store_id` (string, required): Store id (from iap_open_store or iap_list_stores)
- `wallet` (string, required)

### `iap_create_store_key` (~289 tokens)

Create a store key

Create a store key (cd_iap_…) for your server: one store, only the scopes you list. The secret is returned ONCE — store it in the server's secrets, never in a client. Needs account credentials (a session or CHAINDADDY_API_KEY), never a store key.

Params: store_id, name, scopes (catalog:write|orders:read|orders:write|entitlements:read|entitlements:write|drops:write|rewards:award|events:read|messages:send), session_token?, idempotency_key?
Returns: {ok, idempotency_key, key: {id, name, prefix, scopes, createdAt, secret}}
Errors: NO_CREDENTIALS, IAP_PLAN_REQUIRED, HTTP_400

Input parameters:

- `idempotency_key` (string): Idempotency-Key for this write. Omit to generate one; reuse the returned idempotency_key to retry safely
- `name` (string, required): A label, e.g. 'server-prod'
- `scopes` (array, required)
- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)
- `store_id` (string, required): Store id (from iap_open_store or iap_list_stores)

### `iap_list_events` (~367 tokens)

List store events

Read a store's event feed after a cursor: order.created/paid/confirmed/expired/refunded, order.mismatch (a payment named the order id but not its quote; the order is unchanged), order.duplicate_payment (the order was paid twice; the creator refunds the second), order.checkout_paid_again (a second order confirmed for a checkout session that was already paid; both delivered, and only the seller can send a payment back), order.reverted (a paid order undone by a chain reorg), entitlement.granted/consumed/revoked, entitlement.expiring (a timed item is about to run out) / entitlement.expired, drop.claimed/awarded, drop.exhausted (a drop gave out its last item), sku.sold_out (an item reached its max supply), store.not_live (the store stopped selling because its plan lapsed) / store.live (selling again). Keep `last` and pass it as `after` next time; the same events arrive as iap.<type> webhooks, and this feed is how you catch up on any you missed. Store key scope: events:read.

Params: store_id, after? (event id), limit?, session_token?
Returns: {entries: [{id, type, wallet, orderId, payload, createdAt}], last}
Errors: NO_CREDENTIALS, IAP_PLAN_REQUIRED

Input parameters:

- `after` (integer)
- `limit` (integer)
- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)
- `store_id` (string, required): Store id (from iap_open_store or iap_list_stores)

### `iap_set_webhook` (~377 tokens)

Set store webhook

Create or replace the store's webhook: one HTTPS endpoint that receives the store's events as they happen. Each delivery is POST {id, type, created_at, data} with header X-Webhook-Signature = hex HMAC-SHA256 of the raw body keyed with the webhook's whsec_ secret. Creating returns the secret ONCE — store it where the endpoint verifies signatures. Replacing keeps the secret (no secret in the result) and turns back on a webhook that was disabled after repeated failures. Needs account credentials (a session or CHAINDADDY_API_KEY), never a store key.

Params: store_id, url (https://…), events? (subset of iap.order.created|paid|confirmed|expired|reverted|refunded|mismatch|duplicate_payment, iap.entitlement.granted|consumed|revoked|expiring|expired, iap.drop.claimed|awarded|exhausted, iap.sku.sold_out, iap.store.not_live|live; omit for all), session_token?
Returns: {ok, webhook: {id, url, events, active, createdAt, lastTriggeredAt, secret?}} (secret only when created)
Errors: NO_CREDENTIALS, IAP_PLAN_REQUIRED, SESSION_REQUIRED (a store key), HTTP_400 (bad url or event), HTTP_404

Input parameters:

- `events` (array): Only these events; omit for all
- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)
- `store_id` (string, required): Store id (from iap_open_store or iap_list_stores)
- `url` (string, required): Your endpoint, https://…

### `iap_get_webhook` (~200 tokens)

Get store webhook

Get the store's webhook and its last 20 deliveries, newest first. A delivery's status is pending, delivered, failed or exhausted (no more retries); anything missed can be caught up from iap_list_events. Store key scope: events:read.

Params: store_id, session_token?
Returns: {webhook: {id, url, events, active, createdAt, lastTriggeredAt} | null, deliveries: [{id, eventId, eventType, status, attempt, statusCode, error, createdAt, deliveredAt}]}
Errors: NO_CREDENTIALS, IAP_PLAN_REQUIRED, HTTP_404

Input parameters:

- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)
- `store_id` (string, required): Store id (from iap_open_store or iap_list_stores)

### `iap_test_webhook` (~207 tokens)

Send a test webhook

Queue an iap.test event to the store's webhook, to check the endpoint receives and verifies deliveries. See the result with iap_get_webhook. Store key scope: events:read.

Params: store_id, session_token?, idempotency_key?
Returns: {ok, idempotency_key, queued: true, event: {id, type: 'iap.test', createdAt, data}}
Errors: NO_CREDENTIALS, IAP_PLAN_REQUIRED, NOT_FOUND (no webhook set)

Input parameters:

- `idempotency_key` (string): Idempotency-Key for this write. Omit to generate one; reuse the returned idempotency_key to retry safely
- `session_token` (string): Session token from authenticate. Optional when CHAINDADDY_API_KEY is set (or, for store-scoped tools, CHAINDADDY_IAP_KEY)
- `store_id` (string, required): Store id (from iap_open_store or iap_list_stores)

### `list_skills` (~69 tokens)

List the skills

List Chain Daddy's skills: step-by-step workflows for launching or finding a token, checking its health, exporting a listing, selling items for it, signing users in, verifying receipts and building Crown Apps. Read one with read_skill before doing that task. The same skills are this server's prompts.

Output parameters:

- `skills` (array)

### `read_skill` (~61 tokens)

Read a skill

Read one Chain Daddy skill in full, as Markdown: the workflow, the tools it uses and the rules it keeps. Pass a name from list_skills, and follow it for that task.

Input parameters:

- `name` (string, required): A skill name from list_skills.

## Diagnostics

Captured diagnostic sections: Provenance, Dependencies. The full working is on the page: https://verifymcp.io/servers/io-chaindaddy-mcp/chaindaddy-mcp#diagnostics

## Score history

- 2026-10-23: 81
- 2026-10-22: 81
- 2026-10-21: 66
- 2026-10-20: 80
- 2026-10-19: 80
- 2026-10-18: 79
- 2026-10-17: 79
- 2026-10-16: 78
- 2026-10-15: 78
- 2026-10-14: 77
- 2026-10-13: 77
- 2026-10-12: 76
- 2026-10-11: 76
- 2026-10-07: 74
- 2026-10-04: 73
- 2026-10-03: 58

## Common questions

### What is the Chain Daddy MCP server?

Chain Daddy is an MCP server listed in the public MCP registry as io.chaindaddy/mcp. Search tokens, check registrations, and run a Chain Daddy creator store from your agent. This page covers its npm package (@chaindaddy/mcp).

### Is the Chain Daddy MCP server safe to use?

Chain Daddy scores 81 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 23 October 2026. It declares no install or post-install scripts. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the Chain Daddy MCP server expose?

Chain Daddy exposes 50 tools: get_auth_nonce, authenticate, get_session, search_symbol, get_token, and 45 more. Their descriptions and schemas cost roughly 9,723 tokens of context every time the server is loaded.

### Is the Chain Daddy MCP server still maintained?

Chain Daddy is still listed as active in the MCP registry. We last reached this channel on 23 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the Chain Daddy MCP server under?

Chain Daddy declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- npm package: https://www.npmjs.com/package/@chaindaddy/mcp
- Socket report: https://socket.dev/npm/package/@chaindaddy/mcp
- Website: https://docs.chaindaddy.io/developer/build-with-ai
- Changelog RSS feed: https://verifymcp.io/servers/io-chaindaddy-mcp/chaindaddy-mcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/io-chaindaddy-mcp/chaindaddy-mcp.json
- HTML version of this page: https://verifymcp.io/servers/io-chaindaddy-mcp/chaindaddy-mcp
