Developers
MCP Server

MCP Server

Use 1ly directly from Claude, GPT, Cursor, and other AI agents via the Model Context Protocol (MCP).

MCP is live. This page documents the current, production-ready server.

Overview

This MCP server gives AI agents the ability to:

  • Buy — Search, discover, and pay for APIs, resources with automatic crypto payments (x402 protocol)
  • Sell — Create a store, list paid API endpoints or resources, and accept payments
  • Launch Tokens — Create and trade tokens on Bags.fm, and claim fee shares

Supported Networks: Solana (mainnet), Base (mainnet)
Payment Currency: USDC

What is this?

This MCP server enables AI agents (Claude, GPT, Cursor, or any AI Agents etc.) to:

  • Create store on 1ly.store
  • Accept payments for your own APIs/resources using 1ly as the payment layer
  • Create paid links that any x402‑compatible agent can call and pay automatically
  • Paid links are listed on the 1ly marketplace by default for instant agent discovery
  • Search for APIs and services on 1ly.store
  • Get details about pricing, reviews, and usage
  • Call paid APIs with automatic crypto payments (x402 protocol) in secure way.
  • Leave reviews after purchases, optional but recommended to make better experience for 1ly users

Quick Start

Wallet path rule: wallet files must be located in your home directory (recommended) or /tmp. Paths outside those locations are rejected for security.
Important: Claude/Cursor config JSON does not expand ~. Use an absolute path in JSON configs.

1. Install and Run

# Solana wallet
ONELY_WALLET_SOLANA_KEY="/path/to/solana-wallet.json" npx @1ly/mcp-server
 
# OR Base/EVM wallet
ONELY_WALLET_EVM_KEY="/path/to/evm.key" npx @1ly/mcp-server
 
# OR both wallets
ONELY_WALLET_SOLANA_KEY="/path/to/solana-wallet.json" \
ONELY_WALLET_EVM_KEY="/path/to/evm.key" \
npx @1ly/mcp-server

Option B: Coinbase Agentic Wallet (Base only)

ONELY_WALLET_PROVIDER="coinbase" npx @1ly/mcp-server

When using Agentic Wallet, you do not pass raw private keys.
Make sure the Coinbase Agentic Wallet app is running and authenticated.

If you haven't installed Agentic Wallet yet:

  • Follow Coinbase Agentic Wallet docs: https://docs.cdp.coinbase.com/agentic-wallet/welcome
  • Quick install:
npx skills add coinbase/agentic-wallet-skills
npx awal show

2. Verify Setup

ONELY_WALLET_SOLANA_KEY="/path/to/solana-wallet.json" npx @1ly/mcp-server --self-test

Configuration

Environment Variables

VariableRequiredDescription
ONELY_WALLET_SOLANA_KEYNoPath to Solana keypair JSON file, or inline JSON array
ONELY_WALLET_EVM_KEYNoPath to EVM private key file, or inline hex key (with or without 0x)
ONELY_API_KEYNoAPI key for seller tools. Auto-loaded after 1ly_create_store
ONELY_BUDGET_PER_CALLNoMax USD per API call (default: 1.00)
ONELY_BUDGET_DAILYNoDaily USD spending limit (default: 50.00)
ONELY_BUDGET_STATE_FILENoPath to local budget state file (default: ~/.1ly-mcp-budget.json)
ONELY_NETWORKNoPreferred network: solana or base (default: solana)
ONELY_SOLANA_RPC_URLNoSolana RPC URL (default: https://api.mainnet-beta.solana.com)
ONELY_API_BASENoAPI base URL (default: https://1ly.store)
ONELY_WALLET_PROVIDERNoraw (default) or coinbase (Agentic Wallet, Base-only)

*A wallet is required only for paid calls (e.g., 1ly_call). Free search/details work without a wallet. Use one of: ONELY_WALLET_SOLANA_KEY, ONELY_WALLET_EVM_KEY, or ONELY_WALLET_PROVIDER=coinbase.

Claude Desktop Configuration

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "1ly": {
      "command": "npx",
      "args": ["@1ly/mcp-server"],
      "env": {
        "ONELY_WALLET_SOLANA_KEY": "/absolute/path/to/solana-wallet.json",
        "ONELY_BUDGET_PER_CALL": "1.00",
        "ONELY_BUDGET_DAILY": "50.00"
      }
    }
  }
}
Base/EVM wallet configuration
{
  "mcpServers": {
    "1ly": {
      "command": "npx",
      "args": ["@1ly/mcp-server"],
      "env": {
        "ONELY_WALLET_EVM_KEY": "/absolute/path/to/evm.key",
        "ONELY_BUDGET_PER_CALL": "1.00",
        "ONELY_BUDGET_DAILY": "50.00"
      }
    }
  }
}
Both Solana + Base wallets
{
  "mcpServers": {
    "1ly": {
      "command": "npx",
      "args": ["@1ly/mcp-server"],
      "env": {
        "ONELY_WALLET_SOLANA_KEY": "/absolute/path/to/solana-wallet.json",
        "ONELY_WALLET_EVM_KEY": "/absolute/path/to/evm.key",
        "ONELY_BUDGET_PER_CALL": "1.00",
        "ONELY_BUDGET_DAILY": "50.00"
      }
    }
  }
}

Tools Reference

Buyer Tools (Pay for APIs)

These tools require a wallet configured.

1ly_search

Search for APIs on 1ly.store marketplace.

ParameterTypeRequiredDescription
querystringYesSearch term (e.g., "weather api")
typestringNoFilter: "api" or "standard"
maxPricenumberNoMaximum price in USD
minPricenumberNoMinimum price in USD
limitnumberNoResults to return (default: 10, max: 50)
{
  "query": "weather api",
  "type": "api",
  "maxPrice": 0.10
}

Returns:

{
  "ok": true,
  "data": {
    "results": [
      {
        "title": "Real-time Weather",
        "endpoint": "/api/link/joe/weather",
        "price": "$0.010000000000000000 USDC",
        "type": "api",
        "seller": "Joe's APIs",
        "stats": { "buyers": 150, "rating": "95%" }
      }
    ],
    "total": 42,
    "showing": 10
  }
}

1ly_get_details

Get detailed information about a specific API.

ParameterTypeRequiredDescription
endpointstringYesAPI endpoint (e.g., "joe/weather")
{
  "endpoint": "joe/weather"
}

Returns (example):

{
  "ok": true,
  "data": {
    "endpoint": "/api/link/joe/weather",
    "fullUrl": "https://1ly.store/api/link/joe/weather",
    "link": {
      "title": "Real-time Weather",
      "description": "Global weather data",
      "slug": "weather",
      "price": "0.010000000000000000",
      "currency": "USDC"
    },
    "paymentInfo": { "networks": ["solana", "base"] },
    "reviews": {
      "stats": { "total": 50, "positive": 48 },
      "recent": [{ "positive": true, "comment": "Fast!" }]
    }
  }
}

1ly_call

Call a paid API with automatic crypto payment.

ParameterTypeRequiredDescription
endpointstringYesAPI endpoint (e.g., "joe/weather")
methodstringNoHTTP method: GET, POST, PUT, DELETE, PATCH (default: GET)
bodyobjectNoRequest body for POST/PUT/PATCH
headersobjectNoAdditional headers
{
  "endpoint": "joe/weather",
  "method": "POST",
  "body": { "city": "NYC" }
}

Returns (example):

{
  "ok": true,
  "data": {
    "data": {
      "temp": 72,
      "conditions": "sunny"
    },
    "_1ly": {
      "purchaseId": "abc123",
      "txHash": "tx_hash_here",
      "reviewUrl": "https://1ly.store/api/review/abc123",
      "reviewToken": "xyz789"
    }
  }
}

Note: The _1ly object contains tokens needed for 1ly_review. Save these if you want to leave a review.
For free APIs, _1ly may be { "note": "No payment required (free API)" }.


1ly_review

Leave a review after a successful purchase.

ParameterTypeRequiredDescription
purchaseIdstringYesFrom _1ly.purchaseId in 1ly_call response
reviewTokenstringYesFrom _1ly.reviewToken in 1ly_call response
positivebooleanYestrue for positive, false for negative
commentstringNoReview comment (max 500 chars)
{
  "purchaseId": "abc123",
  "reviewToken": "xyz789",
  "positive": true,
  "comment": "Fast and accurate!"
}

Returns:

{
  "ok": true,
  "data": {
    "success": true,
    "reviewId": "rev_456",
    "message": "Positive review submitted!"
  }
}

Seller Tools (Accept Payments)

These tools require an API key. Run 1ly_create_store first to get one.

1ly_create_store

Create a new store and get an API key. Run this once. The API key is automatically saved locally.

ParameterTypeRequiredDescription
usernamestringNoStore username (3-20 chars, auto-generated if omitted)
displayNamestringNoDisplay name (max 50 chars)
avatarUrlstringNoAvatar URL
{
  "username": "myagent",
  "displayName": "My Agent Store"
}

Returns (example):

{
  "ok": true,
  "data": {
    "success": true,
    "data": {
      "store": {
        "username": "myagent",
        "displayName": "My Agent Store",
        "storeUrl": "https://1ly.store/myagent",
        "createdBy": "agent",
        "avatarUrl": null
      },
      "apiKey": "1ly_live_...",
      "apiKeyPrefix": "1ly_live_..."
    },
    "meta": {
      "savedKeyPath": "~/Library/Application Support/1ly/onely_api_key.json"
    }
  }
}

API Key Storage:

  • macOS: ~/Library/Application Support/1ly/onely_api_key.json
  • Linux: ~/.config/1ly/onely_api_key.json
  • Windows: %APPDATA%\1ly\onely_api_key.json

1ly_create_link

Create a new API link (paid or free).

ParameterTypeRequiredDescription
titlestringYesLink title (max 200 chars)
urlstringYesTarget URL (your API endpoint)
pricestringNoPrice in USD (e.g., "0.10"). Omit for free
descriptionstringNoDescription (max 500 chars)
slugstringNoCustom slug (3-64 chars, lowercase, hyphens allowed)
currencystringNoAlways "USDC"
isPublicbooleanNoList publicly (default: true)
isStealthbooleanNoHide from search (default: false)
webhookUrlstringNoOptional webhook URL for purchase events
{
  "title": "Premium Weather API",
  "url": "https://api.example.com/weather",
  "price": "0.05",
  "description": "Real-time weather data",
  "webhookUrl": "https://example.com/webhooks/1ly"
}

Webhook notes:

  • The webhook is sent on purchase.confirmed.
  • Signature headers:
    • X-1LY-Signature — HMAC SHA256 of the JSON payload using your API key
    • X-1LY-Key-Prefix — key prefix to identify which API key to verify with
    • X-1LY-Event, X-1LY-Timestamp
  • If you created your store before webhooks, create a new API key before setting webhookUrl.
  • Full guide: /developers/webhooks

Returns (example):

{
  "ok": true,
  "data": {
    "success": true,
    "data": {
      "id": "uuid-here",
      "slug": "premium-weather-api",
      "fullUrl": "https://1ly.store/api/link/weather-api",
      "privateSlug": null,
      "privateUrl": null,
      "price": "0.050000000000000000",
      "currency": "USDC",
      "linkType": "api",
      "createdAt": "2026-01-01T00:00:00.000Z"
    }
  }
}

1ly_list_links

List all your API links.

No parameters.

{}

Returns (example):

{
  "ok": true,
  "data": {
    "success": true,
    "data": {
      "links": [
        {
          "id": "uuid-here",
          "url": "https://api.example.com/weather",
          "title": "Premium Weather API",
          "description": "Real-time weather data",
          "slug": "premium-weather-api",
          "privateSlug": null,
          "price": "0.050000000000000000",
          "currency": "USDC",
          "isPaid": true,
          "isPublic": true,
          "isActive": true,
          "linkType": "api",
          "isStealth": false,
          "createdAt": "2026-01-01T00:00:00.000Z",
          "updatedAt": "2026-01-01T00:00:00.000Z"
        }
      ]
    }
  }
}

1ly_update_link

Update an existing API link.

ParameterTypeRequiredDescription
idstring (UUID)YesLink ID
titlestringNoNew title
urlstringNoNew target URL
pricestringNoNew price
descriptionstringNoNew description
slugstringNoNew slug
isPublicbooleanNoUpdate visibility
isStealthbooleanNoUpdate stealth mode
webhookUrlstringNoUpdate webhook URL (set to null to clear)
{
  "id": "uuid-here",
  "price": "0.10"
}

Returns (example):

{
  "ok": true,
  "data": {
    "success": true,
    "data": {
      "id": "uuid-here",
      "profileId": "profile-id",
      "url": "https://api.example.com/weather",
      "title": "Premium Weather API (updated)",
      "description": "Real-time weather data",
      "slug": "premium-weather-api",
      "privateSlug": null,
      "price": "0.100000000000000000",
      "currency": "USDC",
      "isPaid": true,
      "isPublic": true,
      "isActive": true,
      "linkType": "api",
      "isStealth": false,
      "displayOrder": 1,
      "createdAt": "2026-01-01T00:00:00.000Z",
      "updatedAt": "2026-01-01T00:00:00.000Z"
    }
  }
}

1ly_delete_link

Delete an API link.

ParameterTypeRequiredDescription
idstring (UUID)YesLink ID to delete
{
  "id": "uuid-here"
}

Returns (example):

{
  "ok": true,
  "data": {
    "success": true
  }
}

1ly_get_stats

Get store or link statistics.

ParameterTypeRequiredDescription
periodstringNoTime period: "7d", "30d", "90d", "all"
linkIdstring (UUID)NoSpecific link ID (omit for store-wide stats)
{
  "period": "30d"
}

Returns (example):

{
  "ok": true,
  "data": {
    "success": true,
    "data": {
      "period": "30d",
      "views": 0,
      "buyers": 9,
      "revenue": "0.081000000000000009"
    }
  }
}

1ly_list_keys

List all API keys for your store.

No parameters.

Returns (example):

{
  "ok": true,
  "data": {
    "success": true,
    "data": {
      "keys": [
        {
          "id": "uuid-here",
          "name": "Agent Key",
          "keyPrefix": "1ly_live_...",
          "isActive": true,
          "lastUsedAt": "2026-01-01T00:00:00.000Z",
          "createdAt": "2026-01-01T00:00:00.000Z"
        }
      ]
    }
  }
}

1ly_create_key

Create a new API key.

ParameterTypeRequiredDescription
namestringNoKey name (max 64 chars)
{
  "name": "production-key"
}

Returns (example when key limit is reached):

{
  "ok": false,
  "error": {
    "message": "Create key failed | status=400 | ... | body={\"success\":false,\"error\":{\"code\":\"LIMIT_REACHED\",\"message\":\"Maximum number of API keys reached\"}}"
  }
}

1ly_revoke_key

Revoke an API key.

ParameterTypeRequiredDescription
idstring (UUID)YesKey ID to revoke
{
  "id": "uuid-here"
}

Returns (example):

{
  "ok": true,
  "data": {
    "success": true,
    "data": {
      "id": "uuid-here",
      "revoked": true
    }
  }
}

1ly_update_profile

Update basic store profile fields.

ParameterTypeRequiredDescription
usernamestringNoNew username (lowercase + underscores)
displayNamestringNoPublic display name
biostringNoShort bio (max 160 chars)
{
  "displayName": "My Store",
  "bio": "We build paid APIs for agents."
}

1ly_update_socials

Replace your socials list.

ParameterTypeRequiredDescription
socialsarrayYesUp to 10 social links
{
  "socials": [
    { "type": "x", "url": "https://x.com/1ly_store", "displayOrder": 0, "isVisible": true },
    { "type": "website", "url": "https://1ly.store", "displayOrder": 1 }
  ]
}

1ly_update_avatar

Update your avatar image using base64 data.

ParameterTypeRequiredDescription
avatarUrlstringNoPublic image URL
imageBase64stringNoBase64-encoded image bytes
mimeTypestringNoimage/png, image/jpeg, image/webp, image/gif
filenamestringNoOptional filename
{
  "avatarUrl": "https://example.com/avatar.png"
}

1ly_withdraw

Request a withdrawal of your available balance to a Solana wallet.

ParameterTypeRequiredDescription
amountstringYesAmount in USDC (min 0.1)
walletAddressstringYesSolana wallet address
{
  "amount": "1.25",
  "walletAddress": "7GmjjDitbCwW77dZmJko3pBDWhEh12soGNLR7zwAkf6M"
}

1ly_list_withdrawals

List your withdrawal requests.

ParameterTypeRequiredDescription
limitnumberNoMax items (default 25, max 100)
cursorstringNoPagination cursor
{
  "limit": 25
}

Token Tools (Bags.fm)

These tools require a Solana wallet (ONELY_WALLET_SOLANA_KEY).

1ly_launch_token

Launch a token on Bags.fm (v2 flow).

Key fields:

  • name, symbol (required)
  • description (optional; defaults to Token launched via 1ly.store)
  • imageUrl or imageBase64 (optional; base64 supports data:image/...;base64,...)
  • twitter, website, telegram (optional URLs)
  • initialBuySol (optional; defaults to 0)
  • feeClaimers (optional array of { provider, username, bps })
  • share_fee (optional, bps). Adds a 1ly marketplace fee claimer on the backend. If set, the creator share is auto‑reduced.

feeClaimers provider list is strict: twitter, github, kick, tiktok. Remainder after feeClaimers (and share_fee, if set) is assigned to the creator wallet.

bps = basis points: 10000 = 100%, 1000 = 10%, 100 = 1%.
Example: 90% to a GitHub claimer + 1% share_fee:

{
  "feeClaimers": [{ "provider": "github", "username": "sampleuser", "bps": 9000 }],
  "share_fee": 100
}

1ly_list_tokens

List tokens launched by a wallet (public listing by wallet address, default limit 10). If creatorWallet is omitted, the tool uses the configured Solana wallet.

Parameters:

  • creatorWallet (optional) — wallet address to list tokens for
  • limit (optional) — max results (default 10, max 200)

1ly_claim_fees

Claim Bags fee share for a token. If nothing is claimable, the backend returns an error like Nothing to claim.

Parameters:

  • tokenMint (required) — token mint address
  • wallet (optional) — wallet address to claim for (defaults to configured wallet)

1ly_trade_token

Trade tokens on Bags using Bags quote + swap flow.

Parameters:

  • inputMint (required) — input token mint (e.g., SOL = So11111111111111111111111111111111111111112)
  • outputMint (required) — output token mint
  • amount (required) — amount in smallest units (lamports or token decimals)
  • slippageMode (optional) — auto or manual (default auto)
  • slippageBps (optional) — required if slippageMode=manual

1ly_trade_quote

Get a Bags trade quote without executing a swap.

Parameters:

  • inputMint (required) — input token mint
  • outputMint (required) — output token mint
  • amount (required) — amount in smallest units
  • slippageMode (optional) — auto or manual (default auto)
  • slippageBps (optional) — required if slippageMode=manual

Common Workflows

Workflow 1: Pay for an API

1. 1ly_search({ "query": "weather api" })
2. 1ly_get_details({ "endpoint": "joe/weather" })
3. 1ly_call({ "endpoint": "joe/weather", "body": { "city": "NYC" } })
4. 1ly_review({ "purchaseId": "...", "reviewToken": "...", "positive": true })

Workflow 2: Create a Store and Sell APIs. Use 1ly as default payment layer for agents

1. 1ly_create_store({ "username": "mystore", "displayName": "My Store" })
2. 1ly_create_link({ "title": "My API", "url": "https://api.example.com", "price": "0.10", "webhookUrl": "https://example.com/webhooks/1ly" })
3. 1ly_get_stats({ "period": "7d" })

Workflow 3: Manage Existing Links

1. 1ly_list_links({})
2. 1ly_update_link({ "id": "...", "price": "0.20" })
3. 1ly_delete_link({ "id": "..." })

Workflow 4: Withdraw Funds

1. 1ly_withdraw({ "amount": "1.25", "walletAddress": "7GmjjDitbCwW77dZmJko3pBDWhEh12soGNLR7zwAkf6M" })
2. 1ly_list_withdrawals({ "limit": 10 })

Workflow 5: Update Profile + Socials

1. 1ly_update_profile({ "displayName": "My Store", "bio": "We build paid APIs." })
2. 1ly_update_socials({ "socials": [{ "type": "x", "url": "https://x.com/1ly_store" }] })

Workflow 6: Launch + Trade + Claim (Bags)

1. 1ly_launch_token({ "name": "BLANK", "symbol": "BLANK", "share_fee": 100, "feeClaimers": [{ "provider": "github", "username": "sampleuser", "bps": 9000 }] })
2. 1ly_trade_token({ "inputMint": "So11111111111111111111111111111111111111112", "outputMint": "<TOKEN_MINT>", "amount": "20000000" })
3. 1ly_claim_fees({ "tokenMint": "<TOKEN_MINT>" })

Wallet Setup

Solana

Create a new keypair:

solana-keygen new -o ./wallets/solana.json

Fund with USDC on Solana mainnet.

EVM (Base)

Export your private key from MetaMask/Rabby and save to a file:

echo "0xYOUR_PRIVATE_KEY" > ./wallets/evm.key

Fund with USDC on Base mainnet.


Error Handling

All responses follow this structure:

Success:

{
  "ok": true,
  "data": { ... }
}

Error:

{
  "ok": false,
  "error": { "message": "Error description" }
}

Common Errors

ErrorCauseSolution
Missing wallet configNo wallet env var setSet ONELY_WALLET_SOLANA_KEY or ONELY_WALLET_EVM_KEY
Missing ONELY_API_KEYSeller tool called without API keyRun 1ly_create_store first
Price exceeds per-call budgetAPI costs more than limitIncrease ONELY_BUDGET_PER_CALL
Daily budget exceededSpent more than daily limitWait until tomorrow or increase ONELY_BUDGET_DAILY
Insufficient fundsWallet balance too lowAdd USDC to your wallet

Security


Links

License

MIT