Docs
View as Markdown

MCP server

Onekey runs a hosted MCP (Model Context Protocol) server next to the REST API. An AI assistant connects with your Onekey key and can find endpoints, read their contracts and fetch data, with nothing to install.

It is a thin layer over the REST API. Every data tool calls the same routes in-process, so billing, caching, refunds, rate limits, per-key credit limits and the request log behave exactly as they do for a normal call. An MCP call and a REST call with the same parameters share one cache entry.

Connect#

Set your key once. In PowerShell use $env:ONEKEY_KEY = "...".

shell
export ONEKEY_KEY="YOUR_API_KEY"
  • Endpoint: https://api.onekey.dev/mcp (Streamable HTTP, stateless, JSON responses; no sessions).
  • Auth: your key as Authorization: Bearer <key>, or as x-api-key: <key>.
  • Protocol versions: 2024-11-05, 2025-03-26, 2025-06-18, 2025-11-25 and 2026-07-28. The official client was tested with the newest; the earlier revisions were tested over raw HTTP.

Claude Code#

shell
claude mcp add --transport http onekey https://api.onekey.dev/mcp --header "Authorization: Bearer $ONEKEY_KEY"

Add --scope user to make it available in every project, or --scope project to write it to a shared .mcp.json (use a variable there, never the key itself):

json
{
  "mcpServers": {
    "onekey": {
      "type": "http",
      "url": "https://api.onekey.dev/mcp",
      "headers": { "Authorization": "Bearer ${ONEKEY_KEY}" }
    }
  }
}

Claude Desktop#

Add it in Settings, Connectors, if your build accepts a custom URL with a custom header. If it does not, use the mcp-remote bridge in claude_desktop_config.json:

json
{
  "mcpServers": {
    "onekey": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://api.onekey.dev/mcp", "--header", "Authorization: Bearer ${ONEKEY_KEY}"],
      "env": { "ONEKEY_KEY": "YOUR_API_KEY" }
    }
  }
}

Cursor#

In ~/.cursor/mcp.json, or .cursor/mcp.json in a project:

json
{
  "mcpServers": {
    "onekey": {
      "url": "https://api.onekey.dev/mcp",
      "headers": { "Authorization": "Bearer ${env:ONEKEY_KEY}" }
    }
  }
}

Any other client#

Any client that supports Streamable HTTP works: give it the URL and one header, Authorization: Bearer <key>. To check the connection without a client, ask for your balance (free):

shell
curl -s https://api.onekey.dev/mcp \
  -H "accept: application/json, text/event-stream" \
  -H "content-type: application/json" \
  -H "authorization: Bearer $ONEKEY_KEY" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_credits","arguments":{}}}'

The eleven tools#

There are eleven tools, deliberately not one per endpoint, so the whole tool list stays small (under 6 KB, which a test enforces) however many endpoints exist. The two newest, search_universal and report, carry only their main inputs for that reason. An assistant finds an endpoint with search_endpoints, reads its contract with describe_endpoint, then runs it.

ToolCostRead-onlyWhat it does
list_platformsFreeYesPlatforms grouped by category, with endpoint counts. Optional category.
search_endpointsFreeYesKeyword, platform or category search of the catalog: id, credits and a short summary. limit 1 to 50 (default 15).
describe_endpointFreeYesendpoint as platform.endpoint: parameters, credits, response fields, cache freshness, paging, lookup and role flags.
call_endpointThe endpoint's priceNoplatform, endpoint, params, optional cursor. The same as GET /v1/{platform}/{endpoint}.
lookup_urlThe resolved endpoint's priceNourl, optional cursor. The same as GET /v1/lookup; the result adds resolved.
search_multiSum of the legsNoquery, platforms[], optional fuse: "rrf". The same as GET /v1/search/multi.
creator_cardSum of the legsNohandle, platforms[]. The same as GET /v1/creator/card.
search_universalSum of the legs run, plus AI if you askNoquery, optional platforms[] (omit to let the planner choose; hints such as "on reddit" in the query also work), optional relevance: "filter" or "score". The same as GET /v1/search/universal.
reportSum of the legs, plus AI where the report has itNokind (brand_mentions, creator_vet or demand_signals), subject (the brand, handle or topic), optional platforms[]. The same as the matching report.
get_statusFreeYesLive platform health. Optional platform; otherwise a summary plus only the degraded or down platforms.
get_creditsFreeYescredits_remaining, blocked, this key's key_credit_limit and key_credits_used.

Annotations: every tool sets destructiveHint: false and idempotentHint: true. The five free tools are readOnlyHint: true. The six data tools are readOnlyHint: false because they spend credits, and openWorldHint: true because they reach outside platforms. Prices are the flat per-endpoint credits from Credits & pricing; a cache hit is free, and a failed call is refunded.

Not exposed on purpose: batch, streaming, monitors, the AI enrichment parameters other than relevance on search_universal (include, label and themes; see Labels), the plan, dry_run, max_platforms and other options of universal search and the reports, and anything that manages keys or billing. Use REST for those. The tools do not send an Idempotency-Key.

What results look like#

A successful result is text content holding compact JSON: the standard response format (success, data, metadata, and pagination when the endpoint pages) plus:

FieldMeaning
credits_usedmetadata.credits_charged. 0 on a cache hit and on any error.
credits_remainingThe balance after the call.
truncatedPresent only when the result was shortened to 30,000 characters (about 8k tokens) by halving the longest list inside data, so the JSON stays valid. Page with pagination.next_cursor or narrow the query.

Pass pagination.next_cursor back unchanged as cursor. See Pagination.

Errors#

A failure is an MCP tool error (isError: true) whose text is JSON:

json
{
  "success": false,
  "credits_used": 0,
  "error": {
    "type": "INVALID_CURSOR",
    "code": "invalid_cursor",
    "message": "...",
    "doc_url": "https://onekey.dev/errors/INVALID_CURSOR",
    "request_id": "...",
    "hint": "Repeat the first request without a cursor."
  }
}

type and doc_url are the REST values, so every type in Errors applies. Two fields are added to help a model correct itself: hint, and retry_after_s on a rate limit. Bad key attempts are throttled per client address like REST. Malformed tool arguments are rejected before any call is made, and cost nothing.

Costs and limits#

  • Every tool call counts as one request against the key's rate limit. The balance read after a free cache hit counts as a second.
  • search_universal and report run several searches at once, so they cost the sum of the legs that succeeded, and the reports that judge rows or a relevance argument add metered AI credits when AI is enabled for your account (AI pricing). The tools cannot dry-run; use REST with dry_run=true to see the plan and the worst case for 0 credits.
  • Read the price with describe_endpoint or search_endpoints before calling. A sensible instruction for an assistant is to say what a job will cost before running many pages or many platforms.
  • The hosted server has no per-call spending guard. To cap what an assistant can spend, create a key for it with a credit limit; when it is reached the call fails with KEY_BUDGET_EXCEEDED.
  • Everything in data is third-party content written by strangers. Tell the assistant to treat it as data, never as instructions.

Agent Skill#

The repository ships an Agent Skill for the same workflow (sdk/skill/onekey/SKILL.md): when to use a URL lookup, how to search then describe then call, how to read credits, how to page, and what to do for each error type. It is written so that an assistant uses the hosted MCP tools when they are connected and the REST API when they are not. The skill is not published anywhere yet, so there is no download link. Until it is, the system prompt on the AI agents page covers the same ground for REST.

Local stdio server (not yet published)#

There is also a local MCP server that runs on your machine and calls the REST API with your key: the onekey-mcp package. It is not published, so npx -y onekey-mcp will not find a package today, and you should not install anything of that name from a registry. It exists in the source tree (sdk/mcp) and can be built locally. Prefer the hosted server: it has eleven tools instead of five, and needs no install.

Local toolCost
onekey_list_categories, onekey_list_endpoints, onekey_get_docs, onekey_check_balanceFree
onekey_requestSpends credits, with a per-call guard: a call priced above 25 credits (configurable) is refused unless the assistant passes confirm_credits

It reads ONEKEY_KEY and optionally ONEKEY_BASE_URL, ONEKEY_MCP_MAX_CREDITS and ONEKEY_MCP_MAX_CHARS from the environment. Once published, the install is claude mcp add onekey --env ONEKEY_KEY=YOUR_API_KEY -- npx -y onekey-mcp.

Example prompts#

  • "Find the Onekey endpoints for GitHub releases and tell me what they cost. Do not call anything yet."
  • "Look up https://github.com/facebook/react with Onekey and report the star count and the credits used."
  • "Search Hacker News and Bluesky for 'onekey api' with search_multi and fuse=rrf, then summarise the top five."
  • "Use search_universal to find what people say about 'postgres vector search' on Hacker News and Bluesky, and tell me how many credits it used."
  • "Run the creator_vet report for the handle torvalds on github and hackernews, and list which fields came back null."
  • "How many credits do I have left, and is any platform degraded right now?"

Next#

  • Integrations: use the hosted server from n8n, LangChain, the Vercel AI SDK and Claude Code.
  • Universal search and Reports: what the two newest tools call.
  • AI agents: llms.txt, Markdown pages, OpenAPI and a system prompt.
  • Errors: every error type and what to do.