# MCP server

Onekey runs a hosted [MCP](https://modelcontextprotocol.io) (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.

> [!NOTE] **Status.** The hosted server is built and tested. The address on this page, `https://api.onekey.dev/mcp`, uses the same placeholder host as the rest of these docs until the public domain is announced. It is not listed in any MCP registry yet.

It is a thin layer over the REST API. Every data tool calls the same routes in-process, so billing, [caching](https://onekey.dev/docs/caching.md), refunds, [rate limits](https://onekey.dev/docs/rate-limits.md), [per-key credit limits](https://onekey.dev/docs/key-limits.md) 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 = "..."`.

```bash
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

```bash
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):

```bash
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":{}}}'
```

> [!WARN] **API key only, no OAuth.** The server does not offer an OAuth sign-in flow. A client that can only connect through OAuth or a "sign in" button cannot use it; use a client that lets you set a header, or the REST API. Connecting, `initialize` and `tools/list` work without a key, but every tool call needs one (a missing key returns a tool error, [`UNAUTHORIZED`](https://onekey.dev/docs/errors.md#unauthorized)). A request that carries a browser `Origin` header is refused unless that origin is allowed; desktop and command-line clients send none.

## 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.

| Tool | Cost | Read-only | What it does |
| --- | --- | --- | --- |
| `list_platforms` | Free | Yes | Platforms grouped by category, with endpoint counts. Optional `category`. |
| `search_endpoints` | Free | Yes | Keyword, `platform` or `category` search of the catalog: id, credits and a short summary. `limit` 1 to 50 (default 15). |
| `describe_endpoint` | Free | Yes | `endpoint` as `platform.endpoint`: parameters, credits, response fields, cache freshness, paging, lookup and role flags. |
| `call_endpoint` | The endpoint's price | No | `platform`, `endpoint`, `params`, optional `cursor`. The same as `GET /v1/{platform}/{endpoint}`. |
| `lookup_url` | The resolved endpoint's price | No | `url`, optional `cursor`. The same as [`GET /v1/lookup`](https://onekey.dev/docs/lookup.md); the result adds `resolved`. |
| `search_multi` | Sum of the legs | No | `query`, `platforms[]`, optional `fuse: "rrf"`. The same as [`GET /v1/search/multi`](https://onekey.dev/docs/search-multi.md). |
| `creator_card` | Sum of the legs | No | `handle`, `platforms[]`. The same as `GET /v1/creator/card`. |
| `search_universal` | Sum of the legs run, plus AI if you ask | No | `query`, 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`](https://onekey.dev/docs/universal-search.md). |
| `report` | Sum of the legs, plus AI where the report has it | No | `kind` (`brand_mentions`, `creator_vet` or `demand_signals`), `subject` (the brand, handle or topic), optional `platforms[]`. The same as the matching [report](https://onekey.dev/docs/reports.md). |
| `get_status` | Free | Yes | Live platform health. Optional `platform`; otherwise a summary plus only the degraded or down platforms. |
| `get_credits` | Free | Yes | `credits_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](https://onekey.dev/docs/credits.md); a [cache hit](https://onekey.dev/docs/caching.md) is free, and a failed call is refunded.

**Not exposed on purpose:** [batch](https://onekey.dev/docs/batch.md), [streaming](https://onekey.dev/docs/streaming.md), [monitors](https://onekey.dev/docs/monitors.md), the AI enrichment parameters other than `relevance` on `search_universal` (`include`, `label` and `themes`; see [Labels](https://onekey.dev/docs/labels.md)), 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](https://onekey.dev/docs/response-envelope.md) (`success`, `data`, `metadata`, and `pagination` when the endpoint pages) plus:

| Field | Meaning |
| --- | --- |
| `credits_used` | `metadata.credits_charged`. 0 on a cache hit and on any error. |
| `credits_remaining` | The balance after the call. |
| `truncated` | Present 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](https://onekey.dev/docs/pagination.md).

### 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](https://onekey.dev/docs/errors.md) 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](https://onekey.dev/docs/ai-pricing.md)). 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](https://onekey.dev/docs/key-limits.md); when it is reached the call fails with [`KEY_BUDGET_EXCEEDED`](https://onekey.dev/docs/errors.md#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](https://onekey.dev/docs/ai-agents.md) 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 tool | Cost |
| --- | --- |
| `onekey_list_categories`, `onekey_list_endpoints`, `onekey_get_docs`, `onekey_check_balance` | Free |
| `onekey_request` | Spends 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](https://onekey.dev/docs/integrations.md): use the hosted server from n8n, LangChain, the Vercel AI SDK and Claude Code.
- [Universal search](https://onekey.dev/docs/universal-search.md) and [Reports](https://onekey.dev/docs/reports.md): what the two newest tools call.
- [AI agents](https://onekey.dev/docs/ai-agents.md): llms.txt, Markdown pages, OpenAPI and a system prompt.
- [Errors](https://onekey.dev/docs/errors.md): every error type and what to do.
