Skip to main content
Glama
CoinStats MCP Server

CoinStats MCP Server

Official
by CoinStatsHQ
README.md
# CoinStats MCP Server

Hosted [Model Context Protocol](https://modelcontextprotocol.io/) server for the CoinStats API. Lets AI agents (Claude, Cursor, Codex, ChatGPT — anything that speaks MCP) read and act on the same crypto data the CoinStats apps use, over a single OAuth-protected HTTPS URL.

There's no API key to copy and no env var to manage: each user authorises the agent against their own CoinStats account in the browser, and the agent gets a per-user token from then on.

<a href="https://glama.ai/mcp/servers/@CoinStatsHQ/coinstats-mcp">
  <img width="380" height="200" src="https://glama.ai/mcp/servers/@CoinStatsHQ/coinstats-mcp/badge" alt="CoinStats Server MCP server" />
</a>

## Server URL

```
https://mcp.coinstats.app/mcp
```

## Installation

### Claude.ai / Claude Desktop

Settings → **Connectors** → **Add custom connector**. Paste the server URL and click **Add**:

```
https://mcp.coinstats.app/mcp
```

A browser window opens at `coinstats.app/openapi/consent`. Sign in (or recognise your existing session), review the requested access, click **Approve**.

### Cursor

[![Install MCP Server](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en/install-mcp?name=coinstats&config=eyJ1cmwiOiJodHRwczovL21jcC5jb2luc3RhdHMuYXBwL21jcCJ9)

Or add to `~/.cursor/mcp.json` manually:

```json
{
  "mcpServers": {
    "coinstats": {
      "url": "https://mcp.coinstats.app/mcp"
    }
  }
}
```

Restart Cursor; on first call it opens a browser window for the OAuth flow.

### Claude Code

```bash
claude mcp add coinstats --transport http https://mcp.coinstats.app/mcp
```

Claude Code opens a browser to authorise. Verify with:

```bash
claude mcp list
```

### Codex

`codex mcp add` only registers the URL; it does **not** open a browser. Run `codex mcp login` separately:

```bash
codex mcp add coinstats --url https://mcp.coinstats.app/mcp
codex mcp login coinstats
```

After the login step `codex mcp list` should show `Auth: OAuth` for `coinstats`.

### Other MCP clients

Any client that speaks the [Streamable HTTP](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#streamable-http) transport with OAuth 2.1 authorization will work. Point it at `https://mcp.coinstats.app/mcp` — Dynamic Client Registration ([RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591)) is supported, so no pre-shared `client_id` is needed.

## What you can do

After authorising, your agent can:

- Look up real-time prices, charts and market data for 100,000+ coins
- Read your CoinStats portfolio coins, P/L and performance over time
- Query wallet balances and transactions across 120+ blockchains
- Read open perpetual and futures positions from connected exchanges, including Hyperliquid, with leverage, P/L and funding where available
- Read synced perpetual trade history with `get-perpetual-trades`, including prices, realized P/L and fees where available. Supports `portfolioId` and `limit`/`skip` pagination; coverage depends on the connector and last sync.
- Retrieve cash-flow-adjusted historical P/L for wallets, exchanges, and portfolios over preset or custom calendar ranges
- Compare ticker pricing across 200+ exchanges
- Pull crypto news (latest, trending, filtered by source or topic)

Full tool catalog: [https://coinstats.app/api-docs/mcp/tools](https://coinstats.app/api-docs/mcp/tools).

## Authentication

Discovery + OAuth flow follows the standard MCP / RFC pattern:

| Endpoint | Spec | Purpose |
|---|---|---|
| `GET /.well-known/oauth-protected-resource` | [RFC 9728](https://datatracker.ietf.org/doc/html/rfc9728) | Points at the authorization server (`https://api.coin-stats.com`) |
| `GET /.well-known/oauth-authorization-server` | [RFC 8414](https://datatracker.ietf.org/doc/html/rfc8414) | AS metadata (also mirrored on the MCP host so older clients can find it without the indirection) |
| `POST /v1/oauth/register` (on AS) | [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591) | Dynamic Client Registration |
| `GET /v1/oauth/authorize` → consent UI | OAuth 2.1 §4.1 | User approves access |
| `POST /v1/oauth/token` (on AS) | OAuth 2.1 §4.1 | PKCE code exchange |
| `POST /v1/oauth/revoke` (on AS) | [RFC 7009](https://datatracker.ietf.org/doc/html/rfc7009) | Per-client disconnect |

Token transport: `Authorization: Bearer <token>`. Single `coinstats` scope today; granular scopes are on the roadmap.

## Self-host / stdio fallback (developer mode)

If you want to run the MCP server yourself (no per-user OAuth, just a developer API key), the legacy stdio entry point is published on npm:

```bash
npx @coinstats/coinstats-mcp
```

with `COINSTATS_API_KEY` set in the env. Wire into a client like this:

```json
{
  "mcpServers": {
    "coinstats": {
      "command": "npx",
      "args": ["-y", "@coinstats/coinstats-mcp"],
      "env": { "COINSTATS_API_KEY": "<YOUR_API_KEY>" }
    }
  }
}
```

Or via Docker:

```json
{
  "mcpServers": {
    "coinstats": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "-e", "COINSTATS_API_KEY", "coinstats/coinstats-mcp"],
      "env": { "COINSTATS_API_KEY": "<YOUR_API_KEY>" }
    }
  }
}
```

This path is the right choice for headless / unattended integrations where there's no human to click "Approve". Get a key from the [CoinStats API Dashboard](https://openapi.coinstats.app).

## Architecture

The hosted server is a stateless Cloudflare Worker (~225 KiB / ~41 KiB gzipped) that:

1. Exposes the RFC 9728 + RFC 8414 discovery endpoints.
2. Gates `POST /mcp` on a `Authorization: Bearer …` token.
3. Dispatches MCP JSON-RPC (`initialize` / `tools/list` / `tools/call` / `ping`) without session state.
4. Forwards each tool call to `https://openapiv1.coinstats.app` carrying the same bearer.

Source: [`src/worker.ts`](./src/worker.ts). Config: [`wrangler.jsonc`](./wrangler.jsonc).

## Local development

The repo ships two entry points:

- **`src/worker.ts`** — Cloudflare Worker. Run with `wrangler dev` (port 8787 by default).
- **`src/index.ts`** — stdio server. Run with `node dist/index.js` after building, or via the published npm package.

```bash
# Build the stdio CLI
npm run build

# Run the Worker locally (requires `wrangler login` first)
npm run dev

# Deploy the Worker manually — needs CLOUDFLARE_ACCOUNT_ID exported in the
# env (the account ID isn't committed to wrangler.jsonc). Normally you don't
# need this: merging to main deploys automatically (see "Deployment" below).
export CLOUDFLARE_ACCOUNT_ID=<your-cf-account-id>
npm run deploy

# Tail production logs
npm run tail
```

For local Worker development you can override env vars:

```bash
wrangler dev --var OAUTH_ISSUER:http://localhost:1337 \
             --var COINSTATS_API_BASE_URL:http://localhost:9999
```

## Deployment

GitHub Actions (`.github/workflows/ci.yml`) builds, tests and dry-run bundles the Worker on every pull request. Each push to `main` runs the same checks, then deploys to `mcp.coinstats.app` and probes `/healthz`. The deploy job uses the `production` environment, which only protected branches can use, and reads two secrets from it: `CLOUDFLARE_API_TOKEN` (Workers deploy permission) and `CLOUDFLARE_ACCOUNT_ID`. Pull requests from forks run the checks without access to either secret. To redeploy without a new commit, run the workflow manually on `main`; the deploy job only ships the current tip of `main`, so re-running an old run fails instead of rolling back.

A failed post-deploy health check does not roll back automatically. To restore the previous version, run `npx wrangler rollback` (or pick a version under Workers & Pages → coinstats-mcp → Deployments in the Cloudflare dashboard), then fix forward on `main`.

### OpenAI plugin domain verification

The OpenAI plugin submission portal verifies domain ownership by fetching `https://mcp.coinstats.app/.well-known/openai-apps-challenge` and expecting the token it issued as plain text. The Worker serves the `OPENAI_APPS_CHALLENGE` env var at that path, and returns 404 when the variable is unset. Set it per deployment, outside the committed config:

```bash
wrangler secret put OPENAI_APPS_CHALLENGE
```

## Related

- [CoinStats API docs](https://coinstats.app/api-docs) — full REST surface, MCP setup guide, tool catalog
- [API dashboard](https://openapi.coinstats.app) — for stdio-mode users to manage their developer API key

## License

MIT — see [LICENSE](./LICENSE).

TDQS

B3/5.0

Scored across 30 tools

Disambiguation4/5

Most tools have distinct purposes targeting specific resources like coins, exchanges, wallets, portfolios, or news, with clear boundaries. However, some potential confusion exists between get-currencies and get-fiat-currencies (both list fiat currencies) and get-exchange-balance versus get-wallet-balance (similar balance concepts but for different assets).

Naming Consistency5/5

Tool names follow a highly consistent verb-noun pattern with hyphens, primarily using 'get-' for retrieval operations (e.g., get-coin-by-id, get-exchange-balance) and other verbs like 'add-', 'save-', and 'transactions-sync' for actions. This uniformity makes the set predictable and easy to navigate.

Tool Count3/5

With 30 tools, the count is borderline high for a cryptocurrency portfolio and data server, potentially overwhelming for agents. While the domain is broad (covering coins, exchanges, wallets, portfolios, news), the number suggests some tools might be redundant or overly granular, such as multiple news-related tools that could be consolidated.

Completeness5/5

The tool set provides comprehensive coverage for cryptocurrency portfolio management and data analysis, including CRUD-like operations (e.g., add-portfolio-transaction, get-portfolio-transactions), data retrieval (coins, exchanges, wallets, news), and synchronization features. No obvious gaps are present; agents can perform end-to-end workflows from data fetching to portfolio updates.

Maintenance

ActivityActive
ResponsivenessNo recent community issues