cryptosense-mcp
# CryptoSense MCP
**Real-time crypto market intelligence for AI assistants.**
CryptoSense MCP wraps the [CoinGecko](https://www.coingecko.com/en/api) free API (no key needed) into a production-ready [Model Context Protocol](https://modelcontextprotocol.io) server built with [FastMCP](https://github.com/jlowin/fastmcp). Connect it to Claude, Cursor, Windsurf, or any MCP-compatible client and ask natural-language questions about crypto markets.
---
## What this MCP does
| Tool | Description |
|------|-------------|
| `price` | Current price, market cap, volume & 24h change for any coin |
| `trending` | Top 10 trending coins by search volume (last 24 h) |
| `market_overview` | Global market cap, BTC/ETH dominance, 24h change |
| `top_coins` | Top N coins by market cap with full stats |
| `compare` | Side-by-side comparison of 2+ coins |
| `portfolio_value` | USD value of your holdings with best/worst performer |
All tools require a **CryptoSense API key** (see [Authentication](#authentication)).
---
## Installation
### Option A — local with `uv` (recommended)
```bash
# 1. Clone
git clone https://github.com/your-org/cryptosense-mcp.git
cd cryptosense-mcp
# 2. Create venv and install
uv venv && uv pip install -e .
# 3. Copy and edit environment variables
cp .env.example .env
# Edit .env: set CMC_API_KEY if you have one, adjust MCP_PORT if needed
# 4. Generate your first API key
python -c "
import asyncio
from src.cryptosense.auth import generate_api_key
key = asyncio.run(generate_api_key('you@example.com'))
print('Your API key:', key)
"
# 5. Start the server
cryptosense-mcp
# or: python -m cryptosense.server
```
### Option B — local with `pip`
```bash
pip install -e .
cp .env.example .env
python -m cryptosense.server
```
### Option C — Docker
```bash
docker build -t cryptosense-mcp .
docker run -p 8000:8000 \
-e CMC_API_KEY=your_key \
-v cryptosense-data:/app/data \
cryptosense-mcp
```
---
## Authentication
Every tool call requires an `api_key` parameter with a valid CryptoSense key.
### Generate a key
```python
import asyncio
from cryptosense.auth import generate_api_key
key = asyncio.run(generate_api_key(email="you@example.com", plan="free"))
print(key) # cs_Abc123...
```
Keys are stored in `keys.db` (SQLite). The `keys.db` file lives next to the server process (or at `DATABASE_URL` from `.env`).
---
## CoinGecko API key (optional)
CoinGecko's free public API works without a key. If you experience rate limiting (30 calls/min on the free tier), sign up at <https://www.coingecko.com/en/api> for a free Demo API key and add it to your `.env`:
```
CG_API_KEY=CG-xxxxxxxxxxxxxxxxxxxx
```
> The server currently uses the public endpoint. If you add a key, pass it via the `x-cg-demo-api-key` header in `_fetch()` calls.
---
## Configure Claude Desktop
Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
```json
{
"mcpServers": {
"cryptosense": {
"command": "python",
"args": ["-m", "cryptosense.server"],
"cwd": "/absolute/path/to/cryptosense-mcp",
"env": {
"MCP_HOST": "127.0.0.1",
"MCP_PORT": "8000"
}
}
}
}
```
Or if the server is already running remotely, use the HTTP transport URL:
```json
{
"mcpServers": {
"cryptosense": {
"url": "http://localhost:8000/mcp"
}
}
}
```
---
## Configure Cursor
Open **Settings → MCP → Add new MCP server** and enter:
| Field | Value |
|-------|-------|
| Name | CryptoSense |
| Type | HTTP |
| URL | `http://localhost:8000/mcp` |
Or add to `~/.cursor/mcp.json`:
```json
{
"mcpServers": {
"cryptosense": {
"url": "http://localhost:8000/mcp"
}
}
}
```
---
## Configure Windsurf
Add to `~/.codeium/windsurf/mcp_config.json`:
```json
{
"mcpServers": {
"cryptosense": {
"serverUrl": "http://localhost:8000/mcp"
}
}
}
```
---
## Tool Reference & Example Prompts
### `price` — Get coin price
> "What is the price of Bitcoin?"
> "How much is Ethereum worth in EUR?"
> "Show me Solana's 24h change and market cap."
```python
price(coin="bitcoin", currency="usd", api_key="cs_...")
# → { "coin": "bitcoin", "price": 67420.0, "market_cap": 1.32T, "change_24h_percent": 2.4, ... }
```
---
### `top_coins` — Top coins by market cap
> "Show me top 10 coins."
> "What are the top 20 cryptocurrencies by market cap?"
> "List the 5 biggest coins in EUR."
```python
top_coins(limit=10, currency="usd", api_key="cs_...")
# → { "coins": [{ "rank": 1, "name": "Bitcoin", "price": 67420, ... }, ...] }
```
---
### `trending` — Trending now
> "What is trending in crypto today?"
> "Which coin is everyone searching for?"
> "Show me the hottest altcoins right now."
```python
trending(api_key="cs_...")
# → { "trending_coins": [{ "name": "Pepe", "symbol": "PEPE", "market_cap_rank": 54, ... }] }
```
---
### `portfolio_value` — Portfolio calculator
> "Calculate my portfolio: 0.5 BTC, 5 ETH, 100 SOL."
> "How much is my crypto worth? I have 1 bitcoin and 10 ethereum."
> "What is my total if I hold 0.1 BTC, 500 DOGE, and 2 ETH?"
```python
portfolio_value(
holdings={"bitcoin": 0.5, "ethereum": 5, "solana": 100},
currency="usd",
api_key="cs_...",
)
# → { "total_value": 54230.00, "best_performer": {...}, "breakdown": [...] }
```
---
### `compare` — Side-by-side comparison
> "Compare Bitcoin and Ethereum."
> "Which performs better: Solana, Avalanche, or Polkadot?"
> "Show me BTC vs ETH vs BNB."
```python
compare(coins=["bitcoin", "ethereum", "solana"], currency="usd", api_key="cs_...")
# → { "comparison": [...], "best_performer_24h": "solana", "worst_performer_24h": "bitcoin" }
```
---
### `market_overview` — Global snapshot
> "What is the total crypto market cap?"
> "What is Bitcoin's market dominance today?"
> "Give me a global crypto summary."
```python
market_overview(api_key="cs_...")
# → { "total_market_cap_usd": 2.45T, "btc_dominance_percent": 52.3, ... }
```
---
## Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `CMC_API_KEY` | — | CoinMarketCap API key (optional, reserved for future CMC tools) |
| `MCP_HOST` | `0.0.0.0` | Server bind address |
| `MCP_PORT` | `8000` | Server port |
| `DATABASE_URL` | `keys.db` | Path to the SQLite database |
| `CRYPTOSENSE_ENABLE_KEYGEN` | — | Set to `true` to expose the `create_api_key` admin tool |
---
## Error Handling
All tools return a friendly `{"error": "..."}` dict on failure — no stack traces are ever returned to the client. Handled conditions:
- **Invalid / missing API key** → prompt to generate one
- **Coin not found** → suggests using the full CoinGecko ID
- **Rate limit (429)** → asks to wait and retry
- **Network errors** → descriptive message
- **Invalid parameters** → caught before the API call
---
## License
MIT
TDQS
Scored across 6 tools
Each tool targets a distinct query type: single price lookup, trending list, global stats, top N, comparison, and portfolio calculation. Overlap is minimal, with trending and top_coins differing by search volume versus market cap.
All names follow a consistent lowercase_with_underscores style, but the grammatical pattern is mixed: nouns (price, market_overview), gerund (trending), adjective+noun (top_coins), verb (compare), and compound noun (portfolio_value). No verb_noun pattern is established, though names remain readable.
Six tools is well-scoped for a crypto market data server, fitting comfortably within the ideal 3-15 range. Each tool has a clear purpose without redundancy.
The surface covers single-coin pricing, market lists, global overview, comparison, and portfolio valuation, covering core workflows. Historical price data and detailed coin metadata are missing, but these are not essential to the server's apparent purpose.