mcp-crypto-arbitrage
by abe-source
README.md
<p align="center">
<img src="assets/hero.svg" alt="mcp-crypto-arbitrage" width="100%" />
</p>
<p align="center">
<a href="https://github.com/abe-source/mcp-crypto-arbitrage/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-4ade80.svg" alt="MIT License"></a>
<img src="https://img.shields.io/badge/node-%3E%3D18-4ade80.svg" alt="Node >= 18">
<img src="https://img.shields.io/badge/TypeScript-7-4ade80.svg" alt="TypeScript 7">
<img src="https://img.shields.io/badge/MCP-server-4ade80.svg" alt="MCP Server">
</p>
An [MCP](https://modelcontextprotocol.io) server that exposes [CoinGecko](https://www.coingecko.com) crypto market data as tools — get spot prices and find cross-exchange arbitrage spreads without ever needing an API key.
## Tools
| Tool | What it does |
|------|---------------|
| `get_coin_prices` | Current USD prices for one or more coins by CoinGecko ID |
| `find_arbitrage` | Widest cross-exchange USD/USDT price spread for one coin, above a minimum percentage |
| `scan_top_coins` | Scan the top N coins by market cap for arbitrage spreads above a threshold |
## Prerequisites
- Node.js 18+
- Nothing else — CoinGecko's public API works with no key. Optionally set `COINGECKO_API_KEY` (free [Demo key](https://www.coingecko.com/en/api/pricing)) for a higher rate limit (100 calls/min vs the public tier's much lower limit)
## Installation
### Quick install
The package is published on npm, so these register it in one step — no cloning or building required:
**Claude Code:**
```bash
claude mcp add crypto-arbitrage -- npx -y mcp-crypto-arbitrage
```
**Codex CLI:**
```bash
codex mcp add crypto-arbitrage -- npx -y mcp-crypto-arbitrage
```
### Manual config (any stdio MCP client)
Most clients that support stdio MCP servers (Claude Desktop, Cursor, Windsurf, etc.) use this same config shape — add it to whichever config file your client expects:
```json
{
"mcpServers": {
"crypto-arbitrage": {
"command": "node",
"args": ["/absolute/path/to/mcp-crypto-arbitrage/dist/index.js"]
}
}
}
```
Add `COINGECKO_API_KEY` under `env` if you have one.
Restart your client, then try asking:
> "What's the price of bitcoin and ethereum right now?"
>
> "Is there an arbitrage opportunity on solana above 0.5%?"
>
> "Scan the top 10 coins for cross-exchange spreads"
## How it works
```
MCP client (Claude, Inspector, ...)
│ stdio, JSON-RPC
▼
McpServer (src/server.ts)
│
▼
tools/*.ts — one file per tool: Zod schema + handler, formats the reply
│
▼
endpoints/*.ts — one file per CoinGecko endpoint: typed request + response
│
▼
apiClient.ts — optional demo-key header, CoinGecko error/rate-limit parsing
│
▼
client.ts — generic fetch wrapper, timeout, HTTP error handling
│
▼
CoinGecko REST API
```
Each layer knows nothing about the one above it. `client.ts` doesn't know CoinGecko exists; `endpoints/` doesn't know MCP exists. Adding a new tool means one new file in `endpoints/`, one new file in `tools/`, one line in `tools/index.ts` — nothing else changes.
Tool arguments are validated with [Zod](https://zod.dev) before any handler runs — a malformed request never reaches the API.
`find_arbitrage` and `scan_top_coins` compare only USD/USDT-quoted markets from CoinGecko's `/coins/{id}/tickers` endpoint — the widest gap between the lowest and highest last-traded price across those markets is reported as the spread. This is raw market-data spread, not a tradeable guarantee: it ignores withdrawal/deposit friction, exchange fees, and execution slippage.
## Development
```bash
git clone https://github.com/abe-source/mcp-crypto-arbitrage.git
cd mcp-crypto-arbitrage
npm install
npm run build # compile TypeScript
npm run lint # check formatting + lint rules
npm run check # lint + format + fix, in place
```
Test locally with the [MCP Inspector](https://github.com/modelcontextprotocol/inspector):
```bash
npx @modelcontextprotocol/inspector --cli node dist/index.js --method tools/call --tool-name get_coin_prices --tool-arg coins=bitcoin,ethereum
```
## License
MIT
TDQS
A4.1/5.0
Scored across 3 tools
Disambiguation5/5
Each tool has a clearly distinct purpose: get_coin_prices retrieves prices, find_arbitrage analyzes a single coin's spread, and scan_top_coins scans multiple coins. No overlap.
Naming Consistency5/5
All tool names follow a consistent verb_noun pattern in snake_case: get_coin_prices, find_arbitrage, scan_top_coins. Very predictable.
Tool Count5/5
Three tools is appropriate for a focused crypto arbitrage server. Each tool adds distinct value without redundancy.
Completeness4/5
Covers core arbitrage functionality: price retrieval, single-coin spread, and multi-coin scan. Minor gap: no tool for listing supported coins or exchanges, but CoinGecko IDs are well-known.
Maintenance
ActivitySlowing
ResponsivenessNo issues