Skip to main content
Glama
README.md
# MCP Mempool ๐Ÿš€

**๋น„ํŠธ์ฝ”์ธ mempool.space WebSocket & REST API๋ฅผ ์œ„ํ•œ Model Context Protocol (MCP) ์„œ๋ฒ„**

[![Docker](https://img.shields.io/badge/docker-%230db7ed.svg?style=for-the-badge&logo=docker&logoColor=white)](https://docker.com)
[![Python](https://img.shields.io/badge/python-3.11+-blue.svg?style=for-the-badge&logo=python&logoColor=white)](https://python.org)
[![FastAPI](https://img.shields.io/badge/FastAPI-005571?style=for-the-badge&logo=fastapi)](https://fastapi.tiangolo.com)
[![Bitcoin](https://img.shields.io/badge/Bitcoin-FF9900?style=for-the-badge&logo=bitcoin&logoColor=white)](https://bitcoin.org)

## ๐Ÿ“‹ ๊ฐœ์š”

MCP Mempool์€ mempool.space์˜ WebSocket๊ณผ REST API๋ฅผ MCP (Model Context Protocol) ํ˜•ํƒœ๋กœ ๋ž˜ํ•‘ํ•˜์—ฌ AI Agent์™€ ์™ธ๋ถ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋น„ํŠธ์ฝ”์ธ ๋„คํŠธ์›Œํฌ ๋ฐ์ดํ„ฐ๋ฅผ ์‰ฝ๊ฒŒ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ์„œ๋ฒ„์ž…๋‹ˆ๋‹ค.

### โœจ ์ฃผ์š” ๊ธฐ๋Šฅ

#### ๐Ÿ”„ WebSocket ๊ธฐ๋Šฅ (์‹ค์‹œ๊ฐ„)
- **์‹ค์‹œ๊ฐ„ ๋ธ”๋ก ๋ฐ์ดํ„ฐ**: ์ƒˆ ๋ธ”๋ก ์ƒ์„ฑ ์‹œ ์ฆ‰์‹œ ์•Œ๋ฆผ
- **๋ฉคํ’€ ๋ธ”๋ก ํ…œํ”Œ๋ฆฟ**: ์˜ˆ์ƒ๋˜๋Š” ๋‹ค์Œ ๋ธ”๋ก ์ •๋ณด
- **๋„คํŠธ์›Œํฌ ํ†ต๊ณ„**: ๋ฉ”๋ชจ๋ฆฌํ’€ ์ƒํƒœ ์‹ค์‹œ๊ฐ„ ๋ชจ๋‹ˆํ„ฐ๋ง  
- **์ฃผ์†Œ ์ถ”์ **: ํŠน์ • ๋น„ํŠธ์ฝ”์ธ ์ฃผ์†Œ์˜ ๊ฑฐ๋ž˜ ์‹ค์‹œ๊ฐ„ ์ถ”์ 
- **๋ผ์ด๋ธŒ ์ฐจํŠธ**: ์ˆ˜์ˆ˜๋ฃŒ ๋ณ€ํ™” ์ถ”์ด ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ

#### ๐Ÿ” REST API ๊ธฐ๋Šฅ (์ฟผ๋ฆฌ)
- **์ฃผ์†Œ ์ •๋ณด ์กฐํšŒ**: ์ž”์•ก, ๊ฑฐ๋ž˜ ๋‚ด์—ญ, UTXO ๋ชฉ๋ก
- **๊ฑฐ๋ž˜ ์ •๋ณด**: ๊ฐœ๋ณ„ ๊ฑฐ๋ž˜ ์ƒ์„ธ ์ •๋ณด ๋ฐ ์ƒํƒœ
- **๋ธ”๋ก ๋ฐ์ดํ„ฐ**: ๋ธ”๋ก ์ •๋ณด, ๊ฑฐ๋ž˜ ๋ชฉ๋ก, ์ตœ์‹  ๋†’์ด
- **์ˆ˜์ˆ˜๋ฃŒ ์ •๋ณด**: ์ถ”์ฒœ ์ˆ˜์ˆ˜๋ฃŒ์œจ, ๋ฉคํ’€ ๋ธ”๋ก๋ณ„ ์ˆ˜์ˆ˜๋ฃŒ
- **๋ฉคํ’€ ์ƒํƒœ**: ํ˜„์žฌ ๋ฉคํ’€ ์ •๋ณด ๋ฐ ์ตœ๊ทผ ๊ฑฐ๋ž˜
- **์ฃผ์†Œ ๊ฒ€์ฆ**: ๋น„ํŠธ์ฝ”์ธ ์ฃผ์†Œ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ

## ๐Ÿš€ ๋น ๋ฅธ ์‹œ์ž‘

### Docker๋กœ ์‹คํ–‰ (๊ถŒ์žฅ)

```bash
# ๊ฐœ๋ฐœ ํ™˜๊ฒฝ
docker-compose up mcp-mempool-dev

# ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ  
docker-compose up mcp-mempool-prod
```

์„œ๋ฒ„๊ฐ€ ์‹คํ–‰๋˜๋ฉด http://localhost:8000 ์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

### ๋กœ์ปฌ ์„ค์น˜

```bash
# ์˜์กด์„ฑ ์„ค์น˜
uv sync

# ์„œ๋ฒ„ ์‹คํ–‰
uv run python -m mempool_ws_mcp_server.main
```

## ๐Ÿ”ง ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ •

```bash
# ์„œ๋ฒ„ ์„ค์ •
MCP_HOST=0.0.0.0                      # ์„œ๋ฒ„ ํ˜ธ์ŠคํŠธ
MCP_PORT=8000                         # ์„œ๋ฒ„ ํฌํŠธ
LOG_LEVEL=INFO                        # ๋กœ๊ทธ ๋ ˆ๋ฒจ

# Mempool API ์„ค์ •
MEMPOOL_WS_URL=wss://mempool.space/api/v1/ws    # WebSocket URL
MEMPOOL_API_URL=https://mempool.space/api       # REST API URL

# WebSocket ์„ค์ •
WS_RECONNECT_INTERVAL=5               # ์žฌ์—ฐ๊ฒฐ ๊ฐ„๊ฒฉ (์ดˆ)
WS_MAX_RECONNECT_ATTEMPTS=10          # ์ตœ๋Œ€ ์žฌ์—ฐ๊ฒฐ ์‹œ๋„
WS_PING_INTERVAL=30                   # Ping ๊ฐ„๊ฒฉ (์ดˆ)
WS_PING_TIMEOUT=10                    # Ping ํƒ€์ž„์•„์›ƒ (์ดˆ)

# HTTP ํด๋ผ์ด์–ธํŠธ ์„ค์ •
HTTP_TIMEOUT=30                       # HTTP ์š”์ฒญ ํƒ€์ž„์•„์›ƒ (์ดˆ)
HTTP_MAX_RETRIES=3                    # ์ตœ๋Œ€ ์žฌ์‹œ๋„ ํšŸ์ˆ˜

# ์„ฑ๋Šฅ ์„ค์ •
MAX_MESSAGE_QUEUE_SIZE=1000           # ๋ฉ”์‹œ์ง€ ํ ์ตœ๋Œ€ ํฌ๊ธฐ
MESSAGE_BATCH_SIZE=10                 # ๋ฉ”์‹œ์ง€ ๋ฐฐ์น˜ ํฌ๊ธฐ

# ๋ณด์•ˆ ์„ค์ •
CORS_ENABLED=true                     # CORS ํ™œ์„ฑํ™”
ALLOWED_ORIGINS=*                     # ํ—ˆ์šฉ๋œ ์˜ค๋ฆฌ์ง„ (์ฝค๋งˆ ๊ตฌ๋ถ„)

# ๊ฐœ๋ฐœ ๋ชจ๋“œ
DEBUG=false                           # ๋””๋ฒ„๊ทธ ๋ชจ๋“œ
RELOAD=false                          # ์ž๋™ ์žฌ์‹œ์ž‘
```

## ๐Ÿ›  MCP ํด๋ผ์ด์–ธํŠธ ์„ค์ •

### Claude Desktop

`claude_desktop_config.json` ํŒŒ์ผ์— ์ถ”๊ฐ€:

```json
{
  "mcpServers": {
    "mcp-mempool": {
      "command": "npx",
      "args": ["mcp-remote", "http://localhost:8000/mcp"]
    }
  }
}

{
  "mcpServers": {
    "mcp-mempool": {
      "transport": "streamable-http",
      "url" : "http://127.0.0.1:8000/mcp" //๋ฐฐํฌ์‹œ ์‹ค์ œ ์„œ๋น™ url
    }
  }
}

```

### Amazon Q Developer

`.aws/amazonq/mcp.json` ํŒŒ์ผ์— ์ถ”๊ฐ€:

```json
{
  "mcpServers": {
    "mcp-mempool": {
      "command": "npx", 
      "args": ["mcp-remote", "http://localhost:8000/mcp"],
      "env": {
        "FASTMCP_LOG_LEVEL": "ERROR"
      }
    }
  }
}
```

## ๐Ÿ“ก ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋„๊ตฌ๋“ค

### WebSocket ๋„๊ตฌ (์‹ค์‹œ๊ฐ„ ์ŠคํŠธ๋ฆฌ๋ฐ)

#### `subscribe_blocks`
์ƒˆ ๋ธ”๋ก ์ƒ์„ฑ ์‹œ ์‹ค์‹œ๊ฐ„ ์•Œ๋ฆผ์„ ๋ฐ›์Šต๋‹ˆ๋‹ค.

#### `subscribe_mempool_blocks` 
์˜ˆ์ƒ๋˜๋Š” ๋‹ค์Œ ๋ธ”๋ก ํ…œํ”Œ๋ฆฟ ์ •๋ณด๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค.

#### `subscribe_stats`
๋„คํŠธ์›Œํฌ ๋ฉ”๋ชจ๋ฆฌํ’€ ํ†ต๊ณ„๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ชจ๋‹ˆํ„ฐ๋งํ•ฉ๋‹ˆ๋‹ค.

#### `subscribe_live_chart`
2์‹œ๊ฐ„ ๋ผ์ด๋ธŒ ์ˆ˜์ˆ˜๋ฃŒ ์ฐจํŠธ ๋ฐ์ดํ„ฐ๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค.

#### `track_address`
ํŠน์ • ๋น„ํŠธ์ฝ”์ธ ์ฃผ์†Œ์˜ ๊ฑฐ๋ž˜๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค.
- `address`: ์ถ”์ ํ•  ๋น„ํŠธ์ฝ”์ธ ์ฃผ์†Œ

#### `get_connection_status`
WebSocket ์—ฐ๊ฒฐ ์ƒํƒœ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

#### `unsubscribe_client`
ํด๋ผ์ด์–ธํŠธ์˜ ๋ชจ๋“  ๊ตฌ๋…์„ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค.
- `client_id`: ๊ตฌ๋… ํ•ด์ œํ•  ํด๋ผ์ด์–ธํŠธ ID

### REST API ๋„๊ตฌ (์ฟผ๋ฆฌ)

#### ์ฃผ์†Œ ๊ด€๋ จ

**`get_address_info`** - ์ฃผ์†Œ์˜ ๋ชจ๋“  ์ •๋ณด ์กฐํšŒ
- `address`: ๋น„ํŠธ์ฝ”์ธ ์ฃผ์†Œ

**`get_address_balance`** - ์ฃผ์†Œ ์ž”์•ก ์กฐํšŒ  
- `address`: ๋น„ํŠธ์ฝ”์ธ ์ฃผ์†Œ

**`get_address_utxos`** - ์ฃผ์†Œ์˜ UTXO ๋ชฉ๋ก ์กฐํšŒ
- `address`: ๋น„ํŠธ์ฝ”์ธ ์ฃผ์†Œ

**`get_address_transactions`** - ์ฃผ์†Œ์˜ ๊ฑฐ๋ž˜ ๋‚ด์—ญ ์กฐํšŒ
- `address`: ๋น„ํŠธ์ฝ”์ธ ์ฃผ์†Œ
- `after_txid` (์„ ํƒ): ํŠน์ • ๊ฑฐ๋ž˜ ์ดํ›„์˜ ๊ฑฐ๋ž˜๋“ค๋งŒ ์กฐํšŒ

#### ๊ฑฐ๋ž˜ ๊ด€๋ จ

**`get_transaction_info`** - ๊ฑฐ๋ž˜ ์ •๋ณด ์กฐํšŒ
- `txid`: ๊ฑฐ๋ž˜ ID

**`get_block_info`** - ๋ธ”๋ก ์ •๋ณด ์กฐํšŒ  
- `hash_or_height`: ๋ธ”๋ก ํ•ด์‹œ ๋˜๋Š” ๋†’์ด

**`get_block_height`** - ํ˜„์žฌ ๋ธ”๋ก ๋†’์ด ์กฐํšŒ

#### ์ˆ˜์ˆ˜๋ฃŒ & ๋ฉคํ’€

**`get_recommended_fees`** - ์ถ”์ฒœ ์ˆ˜์ˆ˜๋ฃŒ์œจ ์กฐํšŒ

**`get_mempool_info`** - ํ˜„์žฌ ๋ฉคํ’€ ์ •๋ณด ์กฐํšŒ

#### ์œ ํ‹ธ๋ฆฌํ‹ฐ

**`validate_bitcoin_address`** - ๋น„ํŠธ์ฝ”์ธ ์ฃผ์†Œ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ
- `address`: ๊ฒ€์ฆํ•  ์ฃผ์†Œ

## ๐Ÿ’ป ์‚ฌ์šฉ ์˜ˆ์‹œ

### ์ฃผ์†Œ ์ž”์•ก ์กฐํšŒ

```bash
# MCP ํด๋ผ์ด์–ธํŠธ์—์„œ ์‚ฌ์šฉ
get_address_balance address="1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
```

### ์‹ค์‹œ๊ฐ„ ์ˆ˜์ˆ˜๋ฃŒ ๋ชจ๋‹ˆํ„ฐ๋ง

```bash
# ์‹ค์‹œ๊ฐ„ ๋ฉคํ’€ ๋ธ”๋ก ๊ตฌ๋…
subscribe_mempool_blocks

# ์ถ”์ฒœ ์ˆ˜์ˆ˜๋ฃŒ ์กฐํšŒ
get_recommended_fees
```

### ์ฃผ์†Œ ์ถ”์ 

```bash
# ํŠน์ • ์ฃผ์†Œ ์‹ค์‹œ๊ฐ„ ์ถ”์ 
track_address address="1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
```

## ๐Ÿ— ๊ฐœ๋ฐœ

### ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ •

```bash
# ํ”„๋กœ์ ํŠธ ํด๋ก 
git clone <repository-url>
cd mcp-mempool

# ๊ฐœ๋ฐœ ์˜์กด์„ฑ ์„ค์น˜
uv sync --dev

# ๊ฐœ๋ฐœ ์„œ๋ฒ„ ์‹คํ–‰
uv run python -m mempool_ws_mcp_server.main
```

### ํ…Œ์ŠคํŠธ ์‹คํ–‰

```bash
# ๋ชจ๋“  ํ…Œ์ŠคํŠธ ์‹คํ–‰
uv run pytest

# ์ปค๋ฒ„๋ฆฌ์ง€ ํฌํ•จ
uv run pytest --cov=mempool_ws_mcp_server
```

### ์ฝ”๋“œ ํ’ˆ์งˆ ๋„๊ตฌ

```bash
# ๋ฆฐํŒ…
uv run ruff check .

# ํฌ๋งทํŒ…
uv run ruff format .

# ํƒ€์ž… ์ฒดํฌ
uv run mypy src/
```

## ๐Ÿณ Docker ๋นŒ๋“œ

```bash
# ์ด๋ฏธ์ง€ ๋นŒ๋“œ
docker build -t mcp-mempool .

# ๋ฉ€ํ‹ฐ ์•„ํ‚คํ…์ฒ˜ ๋นŒ๋“œ
docker buildx build --platform linux/amd64,linux/arm64 -t mcp-mempool .
```

## ๐Ÿ“Š ๋ชจ๋‹ˆํ„ฐ๋ง

```bash
# ๋ชจ๋‹ˆํ„ฐ๋ง ์Šคํƒ ์‹คํ–‰ (Prometheus + Grafana)
docker-compose --profile monitoring up

# Grafana: http://localhost:3000 (admin/admin)
# Prometheus: http://localhost:9090
```

## ๐Ÿ”— API ์—”๋“œํฌ์ธํŠธ

- **Health Check**: `GET /health`
- **Root Info**: `GET /`  
- **MCP Protocol**: `POST /mcp`
- **API Docs**: `GET /docs`

## ๐Ÿ“„ ๋ผ์ด์„ ์Šค

MIT License

## ๐Ÿค ๊ธฐ์—ฌ

์ด์Šˆ ๋ฆฌํฌํŠธ์™€ ํ’€ ๋ฆฌํ€˜์ŠคํŠธ๋ฅผ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค!

## ๐Ÿ“ž ์ง€์›

- ๋ฌธ์ œ๊ฐ€ ์žˆ์œผ์‹œ๋ฉด GitHub Issues๋ฅผ ํ™œ์šฉํ•ด์ฃผ์„ธ์š”
- ๊ฐœ์„  ์ œ์•ˆ์ด๋‚˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ์š”์ฒญ๋„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค