uniswapx-analyzer-mcp
Version:
Model Context Protocol server for UniswapX trading analytics and metrics with multi-chain support (base, ethereum) and cloud deployment
360 lines (295 loc) • 12 kB
Markdown
# UniswapX Analyzer MCP Server
A Model Context Protocol (MCP) server that provides AI agents with access to comprehensive UniswapX trading analytics and metrics. Now supports both local development and cloud deployment!
## Overview
This MCP server exposes UniswapX trading data and analytics through 5 powerful filler-centric tools:
- **Market Overview** - Comprehensive market analysis with filler profit focus and daily breakdown
- **Filler Analysis** - Detailed filler rankings and individual filler performance analysis with tag support
- **Profitable Orders** - Most profitable orders ranked by filler profit with filtering capabilities
- **Token Insights** - Token and token pair analytics ranked by filler profit with flexible sorting
- **SolvedType Analysis** - Comprehensive analysis by solvedType categories with professional Slack formatting
## Quick Start
### Installation & Setup
No installation required! The package is run via `npx`:
1. **Get Google API Key**:
- Go to [Google Cloud Console](https://console.cloud.google.com/)
- Create/select a project
- Enable Google Drive API
- Create credentials (API Key)
- Restrict API key to Google Drive API
2. **Get API Access**:
- Request access to the UniswapX data folder from the administrator
- You'll receive a `GOOGLE_DRIVE_FOLDER_ID`
- Get Portus API credentials for SolvedType analysis
3. **Configure Cursor MCP**:
Edit `~/.cursor/mcp.json`:
```json
{
"mcpServers": {
"uniswapx-analyzer": {
"command": "npx",
"args": ["-y", "--package=uniswapx-analyzer-mcp", "uniswapx-analyzer-mcp"],
"env": {
"GOOGLE_DRIVE_FOLDER_ID": "your_shared_folder_id",
"GOOGLE_API_KEY": "your_google_api_key",
"BASE_RPC_URL": "https://mainnet.base.org",
"PORTUS_API_URL": "your_portus_api_url",
"PORTUS_API_KEY": "your_portus_api_key"
}
}
}
}
```
4. **Restart Cursor** and you're ready!
### Example Queries
Try these natural language queries in Cursor chat:
**Market Analysis:**
- "Show me yesterday's market overview with filler profit focus"
- "Get market metrics for the past week with daily breakdown"
**Filler Analysis:**
- "How much did Portus earn last week?"
- "Show me the top 5 fillers from yesterday"
- "Analyze King's performance over the past 3 days"
**Order Analysis:**
- "Get the most profitable Speed orders from the past 2 days"
- "Show me top 10 orders by filler profit this week"
**Token Analysis:**
- "Which tokens generated the most filler profit yesterday?"
- "Show me top token pairs sorted by volume"
## Tools Reference
### `get_market_overview`
Get comprehensive market analysis focused on filler profit with optional daily breakdown.
**Parameters:**
- `start_date` (required): Start date in YYYY-MM-DD format
- `end_date` (optional): End date in YYYY-MM-DD format (defaults to start_date)
- `include_daily_breakdown` (optional): Include daily breakdown (default: false)
**Features:**
- Market summary with filler profit focus
- Solved type ratios and breakdowns
- Active filler counts and rankings
- Optional daily breakdown with filler profit ratios
**Example Response:**
```json
{
"date_range": "2025-08-03 to 2025-08-03",
"summary": {
"total_orders": 1250,
"total_volume_usd": 2500000,
"total_filler_profit_usd": 15000,
"active_fillers": 45,
"filler_profit_ratio": 0.65
},
"solved_type_breakdown": {
"normal_ratio": 0.45,
"speed_ratio": 0.30,
"resolved_ratio": 0.20,
"other_ratio": 0.05
},
"top_fillers": [
{
"rank": 1,
"address": "0xf85e...c59b",
"tag": "🦦 Portus",
"orders": 156,
"filler_profit_usd": 3240.50
}
]
}
```
### `get_filler_analysis`
Get detailed filler performance analysis with natural language tag support.
**Parameters:**
- `start_date` (required): Start date in YYYY-MM-DD format
- `end_date` (optional): End date in YYYY-MM-DD format (defaults to start_date)
- `filler` (optional): Filler address or tag name ("portus", "king", etc.)
- `solved_type` (optional): Filter by solved type ("Normal", "Speed", "Resolved", "Other")
- `limit` (optional): Maximum number of fillers (default: 10, max: 50)
- `sort_by` (optional): Sort by "profit", "volume", or "orders" (default: "profit")
**Features:**
- Natural language filler identification ("portus" → address resolution)
- Individual filler detailed analysis
- Filler rankings with comprehensive metrics
- Solved type breakdown per filler
**Example Response:**
```json
{
"date_range": "2025-08-02 to 2025-08-03",
"analysis_type": "individual",
"filler": {
"address": "0x606a2c650b1c692686a1370ee586e4a3d711d8b0",
"tag": "🦦 Portus",
"orders": 245,
"total_filler_profit_usd": 5240.75,
"solved_type_breakdown": {
"Normal": { "orders": 120, "filler_profit": 2100.25 },
"Speed": { "orders": 100, "filler_profit": 2840.50 },
"Resolved": { "orders": 25, "filler_profit": 300.00 }
}
}
}
```
### `get_profitable_orders`
Get most profitable orders ranked by filler profit with filtering capabilities.
**Parameters:**
- `start_date` (required): Start date in YYYY-MM-DD format
- `end_date` (optional): End date in YYYY-MM-DD format (defaults to start_date)
- `filler` (optional): Filter by filler address or tag name ("portus", "king", etc.)
- `solved_type` (optional): Filter by solved type ("Normal", "Speed", "Resolved", "Other")
- `sort_by` (optional): Sort by "profit", "volume", or "orders" (default: "profit")
- `limit` (optional): Maximum number of orders (default: 10, max: 100)
**Features:**
- Orders ranked by filler profit (not order profit)
- Natural language filler filtering
- Solved type filtering
- Complete order details with URLs
**Example Response:**
```json
{
"date_range": "2025-08-02 to 2025-08-03",
"filters": {
"filler": "portus",
"solved_type": "Speed"
},
"top_orders": [
{
"rank": 1,
"order_hash": "0x123...",
"tx_hash": "0xabc...",
"filler": {
"address": "0xf85e...",
"tag": "🦦 Portus"
},
"volume_usd": 50000,
"filler_profit_usd": 245.75,
"filler_profit_ratio": 0.78,
"solved_type": "Speed",
"urls": {
"uniswapx_api": "https://api.uniswap.org/v2/orders/0x123...",
"basescan": "https://basescan.org/tx/0xabc..."
}
}
]
}
```
### `get_token_insights`
Get token or token pair analytics ranked by filler profit with flexible sorting.
**Parameters:**
- `start_date` (required): Start date in YYYY-MM-DD format
- `end_date` (optional): End date in YYYY-MM-DD format (defaults to start_date)
- `analysis_type` (required): Analysis type - "tokens" or "pairs"
- `filler` (optional): Filter by filler address or tag name ("portus", "king", etc.)
- `solved_type` (optional): Filter by solved type ("Normal", "Speed", "Resolved", "Other")
- `sort_by` (optional): Sort by "profit", "volume", or "orders" (default: "profit")
- `limit` (optional): Maximum number of results (default: 10, max: 100)
**Features:**
- Focus on filler profit (not order profit)
- Flexible sorting options
- Real token symbols via TokenInfoManager
- Optimized performance (90% fewer RPC calls)
**Example Response:**
```json
{
"date_range": {
"start": "2025-08-03",
"end": "2025-08-03"
},
"analysis_type": "tokens",
"sort_by": "profit",
"analytics": [
{
"rank": 1,
"token_address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
"symbol": "USDC",
"orders": 456,
"volume": 1250000,
"total_filler_profit": 8240.50
}
]
}
```
### `get_solvedtype_report` (NEW)
Get comprehensive SolvedType analysis with professional Slack formatting.
**Parameters:**
- `start_date` (required): Start date in YYYY-MM-DD format
- `end_date` (optional): End date in YYYY-MM-DD format (defaults to start_date for single day)
**Features:**
- **Full TokenInfoManager Integration**: Real token symbols via RPC lookups
- **PortusApiClient Integration**: Speed order time interval analysis (1s, 2s, 3s, 4s, 5s+)
- **Comprehensive Analysis**: Normal token pairs, Speed intervals, Resolved block lags
- **Professional Slack Formatting**: ASCII tables, structured sections, rich formatting
- **Identical to Local Version**: Same analysis quality as local SolvedTypeReporter
**Returns:** Complete Slack message blocks ready to send
## Data Source
Data is fetched from a shared Google Drive folder containing:
- Daily transaction data files (`YYYY-MM-DD.jsonl.gz`)
- Token cache and price information
- Historical trading data
The server automatically:
- Downloads and caches files locally
- Handles compressed data files
- Provides offline capability with cached data
- Updates cache when new data is available
## Troubleshooting
### "GOOGLE_DRIVE_FOLDER_ID environment variable is required"
- Check your `~/.cursor/mcp.json` configuration
- Ensure the folder ID is correct (provided by administrator)
### "GOOGLE_API_KEY environment variable is required"
- Verify your Google API key is properly configured
- Check that Google Drive API is enabled for your key
### "No data file found for date"
- Data may not be available for requested date
- Try a more recent date (data is typically 1-2 days behind)
### "Failed to list Google Drive files"
- Check your API key has access to Google Drive API
- Verify you have permission to access the shared folder
### Connection Issues
- Restart Cursor after configuration changes
- Check internet connection for Google Drive access
- Clear cache if encountering stale data
## Deployment Options
### Local Development (Default)
The server automatically uses stdio transport for local MCP clients like Cursor IDE:
```bash
npx uniswapx-analyzer-mcp
```
### Cloud Deployment (Enhanced in v1.2.3+)
The server automatically detects cloud environments and switches to HTTP transport:
- **Google Cloud Run**: Set `PORT` environment variable to enable HTTP mode
- **Health Check**: `GET /health` endpoint for monitoring
- **Auto-Detection**: No configuration needed - works based on environment
#### Transport Endpoints
The server provides two different transport methods for different clients:
**1. SSE Endpoint** (`GET /sse`)
- For official MCP SDK clients that support Server-Sent Events
- Follows MCP SSE transport specification
- Example: Official MCP Python/Node.js clients
**2. HTTP Message Endpoint** (`POST /message`)
- For direct HTTP JSON-RPC calls
- Simpler integration for custom clients
- Example: Custom HTTP clients like the Slack bot
#### Example Cloud Run Deployment
```bash
# Deploy to Google Cloud Run
gcloud run deploy uniswapx-mcp-server \
--source . \
--platform managed \
--region us-central1 \
--allow-unauthenticated \
--set-env-vars="GOOGLE_DRIVE_FOLDER_ID=your_folder_id,GOOGLE_API_KEY=your_api_key"
```
#### Transport Selection Guide
- **Use SSE** (`/sse`) for official MCP SDK clients
- **Use HTTP** (`/message`) for custom implementations or when SSE timeouts occur
- Both endpoints support the same 5 MCP tools with identical functionality
## Technical Details
- **Node.js**: Requires 18+ for ES modules support
- **Dependencies**: Google APIs client, MCP SDK, Express.js (for cloud mode), ethers, node-fetch
- **Build System**: esbuild bundling for optimized dependency resolution
- **Formatting**: Shared FormattingUtils for consistent number/currency formatting
- **Transport**: Auto-detects stdio (local) vs HTTP/SSE (cloud)
- **Caching**: Local cache in `/tmp/uniswapx-cache/`
- **Data Format**: JSONL with optional gzip compression
- **API Limits**: Respects Google Drive API rate limits
## Support
- **Repository**: [UniswapX Analyzer](https://github.com/JavanC/UniswapXAnalyzer)
- **Issues**: [GitHub Issues](https://github.com/JavanC/UniswapXAnalyzer/issues)
- **Documentation**: [MCP Package Docs](https://github.com/JavanC/UniswapXAnalyzer/tree/main/packages/uniswapx-analyzer-mcp)