# 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": "0xf85e95bef8f2de7782b0936ca3480c41a4b6c59b",
    "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)