# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## **π CRITICAL REFERENCE GUIDE π**
**ALWAYS refer to the complete Remote MCP Bible when working on MCP code:**
π `/Users/rdc/src/oceancoda/shardrunner-api/docs/remote-mcp-bible.md`
This comprehensive technical guide contains ALL the essential knowledge for building Remote MCP servers, including:
- Complete protocol specifications and examples
- SSE formatting requirements
- ngrok testing workflows
- Deployment strategies
- Troubleshooting guides
- Security best practices
**REMEMBER: This bible contains the definitive implementation patterns learned through extensive development and testing. Use it as your primary reference for all MCP work.**
## Project Overview
This repository contains **TWO complete ERDDAP MCP servers** that provide tools for searching and accessing ERDDAP (Environmental Research Division's Data Access Program) oceanographic datasets:
### 1. Local MCP Server (`erddapy_mcp_server.py`)
- **Traditional stdio-based MCP server** for local Claude Desktop use
- **4 comprehensive ERDDAP tools** for data discovery and access
- **Config file setup** via `claude_desktop_config.json`
### 2. Remote MCP Server (`erddap_remote_mcp_oauth.py`)
- **HTTP-based MCP server** for cloud deployment and remote access
- **mcp-remote proxy compatible** for Claude Desktop integration
- **Production-ready** with fly.io deployment configuration
- **Same 4 tools** optimized for remote performance
## π¨ CRITICAL Remote MCP Knowledge
**HARD-WON TRUTH:** Claude Desktop does NOT support direct remote MCP connections! You MUST use the `mcp-remote` proxy.
### The Secret Architecture That Actually Works:
```
Claude Desktop (stdio) β mcp-remote proxy β Remote MCP Server (HTTP)
```
**Configuration Examples:**
**Local Server:**
```json
{
"mcpServers": {
"erddap-local": {
"command": "python",
"args": ["/Users/rdc/src/mcp/erddap2mcp/erddapy_mcp_server.py"]
}
}
}
```
**Remote Server:**
```json
{
"mcpServers": {
"erddap-remote": {
"command": "npx",
"args": ["mcp-remote", "https://erddap2mcp.fly.dev/"]
}
}
}
```
## Architecture Details
### Local Server Architecture
- **MCP Library**: Uses official `mcp` Python library
- **Communication**: stdio (standard input/output)
- **ERDDAP Integration**: Official `erddapy` client library
- **Tools**: 4 comprehensive ERDDAP access tools
- **Data Processing**: Full pandas DataFrame integration
### Remote Server Architecture
- **FastAPI Framework**: HTTP server with JSON-RPC 2.0
- **Transport**: StreamableHttp via mcp-remote proxy
- **Protocol Version**: `2025-06-18` (matches Claude Desktop)
- **Tools**: Same 4 ERDDAP tools as local server
- **Deployment**: Containerized with Docker + fly.io
## Development Commands
### Local Server Development
```bash
# Install all dependencies from requirements.txt
pip install -r requirements.txt
# Run local server
python erddapy_mcp_server.py
# Run integration tests
python test_mcp_integration.py
```
### Remote Server Development
```bash
# Install dependencies
pip install -r requirements.txt
# Run remote server locally
python erddap_remote_mcp_oauth.py
# Server runs on http://localhost:8000
# Test with curl
curl -X POST http://localhost:8000/ \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "method": "tools/list", "id": 1}'
# Test with mcp-remote proxy
npx mcp-remote http://localhost:8000/ --test
```
### Cloud Deployment (fly.io)
```bash
# Install fly CLI (if not already installed)
curl -L https://fly.io/install.sh | sh
# Login to fly.io
fly auth login
# Deploy to production
fly deploy
# Monitor deployment logs
fly logs -a erddap2mcp
# Check deployment status
fly status -a erddap2mcp
# Server will be available at: https://erddap2mcp.fly.dev/
```
### Docker Build and Run
```bash
# Build Docker image
docker build -t erddap-mcp-server .
# Run container locally
docker run -p 8000:8000 erddap-mcp-server
```
## Available Tools (Both Servers)
1. **list_servers**: Lists ERDDAP servers from `erddaps.json` (63+ servers)
2. **search_datasets**: Search for datasets by keyword
3. **get_dataset_info**: Get detailed metadata about a dataset
4. **to_pandas**: Download and preview data as pandas DataFrame
## Server List Management
**Dynamic Loading from `erddaps.json`:**
- Servers are NO LONGER hardcoded in Python files
- `load_erddap_servers()` function reads from JSON file
- 63 pre-configured servers with worldwide coverage
- Fallback to 2-server minimum if file missing
- JSON structure: name, short_name, url, public flag
## Important Parameters
Both servers accept these common parameters:
- `server_url`: ERDDAP server URL (defaults to NOAA CoastWatch)
- `protocol`: Either "tabledap" (tabular data) or "griddap" (gridded data)
- `dataset_id`: The dataset identifier
- `variables`: List of variables to retrieve
- `constraints`: Dictionary of constraints (e.g., time/space bounds)
## Remote MCP Protocol Implementation
### Key Protocol Requirements
- **JSON-RPC 2.0**: Standard request/response format
- **Protocol Version**: Must be `"2025-06-18"` to match Claude Desktop
- **Capabilities**: Must declare `{"tools": {"listTools": {}, "callTool": {}}}`
- **Content Format**: Tools return `{"content": [{"type": "text", "text": "..."}]}`
- **Notifications**: Handle `notifications/initialized` method
### Critical Debugging Lessons Learned
1. **SSE Transport is DEPRECATED** - Use StreamableHttp instead
2. **Protocol version mismatch** causes silent failures
3. **Content-type headers** must be exactly right
4. **mcp-remote proxy is REQUIRED** for Claude Desktop
5. **OAuth discovery endpoints** are optional for simple servers
## File Structure
```
/Users/rdc/src/mcp/erddap2mcp/
βββ erddapy_mcp_server.py # Local MCP server (stdio)
βββ erddap_remote_mcp_oauth.py # Remote MCP server (HTTP)
βββ Dockerfile # Container for remote deployment
βββ fly.toml # fly.io configuration
βββ requirements.txt # Python dependencies
βββ test_mcp_integration.py # Integration tests
βββ CLAUDE.md # This file
βββ README.md # User documentation
```
## Debugging
### Local Server Debugging
- Debug output goes to stderr with "DEBUG:" prefix
- Monitor MCP client logs for communication issues
- Use `test_mcp_integration.py` for validation
### Remote Server Debugging
- Server provides detailed request/response logging
- Test protocol directly with curl commands
- Use mcp-remote proxy with `--test` flag for validation
- Monitor fly.io logs: `fly logs -a erddap2mcp`
## Default Configuration
### Local Server
- Communication: stdio (standard input/output)
- Server name: `erddapy-mcp-server`
- Protocol default: `tabledap`
### Remote Server
- Communication: HTTP with JSON-RPC 2.0
- Server name: `erddap-mcp-server`
- Protocol default: `tabledap`
- Port: 8000
- Protocol version: `2025-06-18`
## Implementation Journey & Lessons Learned
This project represents months of debugging the Remote MCP mystery:
### Failed Approaches That Don't Work:
1. **Direct SSE connections** - Claude Desktop doesn't support this
2. **Config file remote URLs** - Only works for local stdio servers
3. **Connector UI direct connections** - Also unsupported
4. **OAuth discovery without proxy** - Overly complex and unnecessary
### The Working Solution:
- **Build HTTP MCP server** with proper JSON-RPC 2.0 protocol
- **Deploy with HTTPS** (fly.io provides automatic SSL)
- **Use mcp-remote proxy** to bridge stdio β HTTP
- **Configure via command/args** in claude_desktop_config.json
### Key Insight:
The `mcp-remote` proxy requirement was buried in third-party documentation and missing from official MCP docs. This caused WEEKS of debugging pain that is now documented to save others.
## Important Implementation Details
- Both servers use erddapy library for ERDDAP interactions
- Maintain ERDDAP instance cache for performance
- Handle both tabledap and griddap protocols
- Include proper error handling with timeouts
- Data previews include summary statistics
- Remote server optimized for cloud deployment constraints
## Testing and Validation
### Integration Testing
```bash
# Run the integration test script
python test_mcp_integration.py
```
This tests:
- Tool listing functionality
- Dataset search capabilities
- Metadata retrieval
- Data download URL generation
- Data preview functionality
### Manual Testing Commands
```bash
# Test local server directly
python erddapy_mcp_server.py
# Test remote server endpoints
curl http://localhost:8000/ # Should return server info
curl http://localhost:8000/health # Health check endpoint
```
## Dependencies
Core dependencies (from requirements.txt):
- `erddapy>=2.2.0` - ERDDAP Python client
- `mcp>=1.0.0` - MCP protocol library (local server)
- `pandas>=1.3.0` - Data manipulation
- `fastapi>=0.100.0` - Web framework (remote server)
- `uvicorn>=0.23.0` - ASGI server (remote server)
- `httpx>=0.24.0` - HTTP client
- `pydantic>=2.0.0` - Data validation