# Development Guide
This guide covers local development setup, testing, and debugging the GeoGuessr MCP Server.
## Table of Contents
- [Development Setup](#development-setup)
- [Running Locally](#running-locally)
- [Testing with MCP Inspector](#testing-with-mcp-inspector)
- [Testing with Claude Desktop](#testing-with-claude-desktop)
- [Running Tests](#running-tests)
- [Code Quality](#code-quality)
- [Debugging](#debugging)
- [Common Issues](#common-issues)
## Development Setup
### Prerequisites
- Python 3.11 or higher
- `uv` (recommended) or `pip`
- Git
- A GeoGuessr account (for authenticated endpoints)
### 1. Clone the Repository
```bash
git clone https://github.com/NyxiumYuuki/GeoGuessrMCP.git
cd GeoGuessrMCP
```
### 2. Create Virtual Environment
**Using uv (recommended):**
```bash
uv venv
source .venv/bin/activate # On Linux/macOS
# OR
.venv\Scripts\activate # On Windows
```
**Using venv:**
```bash
python -m venv .venv
source .venv/bin/activate # On Linux/macOS
# OR
.venv\Scripts\activate # On Windows
```
### 3. Install Dependencies
**Development dependencies (includes testing tools):**
```bash
uv pip install -e ".[dev]"
# OR
pip install -e ".[dev]"
```
**Production dependencies only:**
```bash
uv pip install -e .
# OR
pip install -e .
```
### 4. Configure Environment Variables
```bash
cp .env.example .env
```
Edit `.env` and configure:
**Required for authenticated endpoints:**
```bash
GEOGUESSR_NCFA_COOKIE=your_cookie_here
```
**Optional development settings:**
```bash
# Disable authentication for local testing
MCP_AUTH_ENABLED=false
# Enable debug logging
LOG_LEVEL=DEBUG
# Local schema cache
SCHEMA_CACHE_DIR=./data/schemas
# Server configuration
MCP_HOST=0.0.0.0
MCP_PORT=8000
MCP_TRANSPORT=streamable-http
```
## Running Locally
### Start the Server
```bash
python -m src.geoguessr_mcp.main
```
The server will start on `http://0.0.0.0:8000` by default.
**Expected output:**
```
INFO - Starting GeoGuessr MCP Server on 0.0.0.0:8000 with streamable-http transport
INFO - MCP server authentication is DISABLED - server is publicly accessible
INFO - Started server process [12345]
INFO - Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
```
### Enable Debug Logging
Set `LOG_LEVEL=DEBUG` in `.env` to see detailed request/response logs:
```bash
LOG_LEVEL=DEBUG
```
This enables:
- Request method and path logging
- Request headers logging
- Authentication flow details
- MCP protocol messages
- Schema detection changes
## Testing with MCP Inspector
**MCP Inspector** is a web-based tool for testing MCP servers interactively. It's the recommended way to develop and debug MCP servers.
### 1. Install MCP Inspector
Download from: [https://github.com/modelcontextprotocol/inspector](https://github.com/modelcontextprotocol/inspector)
Or run with npx:
```bash
npx @modelcontextprotocol/inspector
```
MCP Inspector will start on `http://localhost:6274` by default.
### 2. Configure Connection
#### Without Authentication
In MCP Inspector:
1. Select **"Server-Sent Events (SSE)"** or **"Streamable HTTP"** transport
2. Set URL: `http://localhost:8000/mcp`
3. Click **"Connect"**
#### With Authentication
In MCP Inspector:
1. Select **"Streamable HTTP"** transport
2. Set URL: `http://localhost:8000/mcp`
3. Click **"Custom Headers"**
4. Add header:
- **Name:** `Authorization`
- **Value:** `Bearer YOUR_API_KEY`
5. Click **"Connect"**
**Generate API key:**
```bash
openssl rand -hex 32
```
Add to `.env`:
```bash
MCP_AUTH_ENABLED=true
MCP_API_KEYS=your-generated-key-here
```
### 3. Test the Connection
After connecting, you should see:
- ✅ **Connection Status:** Connected
- ✅ **Protocol Version:** 2025-06-18
- ✅ **Server Info:** GeoGuessr MCP v1.22.0
### 4. Explore Available Tools
In the **"Tools"** tab, you should see:
**Authentication Tools:**
- `login(email, password)` - Login with GeoGuessr credentials
- `logout()` - Logout current session
- `set_ncfa_cookie(cookie)` - Set authentication cookie manually
- `get_current_session_token()` - Get current session status
**Profile Tools:**
- `get_profile(username)` - Get user profile
- `get_current_user_profile()` - Get your profile
- `get_user_stats(user_id)` - Get detailed stats
**Game Tools:**
- `get_game(game_id)` - Get game details
- `get_recent_games(count)` - Get recent games
- `get_activity_feed(count)` - Get activity feed
**Analysis Tools:**
- `get_performance_summary()` - Comprehensive performance overview
- `analyze_recent_games(count)` - Analyze recent gameplay
- `get_strategy_recommendations()` - Get improvement tips
**Monitoring Tools:**
- `check_api_status()` - Check API endpoint availability
- `list_available_endpoints()` - List all monitored endpoints
- `get_endpoint_schema(path)` - Get schema for specific endpoint
- `explore_endpoint(path)` - Manually explore new endpoints
### 5. Test a Tool
Try calling a simple tool:
1. Select `get_current_session_token()` from the tools list
2. Click **"Call Tool"**
3. Check the response
**Expected response (not authenticated):**
```json
{
"has_token": false,
"message": "No authentication cookie set. Use login() or set_ncfa_cookie()."
}
```
**Expected response (authenticated):**
```json
{
"has_token": true,
"user_id": "your-user-id",
"username": "your-username"
}
```
### 6. Debugging Connection Issues
If you see errors in MCP Inspector, check the server logs:
**Common issues:**
**❌ OPTIONS 405 Method Not Allowed**
- **Cause:** CORS middleware not configured
- **Fix:** Ensure middleware is properly applied (should be fixed in latest version)
**❌ POST 401 Unauthorized**
- **Cause:** Missing or invalid API key
- **Fix:** Add correct `Authorization: Bearer YOUR_KEY` header
**❌ POST 400 Bad Request**
- **Cause:** Session ID not maintained (CORS headers not exposed)
- **Fix:** Ensure `expose_headers` includes `mcp-session-id` (should be fixed in latest version)
**❌ Connection timeout**
- **Cause:** Server not running or firewall blocking
- **Fix:** Check server is running on `localhost:8000`
## Testing with Claude Desktop
For testing the full MCP integration with Claude Desktop:
### 1. Configure Claude Desktop
**macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
**Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
**Without authentication:**
```json
{
"mcpServers": {
"geoguessr-local": {
"type": "streamable-http",
"url": "http://localhost:8000/mcp"
}
}
}
```
**With authentication:**
```json
{
"mcpServers": {
"geoguessr-local": {
"type": "streamable-http",
"url": "http://localhost:8000/mcp",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
```
### 2. Restart Claude Desktop
After modifying the config, completely quit and restart Claude Desktop.
### 3. Test in Claude
In a new conversation:
```
Can you check my GeoGuessr profile?
```
Claude should automatically use the MCP server tools to fetch your profile.
## Running Tests
### Unit Tests
```bash
pytest src/tests/unit/ -v
```
### Integration Tests
**Requires authentication:**
```bash
# Set GEOGUESSR_NCFA_COOKIE in .env first
pytest src/tests/integration/ -v
```
### All Tests with Coverage
```bash
pytest --cov=src/geoguessr_mcp src/tests/ -v
```
### Coverage Report
```bash
pytest --cov=src/geoguessr_mcp --cov-report=html src/tests/
open htmlcov/index.html # View coverage report
```
## Code Quality
### Format Code with Black
```bash
black src/ tests/
```
**Configuration:** Line length 100 (see `pyproject.toml`)
### Lint with Ruff
```bash
ruff check src/ tests/
```
**Auto-fix:**
```bash
ruff check --fix src/ tests/
```
### Type Check with MyPy
```bash
mypy src/
```
### Pre-commit Hooks
Install pre-commit hooks to automatically run checks:
```bash
pre-commit install
```
This will run Black, Ruff, and MyPy before each commit.
## Debugging
### Enable Debug Mode
Set in `.env`:
```bash
LOG_LEVEL=DEBUG
```
Restart the server to see:
- All HTTP requests with headers
- Authentication flow
- MCP protocol messages
- Schema detection and changes
### Debug Authentication
Check if your GeoGuessr cookie is valid:
```bash
# In Python console
from src.geoguessr_mcp.auth import session_manager
import asyncio
async def test():
token = session_manager.get_current_session_token()
print(f"Token: {token}")
asyncio.run(test())
```
### Debug API Calls
Test API endpoints directly:
```bash
# Install httpx
pip install httpx
# Test endpoint
python -c "
import httpx
import asyncio
async def test():
async with httpx.AsyncClient() as client:
response = await client.get(
'https://www.geoguessr.com/api/v3/profiles',
cookies={'_ncfa': 'YOUR_COOKIE'}
)
print(response.json())
asyncio.run(test())
"
```
### Debug Schema Detection
Check schema cache:
```bash
ls -la data/schemas/
cat data/schemas/schemas.json | python -m json.tool
```
Force schema refresh:
```bash
rm -rf data/schemas/*
# Restart server - schemas will be regenerated
```
### View Server Logs
**Real-time logs:**
```bash
tail -f server.log # If using file logging
```
**Docker logs:**
```bash
docker compose logs -f geoguessr-mcp
```
## Common Issues
### Issue: Module not found errors
**Solution:**
```bash
# Ensure you're in the project root
pip install -e ".[dev]"
```
### Issue: Permission denied on schema cache
**Solution:**
```bash
mkdir -p data/schemas
chmod 755 data/schemas
```
Or use a different path in `.env`:
```bash
SCHEMA_CACHE_DIR=/tmp/geoguessr-schemas
```
### Issue: Port 8000 already in use
**Solution:**
```bash
# Use different port
echo "MCP_PORT=8001" >> .env
```
Or kill the process using port 8000:
```bash
# Linux/macOS
lsof -ti:8000 | xargs kill -9
# Windows
netstat -ano | findstr :8000
taskkill /PID <PID> /F
```
### Issue: CORS errors in browser
**Solution:**
Ensure CORS middleware is properly configured with `expose_headers`:
```python
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
expose_headers=["mcp-session-id", "mcp-protocol-version"],
)
```
### Issue: Session not maintained (400 errors)
**Symptoms:**
- First POST succeeds (200 OK)
- Second POST fails (400 Bad Request)
- Logs show new session created each time
**Solution:**
The `mcp-session-id` header must be exposed via CORS (fixed in latest version).
Check server logs for:
```
expose_headers=["mcp-session-id", "mcp-protocol-version"]
```
## Contributing
### Development Workflow
1. Create a feature branch
2. Make changes
3. Run tests: `pytest`
4. Run code quality checks: `black`, `ruff`, `mypy`
5. Commit with descriptive message
6. Push and create pull request
### Code Style
- **Formatting:** Black (line length 100)
- **Linting:** Ruff
- **Type hints:** Required for all functions
- **Docstrings:** Google style for public APIs
- **Tests:** Required for new features
### Project Structure
```
src/geoguessr_mcp/
├── api/ # GeoGuessr API client
├── auth/ # Authentication & session management
├── middleware/ # MCP server middleware (auth, CORS)
├── models/ # Data models (Profile, Stats, Games)
├── monitoring/ # API monitoring & schema detection
│ ├── endpoint/ # Endpoint monitoring
│ └── schema/ # Schema detection & registry
├── services/ # Business logic services
├── tools/ # MCP tool definitions
├── config.py # Configuration management
└── main.py # Application entry point
```
## Resources
- [MCP Documentation](https://modelcontextprotocol.io/)
- [FastMCP Guide](https://github.com/jlowin/fastmcp)
- [MCP Inspector](https://github.com/modelcontextprotocol/inspector)
- [GeoGuessr API (unofficial)](https://www.geoguessr.com/api)
- [Starlette Middleware](https://www.starlette.io/middleware/)
## Support
For issues and questions:
- Check this guide first
- Review server logs with `LOG_LEVEL=DEBUG`
- Check existing issues on GitHub
- Create a new issue with logs and reproduction steps