Commit graph

57 commits

Author SHA1 Message Date
75afeaf305
Merge pull request #7 from NyxiumYuuki/claude/fix-middleware-schema-cache-01SXnBSQQ8ptLgqViF4UsUYx
Fix middleware schema caching error
2025-12-01 03:03:24 +01:00
Yûki VACHOT
6ad818ff51 Fix ruff and black 2025-12-01 03:01:54 +01:00
Yûki VACHOT
b0414cf6d0 Add TODO for a test_login_user_creates_manager_if_not_exists 2025-12-01 02:57:31 +01:00
Yûki VACHOT
3844ffc207 CORS Fixed + black and ruff fixes 2025-12-01 02:55:47 +01:00
Claude
5e2f6078a1
Add comprehensive development guide with MCP Inspector instructions
Created DEVELOPMENT.md with detailed instructions for:
- Local development setup
- Testing with MCP Inspector (with/without auth)
- Testing with Claude Desktop
- Running tests and code quality checks
- Debugging common issues
- Troubleshooting connection problems

Key sections:
- Complete MCP Inspector setup guide
- Authentication configuration
- Debug logging setup
- Common error fixes (CORS, auth, sessions)
- Project structure overview
2025-12-01 01:27:25 +00:00
Claude
dda0003226
Expose MCP headers in CORS for session continuity
The 400 Bad Request on second POST was caused by CORS not exposing
the mcp-session-id header, preventing MCP Inspector from reading it
and sending it back in subsequent requests.

Without the session ID, each request created a new transport session
instead of reusing the existing one, causing protocol errors.

Fix:
- Add expose_headers to CORS middleware configuration
- Expose mcp-session-id and mcp-protocol-version headers
- Allows browser clients to read and reuse session IDs
- Applied to both streamable-http and SSE transports

This fixes the session continuity issue and eliminates 400 errors.
2025-12-01 01:27:25 +00:00
Yûki VACHOT
15415080da Trying to fix CORS 2025-12-01 02:21:38 +01:00
Claude
dd9e178e72
Fix uvicorn to run for all types of transport
The previous approach of running uvicorn.run(mcp_app) directly bypassed
MCP's internal session management, causing 400 Bad Request errors when
MCP Inspector tried to reuse sessions.

Solution:
- Use mcp.run() with middleware parameter instead of uvicorn.run()
- Build middleware list using starlette.middleware.Middleware wrapper
- Pass middleware list to mcp.run(transport, middleware=middleware_list)
- This preserves MCP's session handling while applying our middleware

Benefits:
- Proper MCP session continuity for streamable-http transport
- CORS middleware still applies correctly
- Authentication middleware works as expected
- Debug logging middleware available when LOG_LEVEL=DEBUG

This fixes the 400 Bad Request error on the second POST request.
2025-11-30 01:33:39 +00:00
Claude
e4a8748af5
Add debug logging middleware for troubleshooting
Added RequestLoggingMiddleware to help diagnose 400 Bad Request errors:
- Logs all request methods and paths in DEBUG mode
- Logs request headers for debugging
- Warns on any 4xx/5xx responses with details
- Only enabled when LOG_LEVEL=DEBUG to avoid spam

This helps troubleshoot MCP protocol issues without modifying
the core request handling logic.
2025-11-30 01:25:19 +00:00
Claude
fe71704bf8
Fix authentication middleware to allow OPTIONS requests
CORS preflight requests (OPTIONS) don't include Authorization headers
by browser design. The middleware was blocking these requests with 401.

Solution:
- Skip authentication check for OPTIONS requests
- OPTIONS requests are handled by CORS middleware only
- Actual requests (GET, POST) still require authentication

This fixes the "401 Unauthorized" error on OPTIONS /mcp when using
MCP Inspector or other browser-based clients with authentication enabled.
2025-11-30 01:13:26 +00:00
Yûki VACHOT
d0945d99a3 Fix uvicorn to run for all types of transport 2025-11-30 02:10:51 +01:00
Claude
ef177147c4
Fix CORS middleware by running uvicorn directly
The previous fix added CORS middleware to the app, but mcp.run()
creates a new app instance that doesn't include our middleware.

Solution:
- Import uvicorn
- For streamable-http transport, run uvicorn directly with the
  middleware-enhanced app (mcp_app)
- This ensures CORS middleware is actually applied
- For other transports (SSE), fall back to mcp.run() with a warning

This fixes the "OPTIONS /mcp HTTP/1.1 405 Method Not Allowed" error
by ensuring CORS middleware handles preflight requests properly.
2025-11-30 00:58:12 +00:00
Yûki VACHOT
d35e12b6ae add sse transport type 2025-11-30 01:54:46 +01:00
Claude
7c162691db
Fix middleware and schema cache issues
This commit addresses two critical issues in the MCP server:

1. CORS Middleware Fix:
   - Move CORS middleware outside the auth check so it's always enabled
   - CORS is required for browser-based MCP clients, regardless of auth
   - Fixes "OPTIONS /mcp HTTP/1.1 405 Method Not Allowed" error

2. Schema Cache Improvements:
   - Add specific handling for corrupted JSON cache files
   - Automatically remove corrupted cache files and log the action
   - Prevents startup failures due to malformed JSON
   - Better error messages to help diagnose cache issues

3. Configuration Updates:
   - Change default SCHEMA_CACHE_DIR from /app/data/schemas to ./data/schemas
   - Better default for local development (Docker still uses /app/data/schemas)
   - Update .env.example with clearer documentation

These fixes improve robustness and make local development easier.
2025-11-30 00:09:55 +00:00
de023b66c7
Merge pull request #6 from NyxiumYuuki/claude/add-mcp-authentication-01V5tbppGEtXc3tvjRGoTcfh
Fix CI/CD issues and add comprehensive tests for multi-user features
2025-11-30 01:01:37 +01:00
Yûki VACHOT
dc40ab87ec Reformat with black for one file 2025-11-30 00:57:27 +01:00
Yûki VACHOT
c04ba73c8a Fix test for multi user session, add middleware based on app type + modify docker compose for development 2025-11-30 00:56:28 +01:00
Claude
482daa73e0
Fix CI/CD issues and add comprehensive tests for multi-user features
This commit fixes three critical issues identified in CI/CD and adds
comprehensive test coverage for the new multi-user functionality.

## Fixes

### 1. FastMCP Middleware Registration Error

**Problem**: `AttributeError: 'FastMCP' object has no attribute 'app'`

**Solution**: Implemented robust middleware registration that:
- Tries multiple possible locations where FastMCP might store the app
- Gracefully handles cases where app isn't immediately available
- Wraps the run() method to defer middleware addition if needed
- Attempts: _transport.app, sse.app, http_server.app, _app, _asgi_app
- Falls back gracefully with warning if middleware can't be added

**Files Changed**:
- src/geoguessr_mcp/main.py: Added smart middleware registration logic

### 2. Test Permission Errors

**Problem**: `PermissionError: [Errno 13] Permission denied: '/app'`
Schema registry tried to create /app/data/schemas in CI without permission

**Solution**: Made schema cache directory creation fault-tolerant:
- Catches PermissionError and OSError when creating cache directory
- Falls back to temporary directory (tempfile.mkdtemp) if permission denied
- Logs clear warning messages about fallback behavior
- Tests can now run in restricted environments

**Files Changed**:
- src/geoguessr_mcp/monitoring/schema/schema_registry.py: Added fallback logic

### 3. Black Formatting Issues

**Problem**: 10 files needed reformatting

**Solution**: Ran `black src/ --line-length 100` on all source files

**Files Formatted**:
- src/geoguessr_mcp/config.py
- src/geoguessr_mcp/api/dynamic_response.py
- src/geoguessr_mcp/middleware/auth.py
- src/geoguessr_mcp/main.py
- src/geoguessr_mcp/auth/multi_user_session.py
- src/geoguessr_mcp/tools/auth_tools.py
- src/tests/integration/test_auth_flow.py
- src/tests/unit/services/*.py (3 files)

## New Tests

Added comprehensive test coverage for multi-user features:

### test_user_context.py
- Tests UserContext creation with/without sessions
- Tests authentication status checking
- Tests session expiration handling
- Tests string representation
- Tests API key hashing for anonymous users
- Tests consistency of anonymous user IDs

### test_multi_user_session.py
- Tests MultiUserSessionManager initialization
- Tests session manager creation per API key
- Tests session manager reuse for same API key
- Tests isolation between different users
- Tests auth status reporting
- Tests context creation and retrieval

### test_request_context.py
- Tests context variable get/set operations
- Tests require_user_context() error handling
- Tests context isolation between requests
- Tests context updates and clearing
- Tests None handling

## Code Quality

All changes pass:
-  Python syntax checks (py_compile)
-  Black formatting (line-length 100)
-  Test structure validation
-  Import resolution

## CI/CD Impact

These fixes should resolve:
-  Test execution failures (permission errors)
-  Black formatting check failures
-  Runtime errors when starting server with auth enabled

Tests can now run in CI environment without requiring:
- Root permissions
- /app directory access
- Pre-created cache directories
2025-11-29 23:11:32 +00:00
12a05b85f8
Merge pull request #5 from NyxiumYuuki/claude/add-mcp-authentication-01V5tbppGEtXc3tvjRGoTcfh
Add multi-user support - each API key gets own GeoGuessr session
2025-11-29 23:43:07 +01:00
Claude
80ed791b01
Add multi-user support - each API key gets own GeoGuessr session
Implements comprehensive multi-user support allowing multiple users to
access the same MCP server instance with their own independent GeoGuessr
accounts. Each API key now has its own session storage and context.

## Multi-User Architecture

### New Components

**User Context System** (src/geoguessr_mcp/auth/user_context.py):
- UserContext dataclass tracks API key and associated GeoGuessr session
- Properties for user_id, username, ncfa_cookie, is_authenticated
- Automatically attached to each request

**Multi-User Session Manager** (src/geoguessr_mcp/auth/multi_user_session.py):
- MultiUserSessionManager manages separate SessionManager per API key
- Maps API keys to their own GeoGuessr sessions
- Methods: get_user_context, login_user, logout_user, set_user_cookie
- Global instance: multi_user_session_manager

**Request Context** (src/geoguessr_mcp/auth/request_context.py):
- ContextVar for accessing current user context in tools
- Functions: get_current_user_context, require_user_context, set_current_user_context
- Enables tools to access user-specific sessions automatically

### Updated Components

**Authentication Middleware** (src/geoguessr_mcp/middleware/auth.py):
- Now creates user context for each authenticated request
- Attaches context to both request.state and ContextVar
- Supports both authenticated and unauthenticated modes
- Default user context created when auth is disabled

**Authentication Tools** (src/geoguessr_mcp/tools/auth_tools.py):
- Completely rewritten for multi-user support
- login(): Creates session tied to caller's API key
- logout(): Logs out only the calling user's session
- set_ncfa_cookie(): Sets cookie for calling user only
- get_auth_status(): Returns calling user's auth status
- All tools use get_current_user_context() automatically

**GeoGuessr Client** (src/geoguessr_mcp/api/geoguessr_client.py):
- _get_authenticated_client() checks user context first
- Falls back to session_manager for backward compatibility
- Automatically uses caller's session when available
- No changes needed in services (profile, game, analysis)

## How It Works

1. User connects with API key in Authorization header
2. Middleware validates API key and creates/retrieves UserContext
3. UserContext attached to request.state and ContextVar
4. Tools call get_current_user_context() to access caller's session
5. Client automatically uses correct session for API calls
6. Each user's session is completely isolated

## Usage Example

```bash
# Configure multiple API keys
MCP_AUTH_ENABLED=true
MCP_API_KEYS=alice_key,bob_key,charlie_key

# Alice connects with: Authorization: Bearer alice_key
# Bob connects with: Authorization: Bearer bob_key
# Each can login to their own GeoGuessr account
# Sessions are completely independent
```

## Key Features

- **Zero Interference**: Users don't affect each other's sessions
- **Automatic Routing**: Requests automatically use correct user's session
- **Hot Reload**: Add new API keys and restart in ~2-3 seconds
- **Backward Compatible**: Still works with single-user mode
- **Fallback Support**: GEOGUESSR_NCFA_COOKIE still works as default

## Documentation Updates

- README.md: Added Multi-User Mode section with examples
- README.md: Updated authentication section with multi-user details
- README.md: Added "Adding New Users" workflow
- Key Features section now highlights multi-user support

## Technical Details

- Uses Python ContextVar for request-scoped user context
- Each API key gets its own SessionManager instance
- Session storage is in-memory (persists across requests, not restarts)
- Default cookie (GEOGUESSR_NCFA_COOKIE) used as fallback for all users
- Fully async/await compatible throughout
2025-11-29 22:30:55 +00:00
1f8f8e6ac4
Merge pull request #4 from NyxiumYuuki/claude/add-mcp-authentication-01V5tbppGEtXc3tvjRGoTcfh
Add authentication and update MCP server setup
2025-11-29 23:24:50 +01:00
Claude
07b1cb84b2
Add MCP server authentication and update Docker configuration
This commit implements several key improvements to the GeoGuessr MCP server:

## MCP Server Authentication
- Add Bearer token authentication for MCP server access control
- New middleware in src/geoguessr_mcp/middleware/auth.py
- Configuration via MCP_AUTH_ENABLED and MCP_API_KEYS environment variables
- Support for multiple API keys (comma-separated)
- Optional authentication - can be disabled for trusted deployments
- Clients connect using Authorization: Bearer YOUR_API_KEY header

## Docker Configuration Updates
- Update to use official pre-built image: nyxiumyuuki/geoguessr-mcp:latest
- Remove DOCKER_USERNAME and IMAGE_TAG from environment variables
- Simplify docker-compose.yml and docker-compose.prod.yml
- Remove healthcheck configuration (not necessary for the deployment)

## Deployment Improvements
- Move deploy.sh to scripts/deploy.sh for better organization
- Update deploy.sh to use official Docker image
- Add authentication validation in deployment script
- Improve deployment logging and error messages

## Documentation Updates
- Update README.md with authentication configuration examples
- Add MCP server authentication section with setup instructions
- Update environment variables table
- Simplify deployment instructions
- Update CLAUDE.md with new authentication architecture
- Add .env.example configuration for MCP authentication

## Technical Details
- Authentication middleware integrates with FastMCP's Starlette ASGI app
- Middleware validates Bearer tokens on all requests except /health
- Logs authentication attempts and failures
- Returns proper 401/403 HTTP status codes
- Validates configuration on startup to prevent misconfiguration

Resolves TODO items:
- [x] Fix Docker username in compose files and env vars
- [x] Add authentication to MCP server to allow access only to specific users
2025-11-29 22:16:01 +00:00
Yûki VACHOT
52d2f864a8 Add new environment for Bruno and fix README + list of todos. 2025-11-29 23:05:00 +01:00
1621a7f4cc
Merge pull request #3 from NyxiumYuuki/claude/deploy-docker-vps-ssl-014DR2HgeH6wax4BjuPfv8i7
Deploy Docker app to VPS with SSL
2025-11-29 08:31:44 +01:00
Claude
593c668d96
Add VPS production deployment with nginx-proxy-manager support
This commit adds comprehensive support for deploying the GeoGuessr MCP Server
to a VPS alongside existing nginx-proxy-manager setup (e.g., Firefly III).

Changes:
- Updated docker-compose.prod.yml to use existing firefly_network
- Removed standalone nginx service (uses nginx-proxy-manager instead)
- Changed from ports to expose for internal-only access
- Switched default to pre-built Docker Hub images

New files:
- DEPLOYMENT.md: Comprehensive deployment guide with SSL setup
- .env.production: Production-ready environment configuration template
- deploy.sh: Automated deployment script with health checks

Updated files:
- README.md: Added quick reference to VPS deployment with nginx-proxy-manager
- docker-compose.prod.yml: Simplified for proxy manager integration

Deployment features:
- Automatic SSL certificate management via nginx-proxy-manager
- Let's Encrypt integration for HTTPS
- Shared Docker network with existing services
- Persistent schema storage
- Health checks and logging
- Easy updates via deploy script

This setup allows users to deploy the MCP server on the same VPS as other
Docker services while using a single nginx-proxy-manager for SSL/HTTPS.
2025-11-29 07:29:54 +00:00
Yûki VACHOT
92a7298e09 Fix Docker 2025-11-29 07:59:56 +01:00
Yûki VACHOT
0666c07431 Fix Docker 2025-11-29 07:18:31 +01:00
22d70a3bc0
Merge pull request #2 from NyxiumYuuki/claude/add-license-protection-01VCHnCLUEvqQJjEynZR5LFs
Add license and protect repository
2025-11-29 06:30:31 +01:00
Yûki VACHOT
0482fff8c5 Fix format with black 2025-11-29 06:29:35 +01:00
Yûki VACHOT
265e9d25d3 Fix code quality jobs 2025-11-29 06:26:35 +01:00
Yûki VACHOT
d1f0ea2a70 Fix main import and rework files for Bruno collection 2025-11-29 06:24:02 +01:00
Claude
16f3810210
feat: Add comprehensive license and repository protection
- Add MIT LICENSE file with proper copyright attribution
- Add SECURITY.md with vulnerability reporting guidelines
- Add CONTRIBUTING.md with contribution guidelines and standards
- Add CODE_OF_CONDUCT.md following Contributor Covenant 2.1
- Add .github/CODEOWNERS for code ownership protection
- Add GitHub issue templates (bug report, feature request)
- Add pull request template for standardized PRs
- Add automated workflows for code quality and security checks
- Add dependency review workflow for license compliance

This establishes professional standards and protections for the repository.
2025-11-29 05:08:27 +00:00
3855223bab
Merge pull request #1 from NyxiumYuuki/claude/docker-setup-monitoring-01XxBdb5R99jUqtqbAp6p61j
Set up Docker and 24-hour monitoring
2025-11-29 06:00:51 +01:00
Claude
9c5ac820b6
Add Docker deployment support with registry integration
- Update Dockerfile to use pyproject.toml instead of requirements.txt
- Add support for Docker Hub image pulling in compose files
- Add comprehensive deployment documentation with multiple methods
- Create CLAUDE.md with development and architecture guide
- Add .dockerignore for optimized build context
- Update .env.example with Docker configuration variables
- Configure 24-hour monitoring interval by default

Changes:
- Dockerfile: Install from pyproject.toml, use main.py entry point
- docker-compose.yml: Add image option for registry deployment
- docker-compose.prod.yml: Add image option for VPS deployment
- README.md: Add Docker Hub push/pull workflows and examples
- CLAUDE.md: Comprehensive guide for AI assistants and developers
- .dockerignore: Exclude unnecessary files from Docker builds
- .env.example: Add DOCKER_USERNAME and IMAGE_TAG variables
2025-11-29 04:53:07 +00:00
Yûki VACHOT
0236ef23d8 Fix integration tests via mockup 2025-11-29 04:54:37 +01:00
Yûki VACHOT
deeb2af493 Add Geoguessr API Collection updates with v3 and v4 endpoints, including new tools and deprecated endpoints reorganization. 2025-11-29 03:46:18 +01:00
Yûki VACHOT
ca30297033 Add Geoguessr API Collection with v3 and v4 folders, environment setup, and getProfiles endpoint configuration. 2025-11-29 02:52:37 +01:00
Yûki VACHOT
283d7deee4 Add production Docker Compose setup with Nginx and SSL; enhance test fixtures and environment variables for monitoring, logging, and schema caching; and clean up unused imports. 2025-11-29 02:41:39 +01:00
Yûki VACHOT
bf5d1b890a Refactor imports and standardize file naming: update module imports for consistency, align filenames with snake_case convention, and extract DynamicResponse to a dedicated module. 2025-11-29 02:27:58 +01:00
Yûki VACHOT
126d04ab0f Add tools for MCP module: register comprehensive toolsets (auth, profile, game, analysis, monitoring) with enhanced functionality and asynchronous operations. Integrate session handling, API schema analysis, and performance insights. 2025-11-29 02:27:46 +01:00
Yûki VACHOT
1b7963c239 Add and enhance unit tests: include tests for ProfileService, GameService, and AnalysisService; integrate comprehensive mock data and fixtures. Refactor imports and naming conventions in tests for consistency. Augment .env.example with monitoring and logging configurations. 2025-11-29 02:27:15 +01:00
Yûki VACHOT
8cc53378b7 Enable commit message inspection in IDE by configuring subject line character limit warning. 2025-11-29 01:25:34 +01:00
Yûki VACHOT
1a451f6390 Add Geoguessr API collection with getProfiles endpoint to tools module. 2025-11-29 01:25:03 +01:00
Yûki VACHOT
328e597f48 Refactor tools module: removed unused tools, commented out legacy registrations, updated mock data in tests, consolidated imports, and standardized naming conventions in the codebase. 2025-11-29 01:24:58 +01:00
Yûki VACHOT
ec0fe38861 Code cleanup: standardized imports, refined formatting for consistency, and resolved minor redundancies in services, models, monitoring, and tools modules. 2025-11-29 00:49:36 +01:00
Yûki VACHOT
e486d78e31 Standardize "GeoGuessr" naming in docstrings for consistency and correctness. 2025-11-29 00:47:58 +01:00
Yûki VACHOT
f9011dbeaa Add comprehensive unit tests: reorganized test files, removed outdated e2e and unit tests for auth and profile_service, introduced tests for SchemaRegistry, UserProfile, UserStats, Game, Achievement, and SeasonStats. 2025-11-29 00:47:42 +01:00
Yûki VACHOT
f6226f51e4 Remove DEVELOPMENT.md; update .gitignore to include additional ignored files; streamline and condense README.md. 2025-11-29 00:47:33 +01:00
Yûki VACHOT
1976a67a2a Refactor auth module: modularized UserSession and SessionManager, integrated settings for configurable defaults, updated GeoGuessr API domain usage, and added cookie validation functionality. 2025-11-29 00:38:16 +01:00
Yûki VACHOT
80631f6f44 Refactor monitoring module: modularized EndpointMonitor and SchemaRegistry into separate submodules under endpoint and schema respectively. Centralized endpoint definitions, improved structure, and updated imports accordingly. 2025-11-29 00:37:27 +01:00