Fix test for multi user session, add middleware based on app type + modify docker compose for development
This commit is contained in:
parent
482daa73e0
commit
c04ba73c8a
3 changed files with 58 additions and 133 deletions
|
|
@ -1,12 +1,12 @@
|
||||||
services:
|
services:
|
||||||
geoguessr-mcp:
|
geoguessr-mcp:
|
||||||
# Option 1: Build locally (for development)
|
# Option 1: Build locally (for development)
|
||||||
# build:
|
build:
|
||||||
# context: .
|
context: .
|
||||||
# dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
|
|
||||||
# Option 2: Use pre-built image from Docker Hub (recommended)
|
# Option 2: Use pre-built image from Docker Hub (recommended)
|
||||||
image: nyxiumyuuki/geoguessr-mcp:latest
|
# image: nyxiumyuuki/geoguessr-mcp:latest
|
||||||
|
|
||||||
container_name: geoguessr-mcp-server
|
container_name: geoguessr-mcp-server
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
|
||||||
|
|
@ -7,15 +7,12 @@ with automatic API monitoring and dynamic schema adaptation.
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
from mcp.server.fastmcp import FastMCP
|
from mcp.server.fastmcp import FastMCP
|
||||||
from starlette.applications import Starlette
|
from starlette.middleware.cors import CORSMiddleware
|
||||||
from starlette.middleware import Middleware
|
|
||||||
|
|
||||||
from .config import settings
|
from .config import settings
|
||||||
from .middleware import AuthenticationMiddleware
|
from .middleware import AuthenticationMiddleware
|
||||||
from .monitoring import endpoint_monitor
|
|
||||||
from .tools import register_all_tools
|
from .tools import register_all_tools
|
||||||
|
|
||||||
# Configure logging
|
# Configure logging
|
||||||
|
|
@ -28,132 +25,60 @@ logging.basicConfig(
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
# Create the MCP server instance
|
|
||||||
mcp = FastMCP(
|
|
||||||
"GeoGuessr Analyzer",
|
|
||||||
instructions="""
|
|
||||||
MCP server for analyzing GeoGuessr game statistics and optimizing gameplay strategy.
|
|
||||||
|
|
||||||
This server provides:
|
|
||||||
- Profile and statistics retrieval
|
|
||||||
- Game history and analysis
|
|
||||||
- Performance tracking and recommendations
|
|
||||||
- API monitoring with automatic schema adaptation
|
|
||||||
|
|
||||||
The server automatically tracks API endpoint changes and adapts to response format
|
|
||||||
modifications. Use the monitoring tools to check API status and discover available data.
|
|
||||||
|
|
||||||
Authentication:
|
|
||||||
- Use 'login(email, password)' to authenticate with your GeoGuessr account
|
|
||||||
- Or use 'set_ncfa_cookie(cookie)' with a cookie from your browser
|
|
||||||
- Or set GEOGUESSR_NCFA_COOKIE environment variable for automatic auth
|
|
||||||
|
|
||||||
Key tools:
|
|
||||||
- get_performance_summary() - Comprehensive overview of your account
|
|
||||||
- analyze_recent_games(count) - Analyze your recent gameplay
|
|
||||||
- get_strategy_recommendations() - Get personalized improvement tips
|
|
||||||
- check_api_status() - Monitor API endpoint availability
|
|
||||||
- explore_endpoint(path) - Discover new API endpoints
|
|
||||||
""",
|
|
||||||
host=settings.HOST,
|
|
||||||
port=settings.PORT,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Register all tools
|
|
||||||
services = register_all_tools(mcp)
|
|
||||||
|
|
||||||
# Setup authentication middleware if enabled
|
|
||||||
if settings.MCP_AUTH_ENABLED:
|
|
||||||
logger.info("Setting up authentication middleware")
|
|
||||||
|
|
||||||
# Create a function to add middleware to the app
|
|
||||||
def add_middleware_to_app(app):
|
|
||||||
"""Add authentication middleware to a Starlette app."""
|
|
||||||
if app is not None:
|
|
||||||
try:
|
|
||||||
app.add_middleware(AuthenticationMiddleware)
|
|
||||||
logger.info("Authentication middleware successfully added")
|
|
||||||
return True
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"Failed to add middleware: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Try to add middleware immediately to any existing app
|
|
||||||
middleware_added = False
|
|
||||||
|
|
||||||
# Try different possible locations where FastMCP might store the app
|
|
||||||
for attr_path in [
|
|
||||||
"mcp._transport.app",
|
|
||||||
"mcp.sse.app",
|
|
||||||
"mcp.http_server.app",
|
|
||||||
"mcp._http_server.app",
|
|
||||||
"mcp._app",
|
|
||||||
"mcp._asgi_app",
|
|
||||||
]:
|
|
||||||
try:
|
|
||||||
parts = attr_path.split(".")
|
|
||||||
obj = mcp
|
|
||||||
for part in parts[1:]: # Skip 'mcp' itself
|
|
||||||
obj = getattr(obj, part, None)
|
|
||||||
if obj is None:
|
|
||||||
break
|
|
||||||
|
|
||||||
if obj is not None and add_middleware_to_app(obj):
|
|
||||||
middleware_added = True
|
|
||||||
break
|
|
||||||
except (AttributeError, TypeError):
|
|
||||||
continue
|
|
||||||
|
|
||||||
if not middleware_added:
|
|
||||||
# If we couldn't add it immediately, wrap the run method
|
|
||||||
logger.info("Deferring middleware addition until server starts")
|
|
||||||
|
|
||||||
_original_run = mcp.run
|
|
||||||
|
|
||||||
def run_with_middleware_wrapper(*args, **kwargs):
|
|
||||||
"""Wrapper to try adding middleware when run() is called."""
|
|
||||||
# Try again when run is called
|
|
||||||
for attr_path in [
|
|
||||||
"mcp._transport.app",
|
|
||||||
"mcp.sse.app",
|
|
||||||
"mcp.http_server.app",
|
|
||||||
"mcp._http_server.app",
|
|
||||||
"mcp._app",
|
|
||||||
"mcp._asgi_app",
|
|
||||||
]:
|
|
||||||
try:
|
|
||||||
parts = attr_path.split(".")
|
|
||||||
obj = mcp
|
|
||||||
for part in parts[1:]:
|
|
||||||
obj = getattr(obj, part, None)
|
|
||||||
if obj is None:
|
|
||||||
break
|
|
||||||
|
|
||||||
if obj is not None and add_middleware_to_app(obj):
|
|
||||||
break
|
|
||||||
except (AttributeError, TypeError):
|
|
||||||
continue
|
|
||||||
|
|
||||||
return _original_run(*args, **kwargs)
|
|
||||||
|
|
||||||
mcp.run = run_with_middleware_wrapper
|
|
||||||
|
|
||||||
|
|
||||||
async def start_background_tasks():
|
|
||||||
"""Start background monitoring tasks."""
|
|
||||||
if settings.MONITORING_ENABLED:
|
|
||||||
logger.info("Starting API monitoring background task...")
|
|
||||||
await endpoint_monitor.start_periodic_monitoring()
|
|
||||||
|
|
||||||
|
|
||||||
async def stop_background_tasks():
|
|
||||||
"""Stop background monitoring tasks."""
|
|
||||||
if endpoint_monitor._running:
|
|
||||||
await endpoint_monitor.stop_monitoring()
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""Main entry point for the server."""
|
"""Main entry point for the server."""
|
||||||
|
|
||||||
|
# Create the MCP server instance
|
||||||
|
mcp = FastMCP(
|
||||||
|
"GeoGuessr Analyzer",
|
||||||
|
instructions="""
|
||||||
|
MCP server for analyzing GeoGuessr game statistics and optimizing gameplay strategy.
|
||||||
|
|
||||||
|
This server provides:
|
||||||
|
- Profile and statistics retrieval
|
||||||
|
- Game history and analysis
|
||||||
|
- Performance tracking and recommendations
|
||||||
|
- API monitoring with automatic schema adaptation
|
||||||
|
|
||||||
|
The server automatically tracks API endpoint changes and adapts to response format
|
||||||
|
modifications. Use the monitoring tools to check API status and discover available data.
|
||||||
|
|
||||||
|
Authentication:
|
||||||
|
- Use 'login(email, password)' to authenticate with your GeoGuessr account
|
||||||
|
- Or use 'set_ncfa_cookie(cookie)' with a cookie from your browser
|
||||||
|
- Or set GEOGUESSR_NCFA_COOKIE environment variable for automatic auth
|
||||||
|
|
||||||
|
Key tools:
|
||||||
|
- get_performance_summary() - Comprehensive overview of your account
|
||||||
|
- analyze_recent_games(count) - Analyze your recent gameplay
|
||||||
|
- get_strategy_recommendations() - Get personalized improvement tips
|
||||||
|
- check_api_status() - Monitor API endpoint availability
|
||||||
|
- explore_endpoint(path) - Discover new API endpoints
|
||||||
|
""",
|
||||||
|
host=settings.HOST,
|
||||||
|
port=settings.PORT,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Register all tools
|
||||||
|
register_all_tools(mcp)
|
||||||
|
|
||||||
|
# Setup authentication middleware if enabled
|
||||||
|
if settings.MCP_AUTH_ENABLED:
|
||||||
|
logger.info("Setting up authentication middleware")
|
||||||
|
|
||||||
|
# Récupérez l'application ASGI via streamable_http_app
|
||||||
|
mcp_app = mcp.streamable_http_app()
|
||||||
|
|
||||||
|
# Ajoutez les middlewares
|
||||||
|
mcp_app.add_middleware(
|
||||||
|
CORSMiddleware,
|
||||||
|
allow_origins=["*"],
|
||||||
|
allow_credentials=True,
|
||||||
|
allow_methods=["*"],
|
||||||
|
allow_headers=["*"]
|
||||||
|
)
|
||||||
|
mcp_app.add_middleware(AuthenticationMiddleware)
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Starting GeoGuessr MCP Server on {settings.HOST}:{settings.PORT} "
|
f"Starting GeoGuessr MCP Server on {settings.HOST}:{settings.PORT} "
|
||||||
f"with {settings.TRANSPORT} transport"
|
f"with {settings.TRANSPORT} transport"
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ class TestMultiUserSessionManager:
|
||||||
assert session is None
|
assert session is None
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_login_user_creates_manager_if_not_exists(self, manager, mock_http_client):
|
async def test_login_user_creates_manager_if_not_exists(self, manager):
|
||||||
"""Test that login_user creates a manager if it doesn't exist."""
|
"""Test that login_user creates a manager if it doesn't exist."""
|
||||||
# This test requires mocking the HTTP client for GeoGuessr API
|
# This test requires mocking the HTTP client for GeoGuessr API
|
||||||
# We'll mark it as a placeholder for now
|
# We'll mark it as a placeholder for now
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue