Skip to main content
Glama
lenwood

cfbd-mcp-server

by lenwood

get-advanced-box-score

Retrieve detailed statistical data for college football games from the College Football Data API using a specific game identifier.

Instructions

Note: When using this tool, please explicitly mention that you are retrieving data from the College Football Data API. You must mention "College Football Data API" in every response.

Get advanced box score data for college football games.
        Required: gameId
        Example valid queries:
        - gameId=401403910
        

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
gameIdYes

Implementation Reference

  • Registration of the get-advanced-box-score tool in the @server.list_tools() handler, specifying name, description, and inputSchema generated from getAdvancedBoxScore TypedDict.
    types.Tool(
        name="get-advanced-box-score",
        description=base_description + """Get advanced box score data for college football games.
        Required: gameId
        Example valid queries:
        - gameId=401403910
        """,
        inputSchema=create_tool_schema(getAdvancedBoxScore)
    )
  • Generic tool handler decorated with @server.call_tool(). Maps 'get-advanced-box-score' to getAdvancedBoxScore schema (line 518) for validation and to '/game/box/advanced' endpoint (line 542). Makes authenticated API GET request and returns JSON response as text.
    @server.call_tool()
    async def handle_call_tool(
        name: str,
        arguments: dict[str, Any] | None
    ) -> list[types.TextContent]:
        """Handle tool execution requests."""
        if not arguments:
            raise ValueError("Arguments are required")
    
        # Map tool names to their parameter schemas
        schema_map = {
            "get-games": getGames,
            "get-records": getTeamRecords,
            "get-games-teams": getGamesTeams,
            "get-plays": getPlays,
            "get-drives": getDrives,
            "get-play-stats": getPlayStats,
            "get-rankings": getRankings,
            "get-pregame-win-probability": getMetricsPregameWp,
            "get-advanced-box-score": getAdvancedBoxScore
        }
    
        if name not in schema_map:
            raise ValueError(f"Unknown tool: {name}")
    
        # Validate parameters against schema
        try:
            validated_params = validate_params(arguments, schema_map[name])
        except ValueError as e:
            return [types.TextContent(
                type="text",
                text=f"Validation error: {str(e)}"
            )]
    
        endpoint_map = {
            "get-games": "/games",
            "get-records": "/records",
            "get-games-teams": "/games/teams",
            "get-plays": "/plays",
            "get-drives": "/drives",
            "get-play-stats": "/play/stats",
            "get-rankings": "/rankings",
            "get-pregame-win-probability": "/metrics/wp/pregame",
            "get-advanced-box-score": "/game/box/advanced"
        }
       
        async with await get_api_client() as client:
            try:
                response = await client.get(endpoint_map[name], params=arguments)
                response.raise_for_status()
                data = response.json()
                return [types.TextContent(
                    type="text",
                    text=str(data)
                )]
            except httpx.HTTPStatusError as e:
                if e.response.status_code == 401:
                    return [types.TextContent(
                        type="text",
                        text="401: API authentication failed. Please check your API key."
                    )]
                elif e.response.status_code == 403:
                    return [types.TextContent(
                        type="text",
                        text="403: API access forbidden. Please check your permission."
                    )]
                elif e.response.status_code == 429:
                    return [types.TextContent(
                        type="text",
                        text="429: Rate limit exceeded. Please try again later."
                    )]
                else:
                    return [types.TextContent(
                        type="text",
                        text=f"API Error: {e}"
                    )]
            except httpx.RequestError as e:
                return [types.TextContent(
                    type="text",
                    text=f"Network error: {str(e)}"
                )]
  • TypedDict schemas for tool input parameters (getAdvancedBoxScore: requires gameId) and response (AdvancedBoxScoreResponse: contains teams and players stats). Supporting types like TeamStats, PlayerStats defined earlier in file.
    class getAdvancedBoxScore(TypedDict): # /game/box/advanced endpoint
        gameId: int
    
    class AdvancedBoxScoreResponse(TypedDict): # /game/box/advanced endpoint
        teams: TeamStats
        players: PlayerStats
  • validate_params helper function used by handler to validate tool arguments against the TypedDict schema (e.g., getAdvancedBoxScore). Handles optionals, required fields, type checks, and valid classifications.
    def validate_params(params: dict, schema_class: Type[TypedDict]) -> dict:
        """Validate parameters against a TypedDict schema."""
        try:
            # Get the annotations from the schema class
            expected_types = schema_class.__annotations__
            validated_params = {}
    
            # Validate each parameter
            for key, value in params.items():
                if key not in expected_types:
                    raise ValueError(f"Unexpected parameter: {key}")
    
                expected_type = expected_types[key]
    
                # Special handling for classification parameter
                if key == "classification" and value is not None:
                    value = value.lower()
                    if value not in VALID_DIVISIONS:
                        raise ValueError(f"Invalid Classification: Must be one of: {', '.join(VALID_DIVISIONS)}")
    
                # Handle Optional types
                if hasattr(expected_type, "__origin__") and expected_type.__origin__ is Union:
                    if type(None) in expected_type.__args__:
                        # Parameter is optional
                        if value is not None:
                            # Validate against the non-None type
                            non_none_type = next(t for t in expected_type.__args__ if t != type(None))
                            # Handle primitive types
                            if non_none_type in (str, int, float, bool):
                                if not isinstance(value, non_none_type):
                                    raise ValueError(f"Parameter {key} must be of type {non_none_type.__name__}")
                            validated_params[key] = value
                        else:
                            validated_params[key] = None
                else:
                    # Parameter is required
                    if not isinstance(value, expected_type):
                        raise ValueError(f"Parameter {key} must be of type {expected_type.__name__}")
                    validated_params[key] = value
    
            # Check for required parameters
            for param, param_type in expected_types.items():
                is_optional = (hasattr(param_type, "__origin__") and 
                             param_type.__origin__ is Union and 
                             type(None) in param_type.__args__)
                if not is_optional and param not in params:
                    raise ValueError(f"Missing required parameter: {param}")
    
            return validated_params
        
        except Exception as e:
            raise ValueError(f"Parameter validation failed: {str(e)}")
  • create_tool_schema helper converts TypedDict (e.g., getAdvancedBoxScore) to JSON Schema object used for tool's inputSchema in registration.
    def create_tool_schema(params_type: Type) -> dict:
        """Create a tool schema from a TypedDict."""
        return typed_dict_to_json_schema(params_type)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/lenwood/cfbd-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server