handigraphs-stats-api-mcp
OfficialThe Handigraphs Stats API MCP server is a read-only server for querying sports statistics. You can use its three tools to:
List resources: Discover available sports and their stats resources (optionally filtered by sport name).
Describe a resource: Get detailed metadata for a specific sport/resource, including available metrics, canonical units, splits, and supported filters.
Query stats: Retrieve protected sports statistics with powerful filtering and customization — specify a split, select up to 100 metrics, apply up to 5 numeric filters (
eq,ne,gt,gte,lt,lteusing canonical units), sort, filter by team/opponent/entity/day/category/duration/location, paginate withcursor(up to 250 per page), and choose output format (compact,standard, orrichstats;compactorfullmetadata).
API keys are handled securely via environment variables or platform keychains — never as tool arguments — and the server manages auth, redaction, redirect rejection, and bounded responses. Run it locally as a Codex/Claude plugin, Claude Desktop extension, or any stdio MCP client (e.g., npx @handigraphs/stats-api-mcp).
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@handigraphs-stats-api-mcplist NFL passing stats for last season"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Handigraphs Stats API MCP
Public MCP server for read-only access to the Handigraphs Stats API v1. Version 0.2.6 uses stdio only. The normal authenticated server exposes three stats tools:
list_resources({ sport? })discovers sports and resources.describe_resource({ sport, resource })discovers metrics, canonical units, splits, and supported filters.query_stats(...)validates against live discovery and queries one protected data resource. Continue pagination by passing the returned cursor back to this tool.
Sports, resources, metrics, and splits are never compiled into this package. Public discovery remains authoritative.
Credentials
Create a reveal-once Stats API key at www.handigraphs.com/account/api. During rollout testing, keys beginning with hg_test_ automatically use the sandbox API; production keys beginning with hg_live_ use production. Never paste a real key into a repository, issue, prompt, or committed client configuration.
Related MCP server: NHL MCP Server
Install with the Handigraphs plugin
Codex
Install Node.js 22 or newer.
Install the latest Codex CLI and confirm the version before adding the plugin:
npm install --global @openai/codex@latest
codex --versionOpen Terminal and run these commands in order:
codex plugin marketplace add Handigraphs/handigraphs-stats-api-mcp
codex plugin add handigraphs-stats-api@handigraphsIn Codex, select the plugin starter Connect my Handigraphs account. On Windows, approve the local helper launch when prompted.
Codex opens the plugin's secure local setup window. Use its link to create a named Stats API key, paste the reveal-once key into the masked field, and select Save. Never paste the key into the Codex conversation.
Fully quit and reopen Codex, then start a new task. The plugin will load the saved key automatically.
When no key is configured, the plugin intentionally starts in setup-only mode. Its setup skill launches the bundled password-masked helper through Codex's approved local-shell path on Windows and uses the argument-free configure_api_key MCP tool on macOS; Codex never receives the key. Windows stores it as a user environment variable, while macOS stores it in the user's login Keychain. See the Codex setup guide for updating, key rotation, troubleshooting, and the Linux fallback.
Claude Code
Install Node.js 22 or newer.
Create a named Stats API key and copy it when it is revealed.
Open Terminal and run these commands in order:
claude plugin marketplace add Handigraphs/handigraphs-stats-api-mcp
claude plugin install handigraphs-stats-api@handigraphsInside Claude Code, run
/plugin configure handigraphs-stats-api@handigraphs, paste the key into the sensitive setting, and save it.Run
/reload-pluginsor start a new Claude Code session.
Claude Desktop extension
Create a named Stats API key and copy it when it is revealed.
Download
handigraphs-stats-api-mcp-<version>.mcpbfrom the matching GitHub release.Double-click the downloaded file to open it in Claude Desktop. If it does not open, drag the file onto the Claude Desktop window.
Review the extension, select Install, and enter the Stats API key when prompted.
Start a new conversation. Select + in the message box, then Connectors, and confirm Handigraphs Stats API appears.
The bundle includes the compiled server and its production dependencies; a separate Node.js installation is not required by the extension.
These are local distributions. They do not create a hosted connector for Claude.ai, Claude Cowork, mobile clients, or ChatGPT web.
Configure another MCP client
Node.js 22 or newer is required. Add the published npm package to any client that supports local stdio MCP servers:
{
"mcpServers": {
"handigraphs-stats": {
"command": "npx",
"args": ["-y", "@handigraphs/stats-api-mcp"],
"env": { "HANDIGRAPHS_API_KEY": "hg_live_REPLACE_ME" }
}
}
}Restart the MCP client after saving its configuration. Do not commit the configuration when it contains a real key.
An hg_test_ key selects https://handigraphs-sandbox-web-49829810d1bb.herokuapp.com/api/v1 automatically. HANDIGRAPHS_API_BASE_URL remains available as an explicit override for local development or another approved environment.
Configuration
Environment variables:
Variable | Required | Default | Purpose |
| Yes, except for Codex on macOS | macOS Keychain fallback in Codex | Bearer key for protected data. It is never accepted as a tool argument. |
| No | Inferred from key prefix | API v1 root. |
| No |
| In-process public-discovery cache TTL. |
| No |
| Upstream request timeout. |
| No |
| Maximum declared or streamed upstream JSON response size. |
The Codex plugin never accepts the key as a skill or MCP tool argument. Its platform-specific setup workflow launches a separate local masked process without putting the key on a process command line. Windows uses a user-approved local helper launch and saves the key and matching API environment to the current user's environment configuration. macOS uses the argument-free configure_api_key tool, sends the key to the system security utility over a private stdin pipe, stores it in the user's login Keychain, and infers the API environment from the key prefix when the MCP process reads it.
Query model
query_stats accepts sport, resource, and these optional fields: split, metrics, up to five numeric filters, sort, team, opponent, entity_id, day, page_size, cursor, stat_format, meta, category, duration, and location. Resource discovery determines which optional fields are supported. stat_format and meta default to compact.
Filter objects use { "metric": "k_pct", "operator": "gte", "value": 0.20 }. Operators are eq, ne, gt, gte, lt, and lte. Values must be finite and use the canonical unit returned by discovery; proportions use 0.20 for 20%.
Successful tools return the upstream JSON in structuredContent.response, a minified JSON text block, and safe request/quota headers in structuredContent.metadata. Upstream problem responses become isError tool results. The server does not automatically retry 429 or 503 responses.
Security behavior
stdout is reserved exclusively for MCP protocol messages; diagnostics use stderr.
Authorization is sent only to protected resource URLs, never public discovery.
Redirects, credentialed base URLs, cross-origin discovery links, and links outside
/api/v1are rejected.Discovery uses a 300-second default cache with ETag revalidation and in-flight coalescing. Protected data and errors are never cached.
Upstream JSON bodies are bounded by declared and streamed byte size before parsing.
Error and diagnostic values recursively redact the configured key and authorization-like fields.
See SECURITY.md for reporting and key-handling guidance.
Development
Clone this repository and install its locked dependencies:
npm ciRun the complete local validation suite:
npm test
npm run typecheck
npm run build
npm run pack:check
npm run distributions:check
npm run mcpb:checkMaintainers can run the sandbox-only live launch audit with a temporary hg_test_ key held only in HANDIGRAPHS_API_KEY:
npm run audit:live:sandboxThe audit uses the official MCP client over stdio, discovers both sports, describes and queries all nine resources with compact/default metadata, and verifies cursor pagination without printing response rows or the key.
Tests use local mocked HTTP servers and the official MCP client, including an end-to-end stdio process. No live Handigraphs key or external service is required.
Build a local Claude Desktop artifact in artifacts/ with:
npm run mcpb:packMaintainers should use the GitHub Release workflow described in docs/releasing.md rather than publishing from a local machine.
License
Licensed under the Apache License 2.0.
Available Tools
3 toolsdescribe_resourceDescribe a Handigraphs Stats API resourceBRead-only
Return live resource, metric, split, unit, and filter discovery.
| Name | Required | Description | Default |
|---|---|---|---|
| sport | Yes | ||
| resource | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, which the description does not contradict. The description adds that the output includes live resource, metric, split, unit, and filter discovery, but it does not disclose error behaviors, output format, or additional side effects. This is basic context beyond annotations but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no filler, front-loaded with 'Return.' It is efficient but arguably too terse to be fully useful; however, conciseness is about economy, and this achieves that. It could earn a 5 if it packed more meaning, but it leaves too much to inference.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given two required parameters with zero schema descriptions, no output schema, and siblings that could be confused with this tool, the description is incomplete. It fails to explain target parameters, output structure, or the precise scope of 'discovery,' so the agent may not know how to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It mentions 'resource' as part of the discovery output but does not explain the parameters 'sport' or 'resource' (e.g., expected format or values). The agent has no guidance on how to fill the required fields, making this a significant gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the verb 'Return' and identifies what is returned: 'resource, metric, split, unit, and filter discovery.' This clearly indicates the tool provides discovery information. However, the term 'live' is ambiguous (could mean real-time data vs. metadata), and the description does not explicitly contrast with siblings, though the title and tool name suggest it describes a specific API resource.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The word 'discovery' implies use when exploring available metrics/filters before querying, but there is no explicit when-to-use or what-not-to-use instruction. No alternatives are named, leaving the agent to infer that this complements 'list_resources' and 'query_stats'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_resourcesList Handigraphs Stats API resourcesBRead-only
List live sports and stats resources from public Handigraphs discovery.
| Name | Required | Description | Default |
|---|---|---|---|
| sport | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the read-only and open-ended nature is covered. The description adds the context that resources are 'live' and 'public', which slightly expands on the annotations, but it does not disclose behavior like pagination, response format, or what happens when no sport filter is provided.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence with no redundancy. It front-loads the verb and object, and every word adds meaning. Very concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple list tool with annotations, the description is adequate but has clear gaps. It lacks explanation of the optional parameter's behavior and does not describe the response shape (no output schema). The openWorldHint and readOnlyHint provide some context, but the missing parameter semantics and output details keep it from being fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description does not mention the 'sport' parameter at all. With no compensation, the agent has no idea how to use the optional sport parameter, what values to pass, or whether it filters the list. This is a significant gap since the schema provides only the parameter name and length constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description states a specific action 'List' on a specific resource type ('live sports and stats resources') and scopes it to 'public Handigraphs discovery'. This clearly distinguishes from siblings 'describe_resource' and 'query_stats', which describe or query resources rather than list them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus the alternatives. The description only states what it does, leaving implications that you use it to list resources, but it does not mention when to prefer it over describe_resource or query_stats, nor any prerequisites or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
query_statsQuery Handigraphs statsARead-only
Query one live Handigraphs Stats API resource. Use describe_resource first; pagination remains in this tool via cursor.
| Name | Required | Description | Default |
|---|---|---|---|
| day | No | ||
| meta | No | ||
| sort | No | ||
| team | No | ||
| split | No | ||
| sport | Yes | ||
| cursor | No | ||
| filters | No | ||
| metrics | No | ||
| category | No | ||
| duration | No | ||
| location | No | ||
| opponent | No | ||
| resource | Yes | ||
| entity_id | No | ||
| page_size | No | ||
| stat_format | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds that it queries 'live' data, that pagination remains in the tool, and that describe_resource should be used first, offering behavior beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the core purpose, and includes a key usage directive. Every word adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 17 parameters, no output schema, and no parameter explanations, the description is far too minimal. It does not cover how to construct queries, interpret responses, or handle the complex filter and metrics structures, making it inadequate for the tool's complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 17 parameters with no descriptions, and the description only mentions cursor for pagination. It doesn't explain the meaning of sport, resource, metrics, filters, or other parameters, leaving the agent to infer from names and schema types.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it queries one live Handigraphs Stats API resource, using a specific verb and resource. It distinguishes from siblings by indicating it's for querying data, while list_resources and describe_resource serve other purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The instruction to 'Use describe_resource first' provides a clear prerequisite and workflow guidance. Pagination via cursor is noted, implying this tool handles subsequent pages. While alternatives aren't explicitly named, the sibling names imply their distinct roles.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
3 tool updates
v0.2.1- First observed
describe_resource - First observed
list_resources - First observed
query_stats
TDQS
Each tool serves a distinct function: discovery (list), introspection (describe), and data access (query). There is no overlap in their purposes, and the descriptions make it clear when to use each.
All tool names follow a consistent verb_noun pattern (list_resources, describe_resource, query_stats). The naming is predictable and reinforces the workflow.
Three tools is an ideal size for this server's scope: discover, understand, and query. Each tool is necessary and none feel redundant or missing.
The tool set provides a complete workflow for a stats API client: listing available resources, getting detailed descriptions, and querying with pagination support. There are no obvious gaps for the stated purpose.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Sports MCP — wraps TheSportsDB API (free tier, test key 3, no auth required)
Provides access to live sports data and analytics from BALLDONTLIE: The Sports API
TheSportsDB MCP — sports catalog (teams, players, events)
Live sports stats and pre-computed analysis for AI assistants across NBA, MLB, NFL, and NHL.
Related MCP Servers
- FlicenseBqualityNot gradedmaintenanceProvides access to FantasyPros API for retrieving sports data including news, player information, consensus rankings, and projections across NFL, MLB, NBA, and NHL.57-
- FlicenseNot gradedqualityDmaintenanceProvides access to live NHL data including player statistics, team standings, game scores, schedules, and playoff information through 40+ NHL API endpoints.3-
- AlicenseAqualityBmaintenanceProvides read-only access to the Sleeper Fantasy Sports API for league info, rosters, matchups, drafts, transactions, and player data.18711MIT
- AlicenseAqualityAmaintenanceEnables querying FIFA competitions, fixtures, results, and live match data through the FIFA Public API without authentication.1216MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/Handigraphs/handigraphs-stats-api-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server