npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

cricket-chat-mcp

v0.1.0

Published

MCP server for ball-by-ball cricket analytics: eight typed tools over a bundled DuckDB warehouse built from Cricsheet data.

Readme

cricket-chat-mcp

An MCP server for ball-by-ball cricket analytics. Eight typed tools over a DuckDB warehouse built from Cricsheet data — and the warehouse ships inside the package, so there is nothing to download, ingest, host or configure.

{
  "mcpServers": {
    "cricket": { "command": "npx", "args": ["-y", "cricket-chat-mcp"] }
  }
}

Drop that into your MCP client's config and ask a question.

Why this exists

Statsguru is comprehensive and does far more than people give it credit for: opposition, ground, year, batting position, result, toss, innings. What it cannot do is structural, because its grain is the innings and its interface is a form:

| Question | Why the existing sites can't | |---|---| | "Boundary % conceded in T20 death overs since 2020" | Needs the ball as the unit, not the innings | | "Every ball Rashid Khan has bowled to Buttler" | No batter × bowler cell exists | | "Now only in Asia" → "now just the 20th over" | No form UI can hold a conversation |

That is the gap these tools fill. The model composes filters; the server compiles them to SQL against a local file; you get the number, the population it was drawn from, and the window it covers.

What's in the warehouse

Queried from the shipped file, not hardcoded:

| Format | Gender | Range | Matches | Deliveries | |---|---|---|---|---| | IT20 | female | 2009-06-18 → 2026-08-23 | 2,118 | 481,616 | | IT20 | male | 2005-02-17 → 2026-08-21 | 3,528 | 795,382 | | T20 (franchise) | male | 2008-04-18 → 2026-05-31 | 1,243 | 295,732 |

T20 only, and that is the honest headline. No ODIs, no Tests. Ask get_data_coverage and the server will tell you exactly this rather than guess.

Two consequences worth knowing before you trust a number:

  • Ball-by-ball coverage has a floor. Nothing here predates 2005. A career average computed from this data for a player who debuted earlier is not a career average, and every response carries a career_possibly_truncated flag plus the actual window so the model states the boundary instead of quoting a bare figure.
  • Leaderboards are qualified by default — minimum 60 balls faced, 120 balls bowled. Without that, order_by strike_rate hands you someone who faced three balls and hit two sixes. The applied minimums come back in every response.

The eight tools

| Tool | What it does | |---|---| | resolve_entity | Name → 8-hex id. Call first for anything naming a player; every other tool takes ids, never names, and asks rather than guessing when a name is ambiguous. | | get_data_coverage | The table above, live. | | query_batting_aggregate | Runs, strike rate, average, boundary %, dot %, dismissals, for any slice. | | query_bowling_aggregate | Wickets, economy, bowling average and strike rate, dot %, boundary-conceded %. | | query_matchup | One batter against one bowler — the genuine blind spot in every existing site. | | get_scorecard | One match, three views: innings totals, every batter's line, every bowler's line. | | query_matches | Results, margins, venues, toss. | | get_career_reference | Full-career totals for ~100 retired greats, transcribed by hand from ESPNcricinfo with a source_url on every row. Flagged provenance: "reference" and never to be mixed arithmetically with computed figures. |

A failed call is not a protocol error. It returns the real field name, the allowed values, a did_you_mean list and a worked fix_example, so the model corrects itself in one turn instead of surfacing a red box to you. After three consecutive failures on the same tool the payload flips to retryable: false and the model is told to explain the limitation rather than keep guessing.

What it will not do

  • No live scores, no fixtures. Cricbuzz owns live; this is historical analysis, and the server says so rather than improvising.
  • No pace/spin or handedness beyond a curated set. Cricsheet has no such column, so bowling type is a hand-reviewed file covering the ~200 highest-volume bowlers. Any attribute-filtered answer reports its attribute_coverage, so a 90%-unknown result cannot pass as complete.
  • No raw SQL. Tools are typed and parameterised; sql_id in the response is a digest for correlating two calls, not a query you can edit.

CLI

npx cricket-chat-mcp --help        # usage
npx cricket-chat-mcp --version
npx cricket-chat-mcp --db path/to/other.duckdb

Started in a terminal it waits for JSON-RPC on stdin — it is meant to be spawned by a client. --db (or CRICKET_DB) points it at a different warehouse; the default is the bundled one.

Local development

Requires Node 22+.

npm install
npm run build      # tsc -> dist/
npm test           # vitest; warehouse-dependent suites skip without data/cricket.duckdb
npm run lint       # biome
npm run typecheck

The warehouse is not in this repo. It's 74 MB, and git cannot forget a blob once it's in history, so every clone would pay for it forever. It travels in the published npm tarball and is attached to each GitHub release instead. To get one for local work, either take data/cricket.duckdb out of a published tarball:

npm pack cricket-chat-mcp && tar xzf cricket-chat-mcp-*.tgz package/data/cricket.duckdb
mkdir -p data && mv package/data/cricket.duckdb data/

or build it with the ingest pipeline it came from. Without it, the warehouse-dependent test suites skip and the rest still run.

Attribution

Data from Cricsheet, licensed ODC-BY 1.0 — free reuse, including commercial, with attribution. If you build on this, attribute Cricsheet too: the ball-by-ball data is a decade of volunteer work and none of this exists without it.

Source code MIT. See LICENSE.