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

unofficial-ravensburger-playhub-mcp

v1.2.4

Published

MCP server for finding Disney Lorcana TCG events

Downloads

57

Readme

Lorcana Event Finder (MCP Server)

An MCP (Model Context Protocol) server that lets AI assistants look up Disney Lorcana TCG events, stores, and tournament data. It talks to the official Ravensburger Play API so you can ask things like “Where can I play Lorcana near Seattle?” or “What events are coming up in Austin?” from Cursor, Claude Desktop, Claude Code, or any MCP client.

What you need

  • Node.js 25.x (development/tests are pinned to Node 25 via .nvmrc)
  • npm (comes with Node)

Tip: run nvm use in this repo to load the pinned Node version.

No API keys or configuration are required. Event and store search work out of the box.

Quick start

From npm (no clone):

npx -y unofficial-ravensburger-playhub-mcp

From source:

git clone https://github.com/zammitt/unofficial-ravensburger-playhub-mcp.git
cd unofficial-ravensburger-playhub-mcp
npm install
npm run build
npm start

The server runs over stdio. Add it as an MCP server in your client (e.g. Cursor) to use the tools.

Using with Cursor

Cursor limits the combined server name + tool name to 60 characters. Use a short key (e.g. lorcana-event-finder) in mcpServers so tools like get_tournament_round_standings don’t get filtered out.

Option A — npx (easiest): No clone or build. In Settings → MCP, add:

{
  "mcpServers": {
    "lorcana-event-finder": {
      "command": "npx",
      "args": ["-y", "unofficial-ravensburger-playhub-mcp"]
    }
  }
}

Option B — from a local clone: Build first (npm run build), then point at the built script:

{
  "mcpServers": {
    "lorcana-event-finder": {
      "command": "node",
      "args": ["/path/to/unofficial-ravensburger-playhub-mcp/dist/index.js"]
    }
  }
}

After that, the Lorcana Event Finder tools are available to the AI in Cursor.

If you see "No matching version found" when Cursor starts the server: Clear npx’s cache, then reload MCP. In a terminal run: rm -rf ~/.npm/_npx (on Windows: rmdir /s /q %APPDATA%\npm-cache\_npx), then restart Cursor or reload MCP.

If you see "command not found" when running npx in a terminal: Don’t run npx from inside the package directory (same name as the package). npx will use the local project and the bin wrapper can fail. Run from another directory, e.g. cd ~ then npx -y unofficial-ravensburger-playhub-mcp.

Using with Claude

Add the server to Claude Desktop by editing your MCP config file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json

Option A — npx (easiest): No clone or build. Add or merge into the mcpServers object:

{
  "mcpServers": {
    "lorcana-event-finder": {
      "command": "npx",
      "args": ["-y", "unofficial-ravensburger-playhub-mcp"]
    }
  }
}

Option B — from a local clone: Build first (npm run build), then point at the built script:

{
  "mcpServers": {
    "lorcana-event-finder": {
      "command": "node",
      "args": ["/path/to/unofficial-ravensburger-playhub-mcp/dist/index.js"]
    }
  }
}

Restart Claude Desktop after changing the config. The Lorcana Event Finder tools will then be available to Claude.

Using with Claude Code

Claude Code (the IDE) can use this server via the CLI or by editing config. Options must come before the server name; -- separates the name from the command.

Option A — CLI with npx (easiest): No clone or build. Run in your project or from any directory:

claude mcp add --transport stdio unofficial-ravensburger-playhub-mcp -- npx -y unofficial-ravensburger-playhub-mcp

Use --scope user to make it available in all projects:

claude mcp add --transport stdio --scope user unofficial-ravensburger-playhub-mcp -- npx -y unofficial-ravensburger-playhub-mcp

Option B — CLI from a local clone: Build first (npm run build), then:

claude mcp add --transport stdio unofficial-ravensburger-playhub-mcp -- node /path/to/unofficial-ravensburger-playhub-mcp/dist/index.js

Option C — Config file: Add the same mcpServers entry as in the Cursor/Claude Desktop sections to:

  • Project scope: .mcp.json in your project root (share with the team), or
  • User scope: ~/.claude.json (in the mcpServers object).

Example for .mcp.json or ~/.claude.json:

{
  "mcpServers": {
    "lorcana-event-finder": {
      "command": "npx",
      "args": ["-y", "unofficial-ravensburger-playhub-mcp"]
    }
  }
}

Windows (native, not WSL): For npx-based servers, use the cmd /c wrapper:

claude mcp add --transport stdio unofficial-ravensburger-playhub-mcp -- cmd /c npx -y unofficial-ravensburger-playhub-mcp

Check that the server is listed with claude mcp list; in Claude Code you can run /mcp to see status.

LLM-friendly design

Tool descriptions include when to use each tool (e.g. city name → search_events_by_city, coordinates → search_events). Call list_capabilities first if the assistant is unsure which tool to use. list_filters returns exact format/category names for event search parameters.

MCP tools

The server exposes tools that are easy for LLMs to choose and call: descriptions include when to use each tool, and optional parameters are clearly documented. Call list_capabilities first if unsure which tool to use.

| Tool | When to use | |------|-------------| | list_capabilities | Call first when unsure which tool to use (e.g. search_events vs search_events_by_city). Returns a short guide. | | list_filters | Before searching events by format or category; returns exact names for the formats and categories parameters. | | list_quick_filters | List preset website filters like "Locals this week" and "Drivable Set Championships". | | list_games | List available game slugs and IDs from Play Hub. | | get_game_details | Get metadata for one game by slug (e.g. disney-lorcana). | | search_cards | Search cards by name text and return card IDs plus summary metadata. | | get_card_details | Fetch full metadata for one card by card ID. | | search_places | Autocomplete place suggestions and return place_id values for precise location matching. | | get_place_coordinates | Resolve a place_id to normalized address and lat/lng coordinates. | | search_events | When you have latitude/longitude (e.g. from a map or device). | | search_events_by_city | When the user says a city name (e.g. "events in Seattle" or "Austin, TX"). Geocoded. | | get_store_events | Events at a specific store by store ID (from search_stores). Use when the user asks about events at a particular store (e.g. "events at Game Haven"). No city or geocoding needed. | | get_event_details | Full details for one event; use when you have an event ID. For tournaments, the response includes round IDs. | | get_event_standings | Event results/standings by event ID. Use for "championship results", "who won", or "standings". The tool finds rounds and returns standings automatically—prefer over get_tournament_round_standings when the user asks for event results. | | get_player_leaderboard | Aggregate player performance across multiple past and in-progress events in a region and date range. Use when the user asks who had the most wins, top performers, or best record over many events (e.g. "who had the most wins in set championships in January 2026 in Detroit"). Single tool call; no need to search events then call get_event_standings per event. Date range max 3 months; radius max 100 miles. Call list_filters first for valid category/format names. | | get_player_leaderboard_by_store | Aggregate player performance across past and in-progress events at a specific store. Use when the user asks for top performers or leaderboard at a particular store (e.g. "leaderboard at Game Haven", "best players at store 123"). Get store ID from search_stores. Same date range (max 3 months), sort options, and format/category filters as get_player_leaderboard. | | get_event_registrations | Who is signed up for an event (names from API); needs event ID. | | get_tournament_round_standings | Standings for a specific round when you have a round ID (e.g. from get_event_details). | | get_round_matches | Pairings and match results for a round; needs round ID (from get_event_details). Use for "who played whom" or match results. | | search_stores | Stores or venues; optional name search and/or lat/long + radius + store_type. | | get_store_details | Full store profile details by game_store_id (UUID from search_stores output). | | search_stores_by_city | Stores near a city name (e.g. "stores in Seattle"), with optional store_type. |

Dates: When you omit start_date, search uses the start of today (UTC) so events that already started today are included. For "today's events" pass start_date: "YYYY-MM-DD" with today's date (correct year).

get_player_leaderboard and get_player_leaderboard_by_store can take longer when many events match (they fetch and aggregate standings for each). Use a narrow date range or category (e.g. "Set Championship") to keep results focused. Ties on sort (e.g. total_wins) are broken by fewer losses, then best placement.

Performance – caching

The server caches completed (past) events and their round standings in memory. Once an event is finished, its data does not change, so repeat lookups (e.g. the same event details or leaderboard date range) avoid extra API calls. Caches are shared across all tools and are bounded (up to 500 events, 1000 rounds) with simple eviction. Upcoming and in-progress events are never cached.

Development

npm install
npm run build   # compile TypeScript to dist/
npm test        # run unit tests from dist/; run build first
npm run test:integration   # run live integration tests (requires network)
npm run test:all           # unit + integration
npm run test:coverage      # unit test coverage report (c8)
npm run test:coverage:all  # coverage including integration tests
  • npm run dev – Run the server with tsx (no build step) for quick iteration.
  • npm start – Run the compiled server: node dist/index.js.
  • Verbose API logs (optional) – Set LORCANA_MCP_DEBUG=1 to print request/response debug lines for event search. Example: LORCANA_MCP_DEBUG=1 npm run dev

Project structure

| Path | Purpose | |------|---------| | src/index.ts | MCP server entry point: create server, register tools, run stdio transport. | | src/lib/ | Core library: types.ts, api.ts, formatters.ts (Ravensburger API client, types, human-readable formatters). | | src/tools/ | MCP tool handlers: events.ts, stores.ts, filters.ts. | | src/test/ | Unit tests (api, formatters) and integration tests (MCP server + tools). |

Tests

  • Unit testsapi.test.ts (API client: filter maps, strict resolution, fetch with mocked fetch, loadFilterOptions), formatters.test.ts (formatStore, formatEvent, formatLeaderboard, formatLeaderboardEntry, formatStandingEntry, formatRegistrationEntry), http.test.ts (retry/backoff helpers), registrations.test.ts, standings.test.ts. No network required for unit tests (npm test).
  • Integration testssrc/test/mcp-tools.integration.test.ts spawns the MCP server and calls each tool (required-only, optional params, pagination). They hit the real Ravensburger Play APIs (hydraproxy + Play Hub geocoding/autocomplete endpoints), so network access is required and tests may be slower or flaky if the APIs are slow or down (npm run test:integration). You can increase the suite timeout with INTEGRATION_TEST_TIMEOUT_MS, e.g. INTEGRATION_TEST_TIMEOUT_MS=180000 npm run test:integration.

Coverage is reported for dist/ (excluding dist/test/). Run npm run test:coverage to see statement/branch/function coverage for the app code.

API and data

Data comes from the Ravensburger Play API (events, stores, formats, categories, registrations, tournament rounds/standings, cards, games). City-based search uses Play Hub’s public geocoding endpoint (tcg.ravensburgerplay.com/api/address/geocode), the same path used by the website UI. No API keys are required.

Player names: Standings, round matches, registrations, and leaderboards show the player’s display name (username) when the API provides it, and fall back to first name + last initial (e.g. "Joseph C") when no display name is set.

Security & privacy

  • No API keys or secrets are stored in this repo or by the server.
  • All tools use public Ravensburger/Play Hub endpoints with no authentication.

Publishing to npm

  1. Create an npm account (if needed): npmjs.com/signup.
  2. Enable 2FA (required to publish): npm requires two-factor authentication to publish. In Account Settings → Two-Factor Authentication, turn on 2FA (auth-only or auth-and-writes). You’ll be prompted for the code when you run npm publish.
  3. Log in from the CLI: npm login (username, password, OTP when prompted).
  4. Check the package name: Ensure unofficial-ravensburger-playhub-mcp is not taken: npmjs.com/package/unofficial-ravensburger-playhub-mcp. If it is taken, change name in package.json (and optionally scope it, e.g. @yourusername/unofficial-ravensburger-playhub-mcp).
  5. Dry run: npm publish --dry-run to see what would be uploaded (no publish).
  6. Publish: npm publish. You’ll be prompted for your 2FA code. The prepublishOnly script runs npm run build first, so dist/ is built automatically.
  7. Later releases: Bump version in package.json (e.g. 1.0.1), then run npm publish again.

License

Unlicense — public domain. No copyright, no warranty, no liability. Use at your own risk.