R2-D2
Click on "Deploy 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., "@R2-D2 find all leaders with aspect Villainy"
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.
R2-D2
A Star Wars Unlimited MCP server built with FastMCP. Search cards, build decks, validate formats, analyze the meta, and simulate two-player games — all through Claude Code, Claude Desktop, or any MCP-compatible client.
Card data comes from the live SWU DB API first and automatically falls back to the bundled local catalog when the API is unavailable.
Capabilities
Card Database
Tool | What it does |
| Natural text search with typed structured filters (aspect/type/arena/rarity/set as enums; cost/power/hp as |
| Exact lookup by name or set/number. Returns a typed |
| Random card from a filtered pool. Returns a typed |
| Front or back art URL for any card. |
Typed search filters (v0.3.0)
swu_search_cards, swu_lookup_card, and swu_random_card now return Pydantic models instead of opaque dicts. FastMCP serializes them as both content (human-readable text) and structuredContent (typed JSON) — agents can read .cards[0].cost directly without parsing string keys.
Filters are typed too. Aspect/type/arena/rarity/set are Literal[...] enums, so the agent sees the valid options in the tool schema and typos like aspect="Cunninng" are rejected before the API call. Numeric stats use a structured {op, value} instead of magic strings:
swu_search_cards(
query="Vader",
filters={"aspect": "Villainy", "type": "Leader",
"cost": {"op": ">=", "value": 5}},
)Deck and game tools still return dict — that refactor is staged for a follow-up.
Deck Building
Tool | What it does |
| Parse a decklist into a stateful session |
| Check legality for Premier or Twin Suns (leaders, base, copy limits, aspect penalties) |
| Resource curve, aspect breakdown, synergy score, role analysis |
| Targeted card suggestions for a stated goal or matchup |
| First-pass brew from a theme, leaders, and format |
| Export a session to a shareable decklist |
Game Simulation
Tool | What it does |
| Two-player setup with deck loading |
| Current board state, hand, resources, damage |
| Available actions with targeting options |
| Execute an action (play, attack, pass, etc.) |
| Let the AI pilot take a full turn |
| Card management |
| Direct board manipulation |
| Phase management |
Related MCP server: lorcana-mcp
Quick Start
uv sync
uv run python scripts/start_stdio.pyClaude Code / Claude Desktop Config
Add to ~/.mcp.json:
{
"mcpServers": {
"r2-d2": {
"command": "uv",
"args": [
"--directory",
"/path/to/r2-d2",
"run",
"python",
"scripts/start_stdio.py"
]
}
}
}Offline Catalog
A bundled card catalog (data/catalog/cards.json) is auto-discovered at startup. The server uses it as a fallback whenever the live API is unavailable — no configuration needed.
To rebuild the catalog from the latest API data:
uv run python scripts/build_catalog.pyEnvironment Variables
All optional — sensible defaults are built in.
Variable | Default | Purpose |
|
| Live card data API |
| Auto-discovered from | Local JSON fallback |
|
| Per-card response cache |
|
| Default search result limit |
Format Support
Premier — 1 leader, 1 base, 50+ main deck (3x copy limit), 10-card sideboard, off-aspect penalty reporting.
Twin Suns — 2 leaders sharing Heroism or Villainy, 1 base, 80+ singleton main deck, no sideboard.
Game Engine
The simulator supports two-player games with:
Resource turns, unit/event play, leader deployment, combat, base damage
Stack/priority loop with targeting and responses
Ambush, Sentinel, Saboteur, Overwhelm, Shielded, Restore, Raid, Hidden
When Played / On Attack / When Defeated trigger patterns
Upgrade attachment with static buffs and keyword grants
Basic AI pilot for sparring
This is a pragmatic rules engine for playtesting and AI sparring, not a comprehensive rules simulator. Edge cases around complex upgrade conditions, nested optional triggers, and deep timing interactions are not fully covered.
Example Prompts
"Search for all Cunning leaders from Legends of the Force"
"Generate a Twin Suns deck with Cad Bane and Jabba the Hutt"
"Upload this decklist, analyze it, and suggest swaps for an aggro-heavy meta"
"Start a game with my Qui-Gon deck against a generated Villainy aggro deck"
"Take my action to play Boba Fett, then let the AI respond"
License
Available Tools
32 toolsswu_analyze_deckB
Analyze a Star Wars Unlimited deck's curve, aspects, roles, and synergy.
Inputs: decklist, session_id, format_name, meta_context, +1 more. Returns: object
swu_collection_combo_profileA
Profile the loaded collection for combo-package density. Returns per-package enabler/payoff counts (Force engine, Indirect damage, When Defeated, Pilot/Vehicle, Token swarm, Cost reduction, Fortress, Bounty Hunter, Mandalorian) and flags which are 'live' (≥4 enablers + ≥2 payoffs). Pass refresh=true to recompute from scratch.
Inputs: refresh. Returns: object
swu_collection_summaryA
Summarize the loaded Star Wars Unlimited collection — total cards, unique printings, per-set breakdown, and storage path.
Inputs: no named parameters. Returns: object
swu_defeat_cardA
Defeat a card from the board or another in-play zone and move it to discard.
Inputs: zone, card_name, session_id. Returns: object
swu_draw_cardB
Draw one or more cards from an uploaded deck session.
Inputs: count, session_id. Returns: object
swu_export_deckB
Export a deck session or decklist as plain text or JSON.
Inputs: decklist, session_id, format_name, export_format. Returns: object
swu_generate_deckA
Generate a first-pass Star Wars Unlimited brew around a theme. Set only_owned=True to build only with cards in your loaded collection (quantities will be capped by ownership). By default the deck is restricted to on-aspect cards (the aspects granted by the two leaders plus the base); set allow_off_aspect=True to permit off-aspect splashes that cost extra resources. Set target_avg_cost to steer the curve (e.g. 2.5 for an aggressive low-curve deck, 3.5 for midrange); lower = cheaper and faster. When omitted, the format default is used.
Inputs: theme (required), budget, base_name, only_owned, +7 more. Returns: object
swu_get_game_stateA
Get the current two-player game state, with hidden information filtered by viewer unless reveal_all is true.
Inputs: game_id (required), viewer, reveal_all. Returns: object
swu_get_imageA
Return the front or back image URL for a Star Wars Unlimited card.
Inputs: name, set_code, back_face, card_number. Returns: object
swu_get_legal_actionsC
Return the currently legal actions for the active player in a game.
Inputs: game_id (required), player_id. Returns: object
swu_list_collectionA
List owned printings from the loaded collection, optionally filtered by set_code. Pass limit=0 for no limit.
Inputs: limit, set_code. Returns: object
swu_load_collectionA
Import a Star Wars Unlimited card collection from a SWUDB CSV export (columns: Set, CardNumber, Count, IsFoil). Persists to disk. Set merge=True to add to existing collection instead of replacing it.
Inputs: csv_path (required), merge. Returns: object
swu_lookup_cardA
Look up a specific Star Wars Unlimited card by name or set_code+card_number. Returns the full CardDetail record.
Inputs: name, set_code, card_number. Returns: Full card record returned by swu_lookup_card.
swu_move_cardA
Move an existing in-play card or leader/resource between zones such as ground, space, resource, and discard.
Inputs: ready, card_name, session_id, destination, +1 more. Returns: object
swu_mulliganA
Take a full-hand mulligan in the current deck session.
Inputs: session_id. Returns: object
swu_owned_countA
Return how many copies of a specific Star Wars Unlimited printing the user owns. Use set_code and card_number (e.g. LOF 47).
Inputs: set_code (required), card_number (required). Returns: object
swu_play_cardB
Play or deploy a card from hand, discard, or leader zone into ground, space, or resources.
Inputs: ready, damage, shield, card_name, +4 more. Returns: object
swu_random_cardB
Return a random Star Wars Unlimited card from a search result set.
Inputs: query, filters. Returns: Lightweight card view returned in search results. Accepts either CardRecord.to_…
swu_rank_leader_pairsA
Twin Suns only — brew a deck for every legal leader pairing in your owned pool and rank them by composite score (synergy + interaction density - off-aspect burden). Use moral='Heroism' or 'Villainy' to narrow. primary_aspects filters leaders whose aspects intersect the given list. include_decks=true returns full holoscan lists for the top_k results. Useful for surfacing leader pairs you wouldn't have considered manually.
Inputs: moral, theme, top_k, base_name, +4 more. Returns: object
swu_resource_phaseA
Advance the resource phase by readying resources, optionally resourcing a hand card, and drawing for turn.
Inputs: session_id, draw_for_turn, resource_card. Returns: object
swu_search_cardsA
Search Star Wars Unlimited cards using natural text and optional structured filters. Pass query for free-text matching; use filters to constrain by aspect, type, arena, rarity, set, trait, or numeric stats (cost/power/hp). Returns a typed SearchResult.
Inputs: limit, order, query, filters, +1 more. Returns: Top-level search result envelope.
swu_set_card_stateC
Update a card's ready state and counters while it is in play.
Inputs: zone, ready, damage, shield, +3 more. Returns: object
swu_sideboardB
Swap cards between the main deck and sideboard, then reset playtest zones.
Inputs: swaps, session_id. Returns: object
swu_simulate_gameA
Run a full AI-vs-AI game simulation to completion. Both players must be AI (set player_is_ai=true in start_game). Returns winner, base damage breakdown, MVP cards, and full game log.
Inputs: game_id (required), max_turns. Returns: object
swu_start_gameC
Start a two-player Star Wars Unlimited game between you and Claude.
Inputs: game_id, format_name, player_name, meta_context, +8 more. Returns: object
swu_suggest_cardsA
Suggest cards to improve a Star Wars Unlimited deck toward a stated goal. Set only_owned=True to restrict suggestions to cards in your loaded collection.
Inputs: goal (required), limit, decklist, only_owned, +4 more. Returns: object
swu_take_ai_turnC
Let the AI pilot its side for one turn or until it ends the turn.
Inputs: game_id (required), player_id, max_actions. Returns: object
swu_take_game_actionC
Take a game action such as resource, play, resolve_effect, pass_priority, deploy_leader, attack, or end_turn.
Inputs: game_id (required), action, card_name, player_id, +5 more. Returns: object
swu_upload_deckC
Upload a Star Wars Unlimited decklist into a named stateful session.
Inputs: decklist (required), shuffle, session_id, format_name, +1 more. Returns: object
swu_validate_deckB
Validate a Star Wars Unlimited deck for Premier or Twin Suns.
Inputs: decklist, session_id, format_name. Returns: object
swu_view_boardB
View the current in-play board state, including ground, space, leaders, bases, and resources.
Inputs: session_id. Returns: object
swu_view_handA
View the current hand, resources, and core counters for a deck session.
Inputs: session_id. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 32 tools
Tools are largely distinct, each targeting a specific resource or action (search, lookup, collection, deck, game). Minor overlap exists between view_hand/view_board and get_game_state, and play_card vs take_game_action, but descriptions clarify the contexts.
All tools share the swu_ prefix and use snake_case, with most following a verb_noun pattern. A few exceptions like owned_count and collection_summary deviate from verb-first but remain readable and predictable.
32 tools is above the 25+ threshold that indicates a bloated surface. While the scope covers card data, collection, deckbuilding, and gameplay, the count feels heavy and could be consolidated (e.g., combining game actions into a single action dispatcher).
The tool set covers card search, collection management, deck analysis/generation, playtesting, and full game simulation thoroughly. Minor gaps exist (no direct single-card ownership update, no persistent deck save beyond export), but agents can work around them.
Maintenance
Related MCP Connectors
MCP server that lets your AI assistant build and deploy apps, hosting each one at a live URL.
MCP server providing access to the Scorecard API to evaluate and optimize LLM systems.
MCP server for building and testing AI agents with multi-model experimentation and insights.
Related MCP Servers
- AlicenseAqualityBmaintenanceA comprehensive Model Context Protocol server that integrates with the Scryfall API to provide Magic: The Gathering card data to AI assistants like Claude.1475 npm1MIT
- AlicenseAqualityBmaintenanceAn MCP server for searching and aggregating Disney Lorcana cards, enabling card lookup, deck building, and statistical analysis.1017 PyPI1MIT
- AlicenseNot gradedqualityBmaintenanceUnified MCP server for Magic: The Gathering, combining Scryfall card search and pricing, EDHRec commander recommendations, Archidekt deck reading, and decklist validation into a single service.MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server that lets AI assistants look up Disney Lorcana TCG events, stores, and tournament data via the Ravensburger Play API.45 npm-