Skip to main content

dndkit

A Model Context Protocol server that lets an AI be the game master of a Dungeons & Dragons 5e campaign: it keeps the characters, the world, the fights and the dice, and holds the rules, so the model narrates while the server keeps count. It is built with FastMCP 4 and made for voice play with several players around one microphone, as an MCP service in roomkit-ui, while working just as well from Claude Desktop or any MCP client, with a cloud model or a local one.

dndkit began as a fork of study-flamingo/gamemaster-mcp by Joel Casimir, and has since been largely rewritten: voice play with several players, rules kept by the server (combat, the battle map, hit dice, concentration, a campaign checked before play), skills, on-screen widgets and live web pages. It took a name of its own so as not to take the original project's. See CHANGELOG.md for what changed.

What it does

  • Campaigns: several campaigns, one active at a time, each saved as one JSON file. Creating a campaign never overwrites an existing one; deleting one takes a confirmation code and moves its file to a trash folder.
  • Characters: full 5e sheets; damage and healing with temporary hit points applied first, unconsciousness and death saves at 0 HP, massive damage; conditions and exhaustion; inventory that stacks; known spells and spell slots; short and long rests; experience and levelling up (hit points, proficiency, spell slots by class, French class names understood).
  • Combat: party characters and monsters in one initiative order, tracked by position so three "Goblin"s become "Goblin 1/2/3"; monster hit points, AC and conditions; a monster at 0 HP leaves the fight; newcomers mid-fight; the end of the fight sums the XP of the defeated.
  • Bestiary and encounters: saved stat blocks fill monsters in; planned encounters are rated easy to deadly against the party (DMG rules) and started with one call, their initiative rolled.
  • World: NPCs (with private bios), locations and quests with numbered objectives.
  • Journal: session notes and a per-campaign adventure log with search.
  • Dice and rules: d20, 1d20+5, 2d6+1d4+3, advantage and disadvantage; short rule reminders (conditions, cover, grapple, death saves...) by English or French name.
  • Several players: each spoken turn names its speaker; a roll call says who plays which character tonight, and only the characters at the table count for difficulty and XP.
  • Battle map: a grid where moves follow the 5e rules (speed, terrain, opportunity attacks), areas of effect, cover, hidden foes.
  • Before play: check_campaign says what breaks the rules or is missing in a new campaign, each with the tool that fixes it.
  • Skills: how-to guides the model loads when it needs them: being the game master and preparing a campaign, monsters and bosses, the battle map.
  • On-screen widgets (MCP Apps): rolling dice, a live combat tracker, a party board, the table and character sheets, in clients that show MCP Apps.
  • Live web pages: a table screen, each player's sheet on their phone, and a backstage where you follow every call the model makes.

Names are matched without case or accents ("elodie" finds "Élodie"), and a part of a name is enough when only one name contains it ("phare" finds "Le phare éteint"), the way a speech transcript spells them. When a call fails, the error says why and lists the known names, so the model can correct itself.

Install and run

Requires Python 3.12+ and uv.

# From PyPI (from the first release, 0.4.0)
uvx dndkit

# Straight from GitHub
uvx --from git+https://github.com/sboily/dndkit dndkit

# From a checkout
git clone https://github.com/sboily/dndkit.git
cd dndkit
uv sync
uv run dndkit

The server speaks MCP over stdio: an MCP client starts it, you don't keep it running yourself. uvx fetches it on first use and keeps it cached.

Configuration

Variable Default Purpose
DNDKIT_STORAGE_DIR the per-user data directory (below) Where campaigns are stored
DNDKIT_LOG_LEVEL INFO Log level; logs go to stderr
DNDKIT_WEB_PORT unset: no web pages Serve the live web pages on this port
DNDKIT_WEB_HOST 127.0.0.1 0.0.0.0 lets phones on the same network open them
DNDKIT_WEB_URL guessed The address phones should use, when the server cannot tell (a DNS name, Tailscale)

Default data directory:

  • macOS: ~/Library/Application Support/dndkit
  • Linux: ~/.local/share/dndkit (or $XDG_DATA_HOME/dndkit)
  • Windows: %LOCALAPPDATA%\dndkit

Before its rename the project was gamemaster-mcp: its GAMEMASTER_* variables still work, and its data directory is used as long as no dndkit one exists.

To start a campaign from a prepared world document, drop a .md or .txt file in the settings/ folder of the data directory and pass its name as setting_file to create_campaign or update_campaign. Only files directly in that folder can be read.

With roomkit-ui

In Settings → Integrations → MCP, add a server:

Field Value
Name dndkit
Transport stdio
Command uvx
Arguments dndkit (from PyPI), or --from git+https://github.com/sboily/dndkit dndkit
Environment variables DNDKIT_STORAGE_DIR=/Users/you/Games/dnd (optional)
DNDKIT_WEB_PORT=8765 and DNDKIT_WEB_HOST=0.0.0.0 for the web pages (optional)

From a local checkout instead: Command uv, Arguments run --directory /path/to/dndkit dndkit.

roomkit-ui reads what the server publishes besides its tools: its skills (roomkit 0.98 and later) and its instructions, which tell the model how the tools are meant to be used (roomkit 0.99). Put the system prompt below in the assistant's personality.

The 62 tool schemas weigh about 8,900 tokens by roomkit's own estimate, over the 8,000 at which roomkit may hide tools behind find_tools: keep the skills on (the tools they bring then wait for them: about 7,300 tokens), or raise roomkit's threshold (tool_search_threshold_tokens). roomkit-ui's automatic Tool Search leaves a local voice model every tool. Optional parameters are advertised without their null alternative to save room.

Local models

A model running on your own computer can be the game master. The local model bench plays scripted table turns through roomkit with Ornith 1.5 35B-A3B (llama.cpp): with thinking on it passes 26 to 30 of 36 scenarios; without thinking it mostly narrates instead of calling the tools. Tool Search hurts such a model: leave every tool in sight. A thinking turn takes about a minute, which roomkit-ui's background tasks (on a llama.cpp model of their own) keep away from the voice.

Skills

The server ships three Agent Skills, how-to guides the model loads when it needs them, and publishes them by the official MCP Skills extension (SEP-2640, io.modelcontextprotocol/skills): it declares the extension in its capabilities, serves every skill file as a skill://<name>/<file> resource, and answers skills/list and skills/get with each skill's frontmatter and the SHA-256 digest and size of its files. The server instructions also point at each skill's URI, for hosts that only read resources. Load dnd-game-master first: the system prompt below asks for it.

Skill Teaches Gates (roomkit)
dnd-game-master To load first: the game master leads and acts, what the tools hold, opening and ending a session, a session zero by the rules (scores, armor, weapon, skills and spells for each class), check_campaign before play nothing
dnd-monsters Inventing monsters and bosses sized to the party, preparing and rating a fight, legendary actions and resistances, lair actions save_monster, plan_encounter
dnd-battle-map Fights on the grid: laying out the room, placing and hiding combatants, moving by the rules, areas of effect, cover set_battlefield, place_tokens, move_token, area_of_effect, check_target

A skill's allowed_tools frontmatter is roomkit's: roomkit keeps those tools out of the catalogue, and out of its token count, until the model activates the skill. With the skills on, the catalogue weighs about 7,300 tokens. roomkit-ui lists them under the server's name; a client that does not speak the extension can load them from src/dndkit/skills/ as a skill folder.

With Claude Desktop

{
  "mcpServers": {
    "dndkit": {
      "command": "uvx",
      "args": ["dndkit"],
      "env": { "DNDKIT_STORAGE_DIR": "/Users/you/Games/dnd" }
    }
  }
}

System prompt for a voice game master

You are the game master of a Dungeons & Dragons 5e session played by voice.
Speak the players' language, in short spoken sentences: no lists, no markdown.
You lead the game: you decide when a roll is needed, make it and apply it
with the tools, without asking leave. Before anything else, activate the
dnd-game-master skill.

Several players sit around one microphone; each of their turns opens with
who said it. Open every session the same way:
- Greet the table and ask who is playing tonight. When a voice is not named
  yet, ask who it is and call name_speaker.
- Call seat_players with start_over and each player with their character.
  Someone new gets a character first: create_character with their name as
  player_name.
- Remind the table where the last session ended (get_sessions), then play.
Call seat_players again when someone arrives or leaves. A player's "I attack"
is their character's action; speak to players by name and to characters in
the story. Absent players' characters stay in the background.

The dndkit tools hold the campaign. Trust them over your memory:
- Before describing a character, place or quest, read it (get_character,
  get_location, get_quest, get_game_state).
- Record every change as it happens: damage and healing with change_hit_points
  (characters and monsters), conditions with set_condition, a spell held
  with set_concentration (damage then asks for the save), items with
  add_item_to_character and remove_item_from_character, spells with
  use_spell_slot, the party's location and date with update_game_state.
- Roll every die with roll_dice and say the result; never invent a roll.
  Resolve each roll yourself: the attack against the target's AC, then the
  damage, applied with change_hit_points. Never ask the players for a total
  or a number the tools hold (get_character gives bonuses, spell attack and
  save DC).
  What the players must not see (a hidden foe's Stealth, an NPC's lie) is a
  secret roll: say only what it means.
- Ability checks and saves use the sheet's bonuses (get_character); a short
  rest spends Hit Dice with rest and hit_dice.
- In combat, start_combat with everyone's initiative (or a planned encounter),
  then next_turn after each turn. Monsters at 0 HP leave the fight on their own.
  When positions matter, play it on the battle map (the dnd-battle-map skill:
  set_battlefield, then move_token for every move).
  At the end, end_combat, then award_experience with the XP it reports.
- When you're unsure of a rule, lookup_rule.
- Never call get_screen_data: it feeds the on-screen widgets.
- Log notable moments with add_event, and summarise the session with
  add_session_note when the players stop.
- When a tool reports an unknown name, pick the right one from the names it
  lists, or ask the players; never create a duplicate.
- You run the monsters. One the story needs and the bestiary lacks is yours
  to create: save_monster with a challenge rating fitting the party (and
  boss for the boss), then plan_encounter to check the fight's difficulty.
  Spend a boss's legendary actions and resistances with use_legendary, and
  any creature's reaction (an opportunity attack, Shield) with take_reaction.
  A condition that lasts a while gets its rounds in set_condition.
- remove_from_campaign and delete_campaign work in two calls: the first
  says what would be lost and gives a code; ask the players, and call again
  with the code only after a clear yes.

Starting a new campaign, run a short session zero, one question at a time:
the campaign's name and pitch, then each player's character (name, race,
class, level, ability scores, then their skills with update_character), the
starting location, a first NPC and a first quest, creating each with its tool
as soon as you have it (the dnd-game-master skill has the rules for each).
Then call check_campaign and fix what it lists before the first scene.

Tools

Area Tools
Campaign create_campaign, get_campaign_info, check_campaign, list_campaigns, load_campaign, update_campaign, delete_campaign, remove_from_campaign
Characters create_character, get_character 🖥, list_characters, update_character
Resources add_item_to_character, remove_item_from_character, record_death_save, rest
Spells set_spell_slots, use_spell_slot, set_known_spell
Progression award_experience, level_up
NPCs create_npc, get_npc, update_npc, list_npcs
Locations create_location, get_location, update_location, list_locations
Quests create_quest, get_quest, update_quest, list_quests
Table seat_players 🖥, get_game_state 🖥, update_game_state, change_hit_points, set_condition, set_concentration
Combat start_combat 🖥, add_combatant, next_turn, remove_combatant, use_legendary, take_reaction, end_combat
Battle map set_battlefield 🖥, place_tokens, move_token, area_of_effect, check_target
Bestiary save_monster, get_monsters, plan_encounter, list_encounters
Journal add_session_note, get_sessions, add_event, get_events
Utility roll_dice 🖥, lookup_rule, get_screen_data (for the widgets)

🖥 opens an on-screen widget in clients that support MCP Apps.

update_character sets absolute values; change_hit_points applies damage or healing to characters and monsters alike, and changes nobody if one name is unknown. A tool that fails changes nothing, in memory or on disk.

A few rules the tools keep:

  • Before play: check_campaign lists what breaks the 5e rules (hit points the hit dice cannot give, AC under Unarmored Defense, a caster with no spells) and what a first campaign forgets (a fighter without armor, scores left at 10, no weapon, no quest or place), each with its fix.
  • Proficiencies: update_character takes skills, saving throws (English or French names: Discrétion, Sagesse), languages and features; a new character is proficient in its class's saves. The sheets give each proficient skill and save with its bonus. expertise doubles the proficiency of a rogue's or a bard's chosen skills, and a bard from level 2 adds half of it to every other check, initiative included (Jack of All Trades).
  • Hit Dice: rest with hit_dice spends them on a short rest (rolled on the dice tray, each die plus the Constitution modifier); a long rest gives half of them back.
  • Concentration: set_concentration holds one spell. Damage then asks for the Constitution save (DC 10 or half the damage); 0 HP or an incapacitating condition ends it.
  • Secret rolls: roll_dice with secret shows on the backstage only, not on the table screen, the phones or the dice widget.
  • Down at 0 HP: three death save successes or stabilized (Spare the Dying, Medicine) leave a character stable, without death saves until hit or healed; sheets say dying, stable or dead.
  • Exhaustion 4 halves the hit point maximum, 6 kills.
  • Reactions: one a round (take_reaction), back at the start of the creature's turn; one that has reacted provokes no more opportunity attacks.
  • Timed conditions: set_condition with rounds ends by itself at the end of the target's turn that many turns on; next_turn says so.

Monsters and bosses

The game master invents the monsters its story needs: save_monster with a challenge rating alone fills armor class, hit points and a line of attack bonus, damage a round and save DC from the DMG's "Monster Statistics by Challenge Rating", for the model to flesh out. boss marks the fight's boss, a legendary creature with 3 legendary actions a round and 3 legendary resistances a day unless told otherwise. In combat, use_legendary spends them (actions at the end of another creature's turn, back at the start of its own); the screens crown the boss, and the game master's show what it has left. Combatants are found by a unique part of their name ("gardien" for "Gardien de Magma").

Characters created without hit points or armor class get the PHB's: the class hit die at level 1 and its average after, plus Constitution each level; 10 + Dexterity without armor. A caster gets its class's spell slots and casting ability, and its sheet (get_character, the widget and the player's page) gives the spell attack bonus and save DC; the sheet also shows the initiative bonus, background, alignment, appearance and story, spells with their descriptions, gear, features, proficiencies and languages. get_character without a name reads whose turn it is.

The running fight keeps up with the campaign: a combatant named after a party character (even "Fizbin the gnome") plays from that sheet, including one created once the fight began, and a monster that joined without numbers takes its stat block as soon as save_monster saves it.

Battle map

A fight can be played on a grid of 5-foot squares named like a chessboard (a column letter and a row number, A1 at the top left). set_battlefield lays it out with walls and difficult terrain; start_combat puts everyone without a square at an edge (the party left, its foes right) and place_tokens sets chosen squares (an ambush). move_token moves a combatant by the 5e rules (PHB ch. 9) and refuses an impossible move:

  • 5 feet a square, diagonals included (the PHB grid rule), 10 in difficult terrain or through another creature's space; walls are walked around and never cut diagonally;
  • allies can be passed through, foes only when two sizes apart; nobody ends a move on someone else; a Large creature holds 2x2 squares, Huge 3x3, Gargantuan 4x4 (save_monster's size);
  • speed from the sheet (25 ft for dwarves, halflings and gnomes, else 30; create_character's speed overrides it) or the stat block's speed; grappled, restrained, stunned, paralyzed, petrified or unconscious: 0; exhaustion halves it from level 2; Dash doubles the turn's movement;
  • a prone mover stands up first, for half its speed;
  • leaving a foe's reach provokes an opportunity attack, which the result names, unless the mover Disengaged; forced movement (a shove, a spell, a teleport) spends nothing and provokes nothing;
  • toward someone stops within reach or as close as it can ("still 15 ft away"); away_from backs off; next_turn restores the next combatant's movement.

Around the moves:

  • area_of_effect says who a spell or a breath catches: a sphere (or cylinder) of radius R at a square or a creature holds every square within R feet as the grid counts them; a cube is centred there, or set against its source's side facing toward; a cone (as wide as it is far) and a line start at the edge of the caster's space, and take a square when at least half of it is covered (DMG). Walls stop an area. Everyone caught is named, allies first; the area shows on the map until the next turn.
  • check_target gives what an attack needs: distance, reach, cover by the DMG corner rule (walls give half, three-quarters or total cover, creatures half at most), a foe adjacent to a ranged attacker, hidden attacker or target.
  • Hidden foes (place_tokens with hidden, or a planned group's hidden) stay off the players' screens altogether: no token, no line in the initiative they see, no turn named, no hole in the squares a character can reach. The game master's screens show them faint. hidden: false reveals.
  • plan_encounter can carry a battlefield and, per monster group, the squares at which they start (checked against the map, its walls and each other); start_combat with that encounter lays it all out.

remove_combatant takes a creature out of the fight and off the map: a defeated or fled foe counts for XP, a withdrawn one (a mistake, a change of plan) leaves no trace; add_combatant brings one in at its side's edge.

The model reads the map in text: set_battlefield and place_tokens return a grid with a legend, every move says what it cost, what is left and who is in reach, and get_game_state lists the squares and the distances from whoever is acting. The combat widget and the web pages draw it: tokens gold for the party and red for its foes, the squares the acting character can still reach, and on a player's phone their own token ringed. The players' pages show how hurt a foe looks, never its hit points. The map goes away with end_combat.

Who plays

roomkit-ui tells the voices apart (enrolled voices, or Meta Muse labels that the user or the model's name_speaker names) and opens each spoken turn with the speaker's name. The game keeps the rest: a character's player_name ties it to a person, and seat_players records who is at the table tonight, in seat order. Players are matched by name, case and accents aside; the server keeps no voice data. Once there has been a roll call:

  • get_game_state says who plays whom, who is absent and which characters nobody plays, so the model finds its way after a break;
  • encounter difficulty (plan_encounter, list_encounters) counts the characters at the table only: two players out of four turn a medium fight into a deadly one;
  • award_experience without names shares the XP between the characters at the table; name absent characters to include them.

Without a roll call, the whole party counts as present.

delete_campaign works in two calls. The first deletes nothing: it says what the campaign holds and returns a 4-digit code valid for 5 minutes. Only a second call with that code deletes, by moving the file to <data dir>/trash/, from where it can be put back by hand. A wrong code cancels the request.

On-screen widgets (MCP Apps)

Six tools carry an MCP App (_meta.ui.resourceUri): the client opens their page next to the conversation.

Tool Widget
roll_dice Dice tray: each die tumbles and lands on its face; a natural 20 glows, a natural 1 shakes; with advantage the discarded d20 fades out; recent rolls below.
start_combat, set_battlefield Combat tracker, live: the battle map when there is one, initiative order, current turn, hit point bars that flash on damage or healing, AC, conditions, the defeated and their XP.
get_game_state Party board, live: location, date, funds, every character's hit points, spell slots, conditions and death saves, quest progress, combat banner.
seat_players The table, live: the players seated around it with their characters, newcomers without one yet, absent players and characters nobody plays.
get_character Character sheet, live: hit points, AC, proficiency, XP to next level, abilities, conditions, spell slots, spells, inventory.

Each page is self-contained (no network access), French or English after the system language, and reads its data with the get_screen_data tool, refreshing every couple of seconds: the combat tracker follows change_hit_points or next_turn calls made later in the conversation. The widgets only display; the game changes through the conversation, so the model always knows the state.

Live web pages

With DNDKIT_WEB_PORT set, the server also serves web pages that follow the game as it happens: every change made through a tool, and every roll, is pushed to the open pages at once (server-sent events). The pages run inside the MCP server's process, so they are up while roomkit-ui runs the server and reconnect by themselves when it restarts. A taken port only logs a warning; the game goes on without the pages.

Address For Shows
/table/ a shared screen (TV, laptop) The campaign's name and pitch, the session, place and date; initiative order, the party's hit points and conditions (absent players' characters faded), the table with who sits where, the dice tray, active quests, the adventure log, and a QR code per character
/p/<code>/ each player's phone Their full character sheet, the fight, the dice, quests and log, the party; "Your turn!" and a buzz when their turn comes
/gm/ you, on the computer running the game Everything, to follow and debug what the model does: the model's activity (every tool call with its arguments, its answer or error and its time, and the skills the client fetched); the fight with exact monster hit points and AC, or the last fight between two; the adventure log with importance, characters and tags; planned encounters and their difficulty; every quest with its objectives and notes; the notebook (current situation, world notes, setting, past sessions, version, campaign file, last save, skills); the world (NPCs with their secrets and ties, locations with the party's marked, the bestiary's full stat blocks and how many are fighting); every character's full sheet with the game master's notes; the players' join codes
  • Joining: players scan their character's code on the table screen. Each link carries a code derived from the campaign, the character and a key kept in the data directory (player-links.key): it cannot be guessed, survives restarts, and belongs to the active campaign. Delete the key file to change every link.
  • What players see is built field by field from what they may know: the campaign's description (a pitch: create_campaign asks for no spoilers), their party in full, but a monster only as unhurt, hurt, bloodied or down, and never an NPC's biography or notes, a planned encounter, a monster's statistics or the game master's notes.
  • The activity lives in memory for the session, like the dice log, and skips the widgets' own get_screen_data polling. A call the client refuses before sending it (roomkit checks required arguments) never reaches the server, so it is not there: look at the client's log for those.
  • The backstage opens only from the computer running the server: a loopback peer, asking for this server by name (localhost, its address or DNDKIT_WEB_URL's host), so a web page whose domain points at this computer (DNS rebinding) is refused. Requests carrying proxy headers are refused too, but a reverse proxy or tunnel on that computer that adds none would make every visitor look local: do not put one in front of the pages.
  • Read-only: the pages never change the game; it changes through the conversation, so the model always knows the state.
  • Phones need DNDKIT_WEB_HOST=0.0.0.0 and the same network. The table screen then puts this computer's network address in the codes, even when it is open at 127.0.0.1. For players elsewhere, put a private network such as Tailscale between you and set DNDKIT_WEB_URL; the pages carry no other authentication.
  • The log names the addresses at startup: Table screen: http://127.0.0.1:8765/table/.

Data

See docs/STORAGE_STRUCTURE.md. Campaigns saved by gamemaster-mcp, dndkit's upstream, load as they are and are rewritten in the current format at their first change. Its global events/adventure_log.json is not imported: events now belong to their campaign.

Development

uv sync --extra dev
uv run pytest
uv run ruff check . && uv run ruff format --check .
uv run mypy src/
uv run bandit -r src/ -c pyproject.toml
npm ci && npx knip     # unused files and exports in the pages' scripts

The pages' scripts (src/dndkit/ui/*.js) are ES modules, so knip can follow who imports what; each page inlines them as one script. GitHub Actions runs all of the above on every push and pull request (Python 3.12 and 3.13), and pre-commit install runs most of it before each commit.

CLAUDE.md describes the architecture and the project's rules.

Releasing

Each change worth telling goes into CHANGELOG.md under ## Unreleased with the commit that makes it. To release, on an up-to-date main:

uv run python scripts/release.py prepare 0.5.0   # versions follow semver
git push origin main v0.5.0

prepare names the Unreleased section ## 0.5.0 (<date>), sets the version in pyproject.toml and uv.lock, commits release: 0.5.0 and tags v0.5.0; it refuses outside main, with uncommitted changes, an empty Unreleased section or an existing tag. The tag runs .github/workflows/release.yml: it checks that the tag matches the version, sits on main and has its changelog section, runs the tests and builds, then publishes to PyPI by trusted publishing (no token: PyPI trusts the workflow in its pypi environment) and makes the GitHub release, its notes the version's changelog section, the built files attached. A failed step stops what follows: nothing reaches GitHub's releases before PyPI has the version.

Once, on pypi.org: add a pending trusted publisher for the project dndkit (owner sboily, repository dndkit, workflow release.yml, environment pypi). GitHub creates the pypi environment at the first release; required reviewers set on it (Settings → Environments) hold each release for approval.

License

MIT, see LICENSE. dndkit keeps the copyright of gamemaster-mcp, the project it was forked from.

Metadata

Release files for dndkit 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dndkit 0.4.0
File Size Uploaded
dndkit-0.4.0.tar.gz 209.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for dndkit 0.4.0
File Interpreter ABI Platform
dndkit-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 409.0 kB

Release files / dndkit-0.4.0.tar.gz

Download URL dndkit-0.4.0.tar.gz
Size 209.1 kB
Tags Source
SHA-256 checksum
How to use checksums
f5eff0243287b9ec78dce8e73385df25d61b987e98f7071ef8c48f3d285b2f64
BLAKE2b-256 checksum
How to use checksums
ad6c7c1bc72992d7d141cf1e72b6e483506020e2d46131790da3e0db663f7d2f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / dndkit-0.4.0-py3-none-any.whl

Download URL dndkit-0.4.0-py3-none-any.whl
Size 199.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
48e7681eac1ddcb09547b639d3a2952f1b56e5c5091a64c179439e1beb18f8e0
BLAKE2b-256 checksum
How to use checksums
a3028bab23f3ecc499803a1004320438cc563e58d40d36916764e449b610ea1f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.5.0

2 release files

This release

0.4.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page