inkcheck
MCP server for AI agents to compile, playtest, and exhaustively explore ink interactive fiction stories, catching compile errors, runtime errors, unreachable content, and verifying story structure.
README
inkcheck
CI for ink stories. Compile checks, exhaustive branch playtesting, runtime-error repro paths, and dead-content detection — as an MCP server for AI coding agents and as a standalone CLI for your pipeline.
inkcheck is a QA tool, not a writing tool. It doesn't generate a word of prose. It exists so that the story you wrote can be verified the way code is: every branch compiled, every reachable path played, every dead end and broken divert caught before a player finds it.
What it catches
- Compile errors and warnings — broken diverts, unresolved variables, loose ends, with file and line numbers (via inklecate, the official compiler)
- Runtime errors with a reproduction path — the exact sequence of choices that triggers a divide-by-zero, a bad external call, or out-of-content, e.g.
repro: [Enter in darkness → Descend to the cellar] - Unreachable content — knots no explored path ever visits, so orphaned scenes don't ship silently
- Every distinct ending — with the choice trail that reaches it, so you know your five endings are actually five reachable endings
vs. the alternatives
| Catches syntax errors | Plays every branch | Finds unreachable content | Repro path for crashes | Runs in CI | |
|---|---|---|---|---|---|
inklecate (compiler) |
✓ | — | — | — | ✓ |
| Manual playtesting | — | only what you click | by luck | if you remember your clicks | — |
| inkcheck | ✓ | ✓ (bounded exhaustive) | ✓ | ✓ | ✓ |
The compiler tells you the story is valid. Clicking through tells you the paths you happened to click work. Neither tells you whether all five endings are reachable or which choice sequence crashes the runtime. inkcheck walks the graph for you and answers exactly those questions — deterministically, in CI.
Example
$ inkcheck examples/manor.ink
✓ compiled — 92 words, 7 knots, 6 choices
✓ explored 10 states — 5 distinct ending(s)
ending via [Enter in darkness → Search the study → Leave with your loot]: "You slip out the servant door, heavier by half a purse."
...
✗ 1 runtime error(s):
obj is null or undefined (at cellar.3)
repro: [Enter in darkness → Descend to the cellar]
⚠ 1 knot(s) never visited on any explored path:
treasure_vault (manor.ink:35)
Exit code is non-zero on compile or runtime errors (add --strict to also fail on warnings and unvisited knots), so it drops straight into CI.
Scale check: it explores 5,000 states of inkle's published game The Intercept (14,728 words, 343 choices) in ~5 seconds, surfacing 16 distinct endings — and, correctly, zero errors.
MCP server
Four tools for AI agents working on ink stories:
| Tool | What it does |
|---|---|
compile_story |
Structured compile issues (severity, file, line) |
story_stats |
Word/knot/choice counts + full knot list with locations |
playtest_story |
Play one scripted choice path headlessly; returns transcript, tags, variables, errors |
explore_story |
Bounded exhaustive walk: endings, error repro paths, knot coverage |
Add to Claude Code:
claude mcp add inkcheck -- npx -y inkcheck mcp
or to any MCP client config:
{
"mcpServers": {
"inkcheck": { "command": "npx", "args": ["-y", "inkcheck", "mcp"] }
}
}
The intended loop for an agent editing a story: edit .ink → compile_story → explore_story → fix what it reports → repeat. The agent never has to guess whether a story graph is sound.
CLI
inkcheck <story.ink> [--max-depth N] [--max-states N] [--no-min-repro] [--strict] [--json]
inkcheck mcp # start the MCP server on stdio
GitHub Actions:
- uses: actions/setup-node@v4
with: { node-version: 22 }
- run: npx -y inkcheck story/main.ink --strict
For agents
inkcheck is built to be driven by an AI coding agent, not just a human at a terminal.
- Machine-readable interface:
tool.jsonat the repo root describes the CLI flags, MCP tools, exit codes, and--jsonoutput shape in one file. --jsonemits the entire report as a single JSON object ({ compile, stats, explore }) on stdout — parse that instead of scraping the pretty output.- Deterministic exit codes:
0clean ·1compile/runtime errors (or, under--strict, warnings and unvisited knots) ·2usage error. Branch on the exit code; don't grep the text. - MCP:
claude mcp add inkcheck -- npx -y inkcheck mcpexposescompile_story,story_stats,playtest_story, andexplore_storyas tools. - The loop: edit
.ink→compile_story→explore_story→ fix what it reports → repeat. inkcheck is a deterministic oracle for a story graph you generated or edited — use it to verify your own work before returning it.
llms.txt at the repo root is a compact, model-friendly summary of all of the above.
How it works
- Compilation uses
inklecate, the canonical compiler — found via$INKLECATE_PATH, thenPATH, then auto-downloaded from the official ink release into~/.cache/inkcheckon first run. Stories are compiled with-cso all knot visits are counted. - Exploration runs the compiled story in inkjs (the official JS runtime port), walking the choice tree depth-first from a single pooled story instance (the compiled JSON is parsed once, states rewind via
LoadJson). States are deduplicated by content hash (ignoring turn counters and RNG seeds), which is what makes stories with loops terminate.INCLUDEs are followed;EXTERNALfunctions are auto-stubbed so exploration doesn't require a game engine. - A second breadth-first pass shortens error and ending repro paths to minimal choice trails where they're reachable within limits (skip with
--no-min-repro). - Bounds (
--max-depth,--max-states) keep worst-case combinatorics in check; the report says explicitly when it was truncated.
Roadmap
- Localization/tag lint (untagged lines, inconsistent tag schemas)
- State assertions ("gold must never go negative on any path")
- Yarn Spinner support via
ysc
License
MIT
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.