Skip to main content
Glama

Gamebook

A minimal choose-your-own-adventure system with a FastAPI book backend and a Python MCP server that exposes the story to an LLM.

Run it

Play the adventure directly in a terminal. This starts the backend automatically if it is not already running:

uv run gamebook-play

Select a story with --story; the current observatory adventure is the default:

uv run gamebook-play --story observatory
uv run gamebook --story observatory
uv run gamebook-backend --story observatory

Each built-in story is defined in a YAML file under src/gamebook/stories and registered in gamebook.story.STORY_MODULES.

Related MCP server: LLMMO Game Server

Story YAML

Each story file has a start_scene_id and a scenes mapping. A scene defines its narrative text, items, optional stateful_items, and outgoing edges. The loader validates the YAML and converts it into the same NetworkX graph and runtime models used by the game engine.

start_scene_id: hall
scenes:
	hall:
		title: Hall
		context: A locked door leads into the library.
		hint: The door needs a key.
		items: []
		stateful_items:
			- id: library_door
				name: Door
				is_takeable: false
				initial_state: Locked
				descriptions:
					Locked: The Door is Locked.
					Unlocked: The Door is Unlocked.
		edges:
			- id: library_door
				destination_scene_id: library
				stateful_item_id: library_door
				choice: {id: library, description: Enter the library.}
				rule:
					required_item_states:
						- {item_id: library_door, state: Unlocked}
				bidirectional: true
				reverse:
					choice: {id: hall, description: Return to the hall.}
	library:
		title: Library
		context: Dusty shelves fill the room.
		hint: The shelves are worth examining.
		items: []

State predicates use {item_id, state} mappings. Stateful-item transitions use {from, to}, and an item-use conditional rule can set states and replace the item's normal action_message when its required states match.

Use story-level stateful_item_groups for rules that depend on a combination of stateful items, including items in different scenes. Rules are evaluated in order after a group member changes; the first matching rule applies its effects and optional action_message.

Stories use a NetworkX MultiDiGraph. Each graph node stores a StoryNode containing the scene text and items, while each directed edge stores the choice, visibility conditions, traversal rules, and state changes for moving to another scene. A multigraph allows multiple distinct choices to connect the same pair of scenes.

Each StoryNode declares its outgoing StoryEdge values. create_story validates those declarations and builds the graph, expanding a bidirectional edge into reciprocal directed edges. The reciprocal edges share one stable edge ID; when supplied with a non-takeable StatefulItem, its mutable state is stored once per adventure and is therefore visible from both connected scenes. The graph remains a shared story template and never stores player session state.

Enter a choice number to move through the story. Other commands include use <item> [on <target>], examine <item>, take <item>, drop <item>, inventory, look, hint, hint direct, restart, and quit.

Set requires_target: true on an item to require the on <target> form.

Start the book backend and Streamable HTTP MCP server together:

uv run gamebook

Docker

Build the image and start both the MCP server and backend:

make build
make run

The MCP server is available at http://localhost:8000/mcp; the backend is available at http://localhost:8001. Set STORY to choose a registered story, for example make run STORY=observatory.

Start the terminal player in a container with:

make play

The MCP endpoint is http://localhost:8000/mcp. It listens on all WSL network interfaces so applications running on Windows can connect to it. The backend listens internally at http://127.0.0.1:8001; its interactive API docs are at http://127.0.0.1:8001/docs.

Configure LM Studio's mcp.json to connect to the already-running server:

{
	"mcpServers": {
		"gamebook": {
			"url": "http://localhost:8000/mcp"
		}
	}
}

VS Code is configured separately to launch gamebook-mcp over stdio from .vscode/mcp.json. Open the MCP Servers view or run MCP: List Servers, then start gamebook to use or debug it. The HTTP backend must also be running for tools launched this way.

For development, the components can also run separately:

uv run gamebook-backend
uv run gamebook-mcp

Point the MCP bridge at another backend by setting GAMEBOOK_BACKEND_URL.

MCP tools

  • begin_adventure starts a session and returns the opening scene.

  • choose_action sends one of the offered choice IDs to the backend.

  • use uses an inventory item or a stateful item in the current scene.

  • examine describes an inventory item or an item in the current scene.

  • look_around returns the current scene and items present there.

  • request_hint asks the backend for a subtle or direct clue.

  • check_inventory returns the player's health and inventory.

  • take_item moves an item from the current place into the player's inventory.

  • drop_item moves an inventory item into the player's current place.

Run the tests with uv run pytest.

Available Tools

9 tools
begin_adventureB

Begin a new adventure and receive its opening context and choices.

Inputs: adventure_session_id. Returns: title, choices, context, message, +3 more

check_player_statusB

Check the player's current health and inventory.

Inputs: adventure_session_id (required). Returns: health, message, inventory, adventure_session_id

choose_actionC

Choose one of the action IDs offered by the current scene.

Inputs: choice_id (required), adventure_session_id (required). Returns: title, choices, context, message, +3 more

drop_itemC

Drop an inventory item in the player's current place.

Inputs: item_name (required), adventure_session_id (required). Returns: health, message, inventory, adventure_session_id

examineB

Examine an inventory item or an item present in the current scene.

Inputs: item_name (required), adventure_session_id (required). Returns: message, item_name, description

look_aroundB

Review the current place, including any items present there.

Inputs: adventure_session_id (required). Returns: title, choices, context, message, +3 more

request_hintA

Request a subtle hint, or set direct to true for a stronger clue.

Inputs: adventure_session_id (required), direct. Returns: hint, strength, adventure_session_id

take_itemB

Take an item using its exact name; failures list the available item names.

Inputs: item_name (required), adventure_session_id (required). Returns: health, message, inventory, adventure_session_id

useB

Use an inventory item or a stateful item present in the current scene.

Inputs: item_name (required), adventure_session_id (required). Returns: title, choices, context, message, +3 more

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.4/5.0

    Scored across 9 tools

    Disambiguation4/5

    Most tools map cleanly to distinct actions: starting, choosing, examining, looking, using, taking, dropping, hinting, and checking status. Minor overlap exists between look_around and examine since both inspect the current environment, but their intended purposes remain distinguishable.

    Naming Consistency4/5

    The naming pattern is mostly verb_noun with clear action-oriented names like begin_adventure, take_item, and drop_item. The bare verbs 'use' and 'examine' deviate slightly from the pattern, but they are still intuitive and readable.

    Tool Count5/5

    Nine tools is well-scoped for a gamebook server, covering the core interaction loop without unnecessary bloat. Each tool serves a clear gameplay purpose, and the count feels appropriate for the domain.

    Completeness4/5

    The tool set covers the core interactive fiction lifecycle: starting, choosing, looking, examining, using, taking, dropping, hinting, and status tracking. A minor gap is the lack of a dedicated way to refetch the current scene's available actions without beginning or choosing, which could leave agents stuck if context is lost.

    Maintenance

    ActivityStale
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      Enables playing a Workato-themed text-based RPG through MCP tools, allowing users to explore dungeons, battle enemies, and manage character progression in an integration-themed adventure.
      15
      1
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables LLM-driven text game state management by exposing MCP tools for managing players, locations, items, entities, and abstract concepts.
      MIT
    • F
      license
      A
      quality
      C
      maintenance
      A text-adventure interpreter as an MCP server. It enables the AI to act as the player, exploring, solving puzzles, fighting trolls, and collecting treasure through tool calls.
      5
      -
    • A
      license
      Not graded
      quality
      C
      maintenance
      MCP server that enables AI agents to create, edit, validate, and export single-file HTML text adventure games using JSON story data and MCP tools.
      8 npm
      MIT