Skip to main content
Glama

HNPX SDK

A collection of tools for HNPX - a hierarchical XML-based format for planning and writing fiction. This project introduces the HNPX format and provides tools for creating, editing, and managing HNPX documents.

Origin

LLMs can't write a good story. Well, technically they can write a good story: they'll generate thousands of words that follow narrative conventions. But they can't write your story, the specific story only you have in mind. That gap between "AI can write fiction" and "AI can't write the fiction I want" is the core of the workflow described below.

Ask an LLM to write a whole chapter, and it'll speedrun through the plot in about 300 words. Try going paragraph by paragraph, and you'll find the AI doesn't know when to stop one scene and start the next.

This led to experimenting with hierarchy: first generating a detailed chapter plan with sections, then asking the LLM to write each section individually based on that plan. This approach improved structure and word count: the chapter speedrun problem was less severe, and scene boundaries were clearer. This hierarchical method required automation, which I implemented through simple Python scripts. However, a fully automated process without guidance led the LLM to write nonsense, not at all what I wanted. The text became filled with errors, and the problem was even more pronounced when writing in Russian, where general LLMs produce noticeably poorer text quality.

The solution evolved into HNPX, a narrative planning format that structures the writing process from book-level overview down to atomic paragraphs. It allows for step-by-step expansion, maintaining context and control at each level while keeping human guidance central to the process.

To bring HNPX to life, I considered building a custom UI or VS Code extension, but that would have been too difficult: creating a whole AI agent system from scratch. Instead, I realized Roo Code already provided the perfect foundation. Its flexible mode system meant I could build an MCP server and create custom modes to use it, creating exactly the workflow HNPX required. HNPX structures the writing process so that LLMs write under human guidance at each step, transforming them from autonomous storytellers into responsive collaborators.

TL;DR: HNPX defines a structured writing workflow where LLMs write under human direction at each level, turning AI from an autonomous storyteller into a guided collaborator.

Related MCP server: novel-mcp

What is HNPX?

HNPX (Hierarchical Narrative Planning XML) is a structured XML format designed for planning and writing fiction. It organizes narrative content into a strict hierarchy from book-level overview down to individual paragraphs, enabling a step-by-step expansion approach that maintains context and control throughout the writing process. See docs/HNPX.md for a full specification.

The format supports both high-level planning (summaries without full text) and complete documentation (full prose ready for rendering), making it flexible for writers at any stage of their creative process.

See this file as an example of an HNPX document.

Features

  • MCP Server: Model Context Protocol server for AI agent integration

  • CLI Tools: Command-line interface for some tasks

  • Roo Code Integration: Custom modes for collaborative fiction writing

    • HNPX Editor Mode: Interactive mode for creating and editing hierarchical narrative documents

    • Bible Writer Mode: Specialized mode for creating fiction reference documents

MCP Tools

The HNPX SDK provides a comprehensive set of MCP (Model Context Protocol) tools that enable AI agents to fully manipulate HNPX documents, from creating new documents to editing individual paragraphs and restructuring the narrative hierarchy. See docs/mcp-tools.md for complete documentation.

Installation

Install the HNPX SDK:

pip install -e .
# or via uv
uv pip install -e .

Roo Code Modes Setup

To use the custom Roo Code modes for HNPX editing, place .roomodes into your project root:

Available Tools

19 tools
create_beatC

Create a new beat element

Args: file_path (str): Path to the HNPX document parent_id (str): ID of the parent sequence element summary (str): Beat summary text

Inputs: file_path (required), parent_id (required), summary (required). Returns: result

create_chapterB

Create a new chapter element

Args: file_path (str): Path to the HNPX document parent_id (str): ID of the parent book element title (str): Chapter title summary (str): Chapter summary text pov (Optional[str]): Point-of-view character identifier

Inputs: file_path (required), parent_id (required), title (required), summary (required), +1 more. Returns: result

create_documentB

Create a new empty HNPX document

Args: file_path (str): Path where the new HNPX document will be created

Inputs: file_path (required). Returns: result

create_paragraphB

Create a new paragraph element

Args: file_path (str): Path to the HNPX document parent_id (str): ID of the parent beat element text (str): Paragraph text content mode (str): Narrative mode - one of: "narration" (default), "dialogue", "internal" char (Optional[str]): Character identifier (required when mode="dialogue")

Inputs: file_path (required), parent_id (required), text (required), mode, +1 more. Returns: result

create_sequenceB

Create a new sequence element

Args: file_path (str): Path to the HNPX document parent_id (str): ID of the parent chapter element location (str): Location description summary (str): Sequence summary text time (Optional[str]): Time indicator (e.g., "night", "next day", "flashback") pov (Optional[str]): Point-of-view character identifier

Inputs: file_path (required), parent_id (required), location (required), summary (required), +2 more. Returns: result

edit_node_attributesC

Modify attributes of an existing node

Args: file_path (str): Path to the HNPX document node_id (str): ID of the node to modify attributes (dict): Dictionary of attribute names and values to update

Inputs: file_path (required), node_id (required), attributes (required). Returns: result

edit_paragraph_textC

Edit paragraph text content

Args: file_path (str): Path to the HNPX document node_id (str): ID of the paragraph node to modify new_text (str): New paragraph text content

Inputs: file_path (required), paragraph_id (required), new_text (required). Returns: result

edit_summaryC

Edit summary text of a node

Args: file_path (str): Path to the HNPX document node_id (str): ID of the node containing the summary new_summary (str): New summary text content

Inputs: file_path (required), node_id (required), new_summary (required). Returns: result

get_childrenA

Retrieve immediate child nodes of a specified parent

Args: file_path (str): Path to the HNPX document node_id (str): ID of the parent node

Returns: str: Concatenated XML representation of all direct child nodes

Inputs: file_path (required), node_id (required). Returns: result

get_emptyA

Find next container node without children within a specific node's subtree (BFS order)

Args: file_path (str): Path to the HNPX document node_id (str): ID of the node to search within

Returns: str: XML representation of the next empty container node or a message if none found

Inputs: file_path (required), node_id (required). Returns: result

get_nodeA

Retrieve XML representation of a specific node (without descendants)

Args: file_path (str): Path to the HNPX document node_id (str): ID of the node to retrieve

Returns: str: XML representation of the node with its attributes and summary child only

Inputs: file_path (required), node_id (required). Returns: result

get_pathA

Return hierarchical path from document root to specified node

Args: file_path (str): Path to the HNPX document node_id (str): ID of the target node

Returns: str: Concatenated XML representation of all nodes in the path from root to target

Inputs: file_path (required), node_id (required). Returns: result

get_root_idB

Get ID of the book node (document root)

Args: file_path (str): Path to the HNPX document

Returns: str: ID of the book node

Inputs: file_path (required). Returns: result

get_subtreeA

Retrieve XML representation of node including all descendants, optionally pruned

Args: file_path (str): Path to the HNPX document node_id (str): ID of the node to retrieve pruning_level (str): Depth level - one of: "book", "chapter", "sequence", "beat", "full"

Returns: str: XML representation of the node and its descendants, pruned to specified depth

Inputs: file_path (required), node_id (required), pruning_level. Returns: result

move_nodesC

Move multiple nodes between parents

Args: file_path (str): Path to the HNPX document node_ids (list): List of node IDs to move new_parent_id (str): ID of the new parent node

Inputs: file_path (required), node_ids (required), new_parent_id (required). Returns: result

remove_node_childrenC

Remove all children of a node

Args: file_path (str): Path to the HNPX document node_id (str): ID of the parent node

Inputs: file_path (required), node_id (required). Returns: result

remove_nodesA

Permanently remove multiple nodes and all their descendants

Args: file_path (str): Path to the HNPX document node_ids (list): List of node IDs to remove

Inputs: file_path (required), node_ids (required). Returns: result

render_nodeB

Render text representation of the node (only descendent paragraphs)

Args: file_path (str): Path to the HNPX document node_id (str): ID of the node to render show_ids (bool): Whether to show paragraph IDs in square brackets show_markers (bool): Whether to mark chapter/sequence beginnings

Returns: str: Formatted text representation the node

Inputs: file_path (required), node_id (required), show_ids, show_markers. Returns: result

reorder_childrenC

Reorganize the order of child elements

Args: file_path (str): Path to the HNPX document parent_id (str): ID of the parent node child_ids (list): List of child IDs in the desired order

Inputs: file_path (required), parent_id (required), child_ids (required). Returns: result

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 19 tools

    Disambiguation4/5

    Most tools have distinct purposes, but there is some potential for confusion between edit_node_attributes, edit_paragraph_text, and edit_summary, as they all modify node attributes or content. However, their specific targets (general attributes, paragraph text, summary text) are clarified in descriptions, preventing major misselection.

    Naming Consistency5/5

    Tool names follow a highly consistent verb_noun pattern throughout, such as create_beat, edit_node_attributes, get_children, remove_nodes, and reorder_children. This predictability makes it easy for agents to understand and use the toolset without confusion from mixed conventions.

    Tool Count4/5

    With 19 tools, the count is slightly high but reasonable for a document editing and management SDK, covering creation, retrieval, editing, and organization of hierarchical elements. It might feel a bit heavy, but each tool appears to serve a specific function in the domain.

    Completeness5/5

    The toolset provides comprehensive coverage for HNPX document manipulation, including full CRUD operations (create, read via get tools, update via edit tools, delete via remove tools), hierarchical management (move, reorder), and rendering. No obvious gaps are present for the stated purpose of SDK operations.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables local-first book writing with AI assistance, allowing users to scaffold, create, search, validate, and enrich a book repository through natural language using OpenCode or Claude.
      MIT
    • A
      license
      A
      quality
      C
      maintenance
      Enables AI tools to collaboratively write novels by managing chapters, characters, and story state through commands like validate, context, draft, review, and approve.
      8
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables AI-driven long-form novel creation and management, including chapter generation, character and timeline tracking, semantic memory retrieval, version savepoints, and deep consistency checking across multiple projects through MCP tools, with support for local LM Studio or any OpenAI-compatible API.
      16
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Exposes 30+ novel-writing tools over stdio or HTTP so external agents such as Claude Code or WorkBuddy can use their own models and API keys to read chapters, write prose, manage characters, foreshadowing, story arcs and worldbuilding, run local semantic search, and launch review sub-agents. Supports one-click enabling with configurable port, token, and approval mode.
      AGPL 3.0