Skip to content

Feature: update_chapter tool and priority support for content ordering #12

Description

@scocchiarella

Summary

Two gaps prevent the MCP from controlling content order within a book:

  1. update_page doesn't expose priority — only name, html, markdown, book_id, chapter_id are passed through
  2. There is no update_chapter tool — chapters can be created and deleted but not renamed, reordered, or moved

BookStack displays book contents in priority order (chapters and top-level pages interleaved), so without priority access the MCP can build a book but can't control or fix its table of contents.

BookStack API support (verified against development branch)

Both PUT endpoints accept priority as an optional integer:

PUT /api/pages/{id} — already used by update_page, just needs priority added to the passthrough:

'priority' => ['integer'],

PUT /api/chapters/{id} — not currently exposed as a tool:

'name'                => ['string', 'min:1', 'max:255'],
'description'         => ['string', 'max:1900'],
'description_html'    => ['string', 'max:2000'],
'tags'                => ['array'],
'priority'            => ['integer'],
'book_id'             => ['integer'],   // moves chapter to another book
'default_template_id' => ['nullable', 'integer'],

There is no dedicated bulk "sort book" API endpoint — the UI's drag-and-drop uses an internal web route. Per-item priority via PUT is the supported API mechanism.

Proposed changes

1. update_page: add optional priority (integer, min 0)

Just add it to the input schema and pass it through — updatePage in the client already forwards the data object to axios unchanged.

2. New tool: update_chapter

Inputs:
  id: number (required)
  name: string (optional) — rename the chapter
  description: string (optional) — max 1900 chars
  priority: number (optional) — sort order within the book (lower = earlier)
  book_id: number (optional) — move chapter to another book
  tags: array (optional)

This also fixes the unrelated gap that chapters currently can't be renamed or have their description edited via MCP.

3. Client method: updateChapter(id, data)

Same pattern as updatePage:

async updateChapter(id, data) {
    if (!this.enableWrite) throw new Error('Write operations are disabled...');
    const response = await this.client.put(`/chapters/${id}`, data);
    return await this.enhanceChapterResponse(response.data);
}

Use case

We had a book where the chapter/page order didn't match the source document. Without priority access, the only fix was manual drag-and-drop in the BookStack UI. With these changes, the model can reorder an entire book's table of contents in a few tool calls.

We've implemented this in our fork and it's working. Happy to PR if you'd like.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions