---
name: bookstack-documentation
description: Use when completing any significant work — deploying services, fixing cluster issues, writing runbooks, finishing brainstorming sessions, or making architectural decisions — to determine whether and where to save it to BookStack at https://wiki.ctz.fyi
---

# BookStack Documentation

## Overview

Save durable knowledge to BookStack as part of normal work — not just specs and plans, but ops runbooks, architecture notes, troubleshooting outcomes, and session results. If future-you would need to look it up, write it down.

**Instance:** https://wiki.ctz.fyi (BookStack v26.03.5)
**MCP tools:** `litellm_bookstack-*`

## Decision Table — Where Does This Go?

| Content type | Location |
|---|---|
| Design spec (from brainstorming) | Specs book (ID 157) |
| Implementation plan | Plans book (ID 159) |
| Architecture decision / how a system works | Ansiblestack book (ID 79), find or create page |
| Ops runbook / "how to do X on the cluster" | Ansiblestack book, `playbook-reference` page or new dedicated page |
| Troubleshooting investigation outcome | Ansiblestack book, relevant service page (e.g., update `keycloak` page) |
| New service deployed | Ansiblestack book, create new page named after the service |
| Project-specific docs | New book in Infrastructure Docs shelf, or new chapter in Ansiblestack |

## Shelf and Book Structure

```
Shelf: Superpowers (ID 1)
  Book: Specs (ID 157)        — Design specs from brainstorming sessions
  Book: Plans (ID 159)        — Implementation plans

Shelf: Infrastructure Docs (ID 78)
  Book: Ansiblestack (ID 79)  — Cluster bootstrap, services, architecture docs
    Existing pages: INDEX, addons, applications, architecture, argocd-consolidation,
    cluster, crowdsec, dns, external-secrets, hacker-ethos, keycloak,
    litellm-qdrant-memory, mcp-servers, missing-services, monitoring,
    netbox, networking, openbao, pangolin-newt-troubleshooting,
    playbook-reference, playwright-mcp, rabbitmq, scripts, tandoor,
    terrakube, tofu

Shelf: Repo Documentation (ID 121)
  Various per-repo books

Book: touchscreen — Family Room Dashboard (ID 162)
```

## When to Save

- After brainstorming session completes → spec to Specs book
- After plan is written → plan to Plans book
- After deploying a new service → create/update service page in Ansiblestack
- After investigating and fixing a cluster issue → document fix on the relevant service page
- After writing a runbook or procedure → Ansiblestack `playbook-reference` or dedicated page
- After any architectural decision that isn't obvious from the code

## When NOT to Save

- Temporary debug output or scratch work
- Q&A that belongs in chat history
- Anything immediately obsolete

## Page Naming Conventions

| Type | Format |
|---|---|
| Specs | `[Spec] YYYY-MM-DD: <topic>` |
| Plans | `[Plan] YYYY-MM-DD: <feature name>` |
| Service pages | lowercase service name (e.g., `rabbitmq`) |
| Runbooks | descriptive verb phrase: `Rotating OpenBao Unseal Keys` |

## Page Format (Markdown)

For service pages, use this structure:

```markdown
# Service Name

**Status:** Running / Deprecated
**Namespace:** `<ns>`
**URL:** https://<hostname>
**Chart:** `helm/charts/<name>/`
**ArgoCD App:** `helm/argocd/<name>-app.yaml`
**Secrets:** OpenBao path `secret/production/<ns>/...`

## Overview
What it is and why we run it.

## Architecture
How it's deployed, what it depends on.

## Configuration
Key config decisions, non-obvious settings.

## Operations
### How to restart
### How to update
### Common issues
```

For runbooks and procedures, use a clear numbered steps format. For troubleshooting outcomes, document: symptoms → investigation → root cause → fix.

## MCP Usage

```python
# Find an existing page (search or list book contents)
bookstack_books_read(id=79)  # lists pages in Ansiblestack

# Create a new page
bookstack_pages_create(
    book_id=79,
    name="my-service",
    markdown="# My Service\n..."
)

# Update existing page — ALWAYS read first, updates replace entire content
page = bookstack_pages_read(id=<page_id>)
bookstack_pages_update(
    id=<page_id>,
    markdown="<updated full content>"
)
```

**Always read before updating.** `bookstack_pages_update` replaces the entire page.
