Skip to main content

2 posts tagged with "mkdocs"

View All Tags

Building the Arbiter-Bot Documentation Site

· 2 min read
Antigravity
Arbiter Bot Project
Claude
AI Assistant

How we chose MkDocs Material for our documentation platform and what we learned implementing it.

Context

The arbiter-bot project accumulated significant documentation over its development:

  • Architecture Decision Records (ADRs)
  • Functional Requirements Specification
  • Implementation plans
  • Design reviews
  • Traceability ledger

All of this existed as raw markdown files without unified navigation, search, or public accessibility. More critically, our CLAUDE.md workflow mandates a blog post for each change—and we had no blog infrastructure.

Decision

We evaluated four alternatives:

AlternativeVerdict
MkDocs MaterialSelected
mdBookRejected (no blog plugin)
DocusaurusRejected (heavier Node.js dependency)
GitHub WikiRejected (limited navigation)

Primary driver: Organization alignment with amiable-templates.dev, which already uses MkDocs Material, enabling shared patterns and developer familiarity.

Implementation

Site Structure

We organized content into logical sections:

docs/
├── getting-started/ # Installation, config, first run
├── architecture/ # Actor model, saga pattern, clients
├── spec/ # Requirements specification
├── adrs/ # Architecture decisions
├── development/ # TDD, council review, contributing
├── reference/ # CLI and environment reference
├── blog/ # Engineering blog (this post!)
└── reviews/ # Council review documents

Content Migration

Existing documentation was reorganized:

  • implementation.mdarchitecture/index.md
  • ledger.mddevelopment/ledger.md
  • *_plan.mddevelopment/plans/

Key Configuration

The mkdocs.yml enables Material theme features matching our reference site:

theme:
name: material
features:
- navigation.tabs
- navigation.instant
- search.suggest
- content.code.copy

plugins:
- blog
- git-revision-date-localized

Security Considerations

Before publishing, we implemented a content review checklist:

  • No API keys or credentials in examples
  • No production wallet addresses
  • CLI examples use placeholder values
  • Architecture diagrams reviewed for sensitive details

Verification

  1. Local build: mkdocs build --strict passes
  2. Local preview: mkdocs serve renders correctly
  3. Deployment: GitHub Actions workflow deploys to Pages
  4. Council review: ADR-003 reviewed with reasoning tier (85% confidence)

Lessons Learned

  1. Migration planning matters - Document where files move before restructuring
  2. Security first - Public docs require content review before publishing
  3. Blog plugin configuration - The Material blog plugin needs explicit category allowlisting

The site is now live at amiable-dev.github.io/arbiter-bot.

Choosing MkDocs Material: ADR-002 Site Architecture

· 4 min read
Amiable Dev
Project Contributors

Why we chose MkDocs Material over Docusaurus or a custom solution, and how we structured the site.

The Problem

We needed a documentation site that could showcase templates in a scannable, attractive format. The site also needed to aggregate documentation from multiple template repositories, provide excellent search, support dark/light mode for accessibility, and be easy for contributors to work with.

Three options emerged: MkDocs Material, Docusaurus, or a custom Next.js/Astro site.

Why MkDocs Material?

CriteriaMkDocs MaterialDocusaurusCustom
Stack alignmentPython (matches scripts)React/NodeVaries
Setup timeHoursHoursDays/Weeks
MaintenanceLowMediumHigh
SearchBuilt-in (lunr.js)Algolia neededBuild it
Dark modeBuilt-inBuilt-inBuild it

Why not Docusaurus? It's a great framework, and we use it in our own blog amiable.dev but it would introduce React/Node into a Python-focused project. Our aggregation scripts are Python, and having a consistent stack reduces cognitive load.

Why not custom? A Next.js or Astro site would give us full control, but it's overkill for documentation. We'd spend weeks building what MkDocs Material gives us out of the box.

The deciding factor: consistency. Our llm-council docs already use MkDocs Material. Same tooling, same patterns, same contributor experience.

The Architecture

docs/
├── index.md # Hero + featured templates
├── quickstart.md # Prominent, top-level
├── templates/ # Template grid + aggregated docs
├── adrs/ # Architecture decisions
├── blog/ # You're reading it
└── stylesheets/
└── extra.css # Hero + grid styling

We use top-level tabs for main sections:

nav:
- Home: index.md
- Quick Start: quickstart.md
- Templates: templates/index.md
- ADRs: adrs/index.md
- Contributing: contributing.md
- Blog: blog/index.md

Quick Start gets its own tab because that's what most visitors want.

The Template Grid

We wanted a scannable grid of template cards without any JavaScript complexity. Here's how we built it using pure markdown with custom CSS:

<div class="template-grid" markdown="1">

<div class="template-card" markdown="1">

### LiteLLM + Langfuse Starter

Production-ready LLM proxy with observability.

**Features:**
- 100+ LLM providers via LiteLLM
- Request tracing with Langfuse
- Cost tracking and analytics

**Estimated Cost:** ~$29-68/month

[:octicons-rocket-16: Deploy](https://railway.app/template/...)
[:octicons-mark-github-16: Source](https://github.com/amiable-dev/litellm-langfuse-railway)

</div>

<div class="template-card" markdown="1">

### Another Template

Description here...

</div>

</div>

The markdown attribute is key—it tells MkDocs Material to process the markdown inside the HTML divs.

The CSS does the heavy lifting:

.template-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: 1.5rem;
}

.template-card {
border: 1px solid var(--md-default-fg-color--lightest);
border-radius: 0.5rem;
padding: 1.5rem;
}

.template-card:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
transform: translateY(-2px);
}

No framework needed. Pure CSS grid with markdown content.

Dark Mode

MkDocs Material handles dark mode elegantly with palette configuration. Users get automatic detection based on their system preference, plus a toggle to override:

theme:
name: material
palette:
- media: "(prefers-color-scheme: light)"
scheme: default
primary: deep purple
accent: deep purple
toggle:
icon: material/brightness-7
name: Switch to dark mode
- media: "(prefers-color-scheme: dark)"
scheme: slate
primary: deep purple
accent: deep purple
toggle:
icon: material/brightness-4
name: Switch to light mode

The toggle icon appears in the header. No JavaScript to write, no state to manage—it just works.

What We Learned

  1. Start with constraints: "No JavaScript" forced simpler, more maintainable solutions
  2. Reuse organizational patterns: Same theme as llm-council = less cognitive load
  3. Put Quick Start first: Most visitors want to deploy, not read architecture docs

What's Next

  • ADR-003: Template configuration system (templates.yaml)
  • ADR-006: Cross-project documentation aggregation

Links: