Lectern docs

Everything you need to run Lectern, connect models, drive it from other agents and build on its API.

Overview

Lectern turns a prompt, plus spreadsheets, documents and links, into a finished presentation. It has two parts that share one engine:

The same engine is also an MCP server, so Claude Code, Codex, Cursor or Antigravity can make decks without the web app.

Quick start

You need Python 3.12+ with uv, and Node 20+ with pnpm.

git clone https://github.com/mrigankad/Lectern.git
cd Lectern

# 1. Backend · http://localhost:8000 (API docs at /docs)
cd server
uv sync
uv run uvicorn lectern.main:app --port 8000

# 2. Web app · http://localhost:3000 (in a second terminal)
cd web
pnpm install
pnpm dev

Open http://localhost:3000 and start a deck. With no keys, every agent uses the built-in offline provider: it writes a sensible deck from the prompt alone, with no network, so you can try the whole flow first.

pnpm dev:mock runs the web app on mock data with no backend at all, which is handy for UI work.

Connect a model

Open Connections and models in the sidebar, add a key and press Test. Then pick a preset (Best quality, Balanced, Lowest cost) or choose a provider and model for each agent.

ProviderHow it connects
Claude CodeUses your local claude login. No API key needed.
AnthropicANTHROPIC_API_KEY or a key saved in Connections.
OpenAI-compatibleOpenAI, OpenRouter, a LiteLLM gateway, Gemini, Groq, DeepSeek, Mistral and Ollama, all through one client with a base URL.
OfflineDeterministic, no network. The default, and what the tests use.

Keys are stored in your local database and the API never returns them. A role whose provider has no key falls back to offline.

How a deck is built

  1. Brief. POST /api/decks with a prompt and optional audience, goal, length and sources.
  2. Interview. The Strategist asks only the questions the brief leaves open. If audience, goal and length are already set, it skips straight to the outline.
  3. Outline. You edit and reorder the headlines, then approve. Nothing is built before approval.
  4. Build. Slides are built three at a time: Writer, Art Director, Renderer, then Critic. You can pause and resume.
  5. Review. A slide with a high or medium finding goes back to the Writer once and is checked again.
  6. Edit and export. Ask for changes in chat, edit directly, then export.

Every step is recorded as a run with a one-sentence summary, which feeds the live activity view.

The agents

AgentWhat it does
StrategistRuns the interview and drafts the storyline, with every headline written as a claim.
AnalystDeterministic. Computes figures from real cells in your sources, so every number traces back to a cell.
WriterFills headlines, body text, chart labels and speaker notes. If the brief can't fill a slide, it writes what still needs finding out instead of template text.
Art DirectorChooses one of 21 layouts, the chart type and the visuals.
RendererFits the content into the layout's slots on the canvas.
CriticDeterministic lint over every slide (see below).
EditorApplies chat requests to one slide or the whole deck.
ExporterWrites PPTX, PDF, PNG and notes, plus an editability report.

Your rules ("never use the word synergy", "always show currency in USD") are added to every agent prompt. A rule that bans a word is also enforced by the lint.

Scene graph

A slide is typed JSON: a layout id plus nodes (headline, text, bullets, stat, chart, table, image, quote). The placer turns it into a RenderedSlide on a 1920×1080 canvas. The web canvas, PowerPoint, PDF and PNG are all drawn from that one rendered form, so every format matches. The full schema is in docs/SPEC.md.

The Critic

The Critic runs without a model. Its rules:

Each slide starts at 100 and loses points by severity; the deck score is the mean, with Story, Design and Editability sub-scores. For each finding you can Fix it, or Keep it, which adds a rule so the Critic stops raising it.

Undo

Removed slides are not restored yet.

Data and charts

Attach spreadsheets, CSVs, documents or links as sources. Charts and stats link to sheet ranges. Refresh from sheet re-reads them and also rewrites matching figures in headlines, text and notes; anything it can't trace to a single changed cell is flagged for you.

Brand kits

Upload a .potx or .pptx (and optionally a brand PDF). Lectern reads the colour scheme, fonts, logos and layouts, builds a theme, and suggests rules the Critic checks. A branded deck's PowerPoint export is built on your template's master.

Images and video

ProviderSetup
HiggsfieldUses the Higgsfield CLI's own login. Test it under Connections to enable it. It bills credits.
Google Imagen and VeoGEMINI_API_KEY
OpenAI ImagesOPENAI_API_KEY
FLUX (fal.ai)FAL_KEY
RunwayRUNWAYML_API_SECRET
Stock (Pexels)PEXELS_API_KEY
Upload / offlineBuilt in. Offline draws flat placeholders in the deck colours.

Export

Every export comes with a report that counts editable objects, charts, tables and pictures. Urbanist isn't embedded in PPTX files, so a machine without the font shows a fallback; the PDF always looks right.

MCP server

Lectern runs as an MCP server in two ways, on the same engine and database:

Claude Code

claude mcp add lectern -- uv --directory "/path/to/Lectern/server" run lectern-mcp
# or, with the API running
claude mcp add --transport http lectern http://localhost:8000/mcp

Claude desktop, Cursor, Gemini CLI, Antigravity

{
  "mcpServers": {
    "lectern": {
      "command": "uv",
      "args": ["--directory", "/path/to/Lectern/server", "run", "lectern-mcp"]
    }
  }
}

Codex

# ~/.codex/config.toml
[mcp_servers.lectern]
command = "uv"
args = ["--directory", "/path/to/Lectern/server", "run", "lectern-mcp"]

The web app's Claude Code and agents page shows these with your machine's path filled in.

Tools

create_deck, get_interview, answer_interview, skip_interview, get_outline, update_outline, regenerate_outline, approve_outline, get_status, wait_until_ready, get_critic_report, fix_findings, ask, edit_slide, list_decks, export_deck. Resources: lectern://decks/{id} and lectern://decks/{id}/outline.

The outline stays a human decision. approve_outline is never called automatically. Clients should show the outline and wait for a yes. The HTTP endpoint accepts localhost only and has no authentication, so keep the API on localhost.

HTTP API

All routes are under /api and return JSON. Errors are an HTTP status plus { "detail": "..." } in plain language. Interactive docs are at http://localhost:8000/docs.

MethodPathPurpose
GET/healthHealth and active provider
GET · POST/decksList decks · create one (starts the outline)
GET · PATCH · DELETE/decks/{id}Read, rename or set icon, delete
PUT/decks/{id}/outlineEdit, reorder, add or remove outline slides
POST/decks/{id}/outline/regenerateRedraft, e.g. "make it shorter"
POST/decks/{id}/approve · /pause · /resumeStart, pause or resume the build
GET/decks/{id}/renderAll rendered slides
PATCH/decks/{id}/slides/{sid}Manual edit, re-linted
POST/decks/{id}/askA change in plain words, for a slide or the deck
POST/decks/{id}/slides/{sid}/undoSlide undo
POST/decks/{id}/messages/{mid}/undoAsk undo
GET/decks/{id}/criticScores and findings
POST/decks/{id}/critic/findings/{fid} · /critic/fix-allFix, keep or reopen findings
GET · POST · DELETE/rulesYour standing rules
POST/decks/{id}/exportpptx, pdf, images or notes
GET/files/{file_id}Download an export
GET/layoutsThe 21 layouts and their slots
GET · PUT/settings/connections · /settings/routingProviders, keys and model per agent
GET/decks/{id}/eventsServer-Sent Events

Events

GET /api/decks/{id}/events streams Server-Sent Events: deck.updated, outline.ready, slide.updated, run.updated (one plain sentence per agent step), message.updated, finding.updated, and a ping every 20 seconds.

Environment

VariableDefaultPurpose
LECTERN_DATA_DIRserver/dataDatabase and exported files
LECTERN_OFFLINE_DELAY0.6Seconds per offline step, so the live build has something to show
LECTERN_CORS_ORIGINShttp://localhost:3000Origins allowed to call the API
LECTERN_REFERENCES_DIR../referencesLayout and deck-type knowledge for the agents
LECTERN_FORCE_OFFLINEunset1 routes every agent to offline
LECTERN_WEB_URL, LECTERN_API_URL, LECTERN_MCP_URLlocalhostLinks returned by MCP tools
Provider keysunsetANTHROPIC_API_KEY, OPENAI_API_KEY, OPENROUTER_API_KEY, GEMINI_API_KEY and others. A key saved in the app takes precedence.

Repository

PathWhat it is
server/lectern/agentsStrategist, Writer, Art Director, Renderer, Critic, Editor and the pipeline
server/lectern/enginePlacement on the canvas and the lint rules
server/lectern/layoutsThe 21 layouts and their slots
server/lectern/exportPPTX, PDF, images, notes and the editability report
server/lectern/llm, mediaModel and media routers and providers
server/lectern/mcpThe MCP server
web/srcThe Next.js app
docs/SPEC.mdThe contract between backend and web app
references/Layout, deck-type and visual-design knowledge

Run the checks with cd server && uv run pytest (offline) and cd web && pnpm typecheck && pnpm lint.

Status

Lectern is early. Built and tested: the full flow from brief to export, chat edits and undo, the Critic, data sources, brand kits, share links, present mode and the MCP server. Not built yet: invite by email, comments, Google Slides export, restoring removed slides, and accounts. Paid image providers are wired in but need your own keys or credits.