--- name: "Presenton" client: Open-source (presenton.ai) status: active tech: [Python 3.11, FastAPI, Next.js 14, SQLModel, python-pptx, OpenAI/Google/Anthropic LLMs, Docker] local_path: /Users/ai_leed/Documents/Projects/Oliver/presenton deploy: docker compose up production url: http://localhost:5000 tags: [oliver, presentation, ai, open-source] created: 2026-04-14 server: local port: 5000 db: SQLite --- ## Overview Presenton is an open-source, self-hosted AI presentation generator that transforms prompts, documents, or existing PPTX files into fully designed presentations (PPTX/PDF format). It supports multiple LLM providers (OpenAI, Google, Anthropic, Ollama, custom endpoints) and image providers (DALL-E, Gemini, Pexels, ComfyUI), includes a built-in MCP server for AI agent integration, and exposes a REST API for programmatic access. The project is production-ready, actively maintained, and Apache 2.0 licensed. ## Tech Stack - **Frontend:** Next.js 14 (App Router), React, Redux Toolkit, TypeScript - **Backend:** FastAPI (Python 3.11), SQLModel (ORM), uvicorn - **Database:** SQLite (default, can override with PostgreSQL/MySQL via `DATABASE_URL`) - **Infrastructure:** Docker (single container), nginx reverse proxy, LibreOffice (PDF export), Puppeteer/Chromium - **AI/ML:** OpenAI (GPT-4, DALL-E, GPT-Image-1.5), Google Gemini, Anthropic Claude, Ollama (local models), custom OpenAI-compatible endpoints - **Key libraries:** python-pptx (PPTX generation), docling/pdfplumber (document extraction), fastmcp (MCP server), Pillow (image processing) ## Architecture Presenton runs as a single Docker container with four coordinated processes spawned by `start.js`: - **nginx** (port 80) — reverse proxy and static file server - **FastAPI** (port 8000) — backend REST API and core logic - **Next.js** (port 3000) — frontend SSR - **MCP Server** (port 8001) — AI agent integration via Claude Desktop - **Ollama** (port 11434) — optional local LLM serving All processes are internally networked; external access is exclusively through nginx on port 80 (mapped to host port 5000). ### Presentation Generation Pipeline ``` User Input (prompt/files/PPTX) ↓ [Outline Generation] — LLM streams slide outlines (SSE) ↓ [Structure Assignment] — LLM assigns layout index per slide ↓ [Slide Content] — Batch of 10 slides: content generation ↓ [Asset Fetching] — Images fetched/generated concurrently per slide ↓ [Export] — python-pptx builds PPTX; LibreOffice converts to PDF ↓ [Webhook] — presentation.generation.completed event fired ``` ### Data Model - **PresentationModel** — metadata (title, template, status, content type) - **SlideModel[]** — per-slide content (outline, title, bullet points, speaker notes, layout index) - **ImageAsset[]** — images per slide (URL, provider, generation prompt, alt text) All persisted in SQLite at `/app_data/fastapi.db`. ## Dev Commands ### FastAPI Backend ```bash cd servers/fastapi # Install uv package manager pip install uv # Install dependencies uv sync # Run development server (requires APP_DATA_DIRECTORY env var) APP_DATA_DIRECTORY=./app_data uv run python server.py --port 8000 # Run tests uv run pytest # Lint/format uv run ruff check . ``` ### Next.js Frontend ```bash cd servers/nextjs # Install dependencies npm install # Dev mode with HMR (connects to FastAPI at localhost:8000) npm run dev # Production build npm run build npm run start # Lint npm run lint # E2E tests (Cypress) npx cypress open # interactive npx cypress run # headless ``` ### Full Stack (Docker) ```bash # Development with hot-reload docker compose up development # Production docker compose up production # GPU-accelerated (NVIDIA) docker compose up production-gpu # View logs docker compose logs -f production # Stop and clean up docker compose down ``` ## Deployment - **Server:** Local (self-hosted) - **Deploy:** `docker compose up production` or `docker run -it --name presenton -p 5000:80 [env vars] ghcr.io/presenton/presenton:latest` - **URL:** `http://localhost:5000` - **Port:** 5000 (host) → 80 (container) - **Service:** None (container-based) - **Local path:** `/Users/ai_leed/Documents/Projects/Oliver/presenton` - **Image:** `ghcr.io/presenton/presenton:latest` - **Base:** `python:3.11-slim-bookworm` - **Persistent volume:** `./app_data → /app_data` ### Quick Start ```bash git clone https://github.com/presenton/presenton.git cd presenton docker run -it --name presenton -p 5000:80 \ -e LLM="openai" \ -e OPENAI_API_KEY="sk-..." \ -e IMAGE_PROVIDER="dall-e-3" \ -v "./app_data:/app_data" \ ghcr.io/presenton/presenton:latest # Open http://localhost:5000 ``` ## Environment Variables **LLM Configuration:** - `LLM` — Provider: `openai`, `google`, `anthropic`, `ollama`, `custom` - `OPENAI_API_KEY` — OpenAI API key (required for OpenAI LLM or DALL-E/GPT-Image) - `OPENAI_MODEL` — Model ID (default: `gpt-4-1`) - `GOOGLE_API_KEY` — Google API key (Gemini LLM or image generation) - `GOOGLE_MODEL` — Gemini model ID (default: `models/gemini-2.0-flash`) - `ANTHROPIC_API_KEY` — Claude API key - `ANTHROPIC_MODEL` — Claude model ID (default: `claude-3-5-sonnet-20241022`) - `OLLAMA_URL` — Ollama server (default: `http://localhost:11434`) - `OLLAMA_MODEL` — Model to use (e.g., `llama3.2:3b`) - `CUSTOM_LLM_URL` — OpenAI-compatible endpoint URL - `CUSTOM_LLM_API_KEY` — API key for custom endpoint - `CUSTOM_MODEL` — Model ID for custom endpoint - `TOOL_CALLS` — Use tool calls for structured output (default: `false`) - `DISABLE_THINKING` — Disable chain-of-thought (default: `false`) - `EXTENDED_REASONING` — Enable extended reasoning (default: empty) - `WEB_GROUNDING` — Enable LLM web search (default: `false`) **Image Provider Configuration:** - `IMAGE_PROVIDER` — Provider: `dall-e-3`, `gpt-image-1.5`, `gemini`, `pexels`, `pixabay`, `comfyui` - `PEXELS_API_KEY` — Pexels API key - `PIXABAY_API_KEY` — Pixabay API key - `COMFYUI_URL` — ComfyUI server URL (for local image generation) - `COMFYUI_WORKFLOW` — ComfyUI workflow JSON path **Data & Infrastructure:** - `APP_DATA_DIRECTORY` — Root for persistent data (default: `/app_data`) - `TEMP_DIRECTORY` — Temp file staging (default: `/tmp/presenton`) - `DATABASE_URL` — Override SQLite; use `postgresql://` or `mysql://` for other DBs - `PUPPETEER_EXECUTABLE_PATH` — Chromium path (default: `/usr/bin/chromium`) - `CAN_CHANGE_KEYS` — Allow UI to modify API keys (default: `true`) ## API / Endpoints **REST API Base:** `http://localhost:5000/api/v1/` **Key Endpoints:** - `POST /ppt/presentation/generate` — Generate presentation (sync, returns PPTX/PDF path) - `POST /ppt/presentation/create` — Save new presentation (returns ID) - `GET /ppt/outlines/stream/{id}` — Stream outline JSON (SSE) - `POST /ppt/presentation/prepare` — Assign layouts and structure - `GET /ppt/presentation/stream/{id}` — Stream slide content (SSE) - `POST /ppt/presentation/export` — Export to PPTX or PDF - `POST /ppt/pptx-slides/process` — Analyze uploaded PPTX (extract slides, fonts, XML) - `POST /ppt/slide-to-html/` — Convert PPTX slide to HTML **MCP Server:** - `http://localhost:5000/mcp` — FastMCP HTTP endpoint for Claude Desktop integration **Swagger UI:** `http://localhost:5000/docs` ## Known Issues - None explicitly documented in provided files. Refer to GitHub issues at https://github.com/presenton/presenton/issues ## Git - **Remote:** `https://github.com/presenton/presenton.git` - **Latest commits:** Recent work includes new templates refactor, MCP OpenAI spec fixes, Ukrainian language support, GPT-Image-1.5 integration, local ComfyUI image provider support, and NanoBanana integration - **License:** Apache 2.0 --- ## Additional Resources - **Architecture & Design:** See `docs/project/architecture.md` for detailed data flows and component interactions - ## Sessions ### 2026-04-14 – Project catalogued **Done:** Added to Obsidian second brain. --- ## Change Log | Date | Requested | Changed | Files | |------|-----------|---------|-------| | 2026-04-14 | Initial setup | Note created | — | ## Related - [[ppt-tool/PPT Tool DeckForge]]