# Explain It Simply: What Is Presenton?

> What this app does in one sentence, the simplest useful analogy, and the three ideas every reader should hold on to before diving deeper.

- Repository: presenton/presenton
- GitHub: https://github.com/presenton/presenton
- Human wiki: https://grok-wiki.com/public/wiki/presenton-presenton-f6685dc028cc
- Complete Markdown: https://grok-wiki.com/public/wiki/presenton-presenton-f6685dc028cc/llms-full.txt

## Source Files

- `README.md`
- `VISION.md`
- `docker-compose.yml`
- `start.js`
- `package.json`

---

<details>
<summary>Relevant source files</summary>
The following files were used as context for generating this wiki page:

- [README.md](README.md)
- [VISION.md](VISION.md)
- [docker-compose.yml](docker-compose.yml)
- [start.js](start.js)
- [servers/fastapi/api/v1/ppt/endpoints/presentation.py](servers/fastapi/api/v1/ppt/endpoints/presentation.py)
- [servers/fastapi/models/generate_presentation_request.py](servers/fastapi/models/generate_presentation_request.py)
- [servers/fastapi/enums/llm_provider.py](servers/fastapi/enums/llm_provider.py)
- [servers/fastapi/enums/image_provider.py](servers/fastapi/enums/image_provider.py)
- [servers/fastapi/mcp_server.py](servers/fastapi/mcp_server.py)
- [Dockerfile](Dockerfile)
</details>

# Explain It Simply: What Is Presenton?

This page gives a first-principles orientation to Presenton for anyone who just cloned the repo or stumbled across it. It answers the one-sentence question, offers the simplest analogy that holds up under inspection, and pins down the three ideas you must carry into every other page of this wiki.

Presenton is an **open-source, self-hosted AI presentation generator**: you give it text or documents, it calls an LLM and an image provider of your choice, and it hands you back a finished PowerPoint (or PDF) slide deck — all running on your own machine or server, with none of your data sent to a SaaS platform.

---

## The One-Sentence Summary

Presenton is a **bring-your-own-model (BYOM) document engine** that turns a prompt or uploaded file into a styled, exportable slide deck, and exposes the same workflow as a REST API, an MCP server, and a desktop app.

Sources: [README.md:18-34](), [VISION.md:1-17]()

---

## The Simplest Useful Analogy

Think of Presenton as a **smart print shop that you own**.

You bring the raw material — a topic sentence, a PDF report, a CSV of sales figures — and the shop turns it into a finished, designed document. But unlike a cloud print shop, this one runs entirely on your premises:

- You choose which printing press to use (OpenAI, Google Gemini, a local Ollama model, AWS Bedrock, Azure, Anthropic, Fireworks, Together AI, LM Studio, or any OpenAI-compatible endpoint).
- You choose the photo supplier for slide images (DALL-E 3, Gemini Flash, Pexels, Pixabay, ComfyUI, or Open WebUI).
- The finished product (a `.pptx` or `.pdf` file) belongs to you, stored in a volume you mount.
- You can swap press, designer, and template at any time without changing anything else.

The analogy maps directly to code: the `LLM` env variable picks the text press ([`servers/fastapi/enums/llm_provider.py:4-19`]()), the `IMAGE_PROVIDER` variable picks the photo supplier ([`servers/fastapi/enums/image_provider.py:4-13`]()), and the `template` field in the API request picks the design ([`servers/fastapi/models/generate_presentation_request.py:29-30`]()).

---

## The Three Ideas to Hold On To

### 1. Model-Agnostic by Design (BYOK / BYOM)

Presenton makes no assumptions about which AI provider you use. The `LLMProvider` enum lists 15 backends, from `openai` and `anthropic` to `ollama` and `custom` (any OpenAI-compatible URL):

```python
# servers/fastapi/enums/llm_provider.py:4-19
class LLMProvider(Enum):
    OLLAMA     = "ollama"
    OPENAI     = "openai"
    GOOGLE     = "google"
    VERTEX     = "vertex"
    AZURE      = "azure"
    BEDROCK    = "bedrock"
    OPENROUTER = "openrouter"
    FIREWORKS  = "fireworks"
    TOGETHER   = "together"
    CEREBRAS   = "cerebras"
    ANTHROPIC  = "anthropic"
    LITELLM    = "litellm"
    LMSTUDIO   = "lmstudio"
    CUSTOM     = "custom"
    CODEX      = "codex"
```

Image generation is equally flexible — nine providers are enumerated in `ImageProvider`, covering AI-generated images (DALL-E 3, Gemini Flash, ComfyUI) and stock photo APIs (Pexels, Pixabay) ([`servers/fastapi/enums/image_provider.py:4-13`]()). Switching providers is a one-line environment variable change with no code edits.

Sources: [servers/fastapi/enums/llm_provider.py:1-19](), [servers/fastapi/enums/image_provider.py:1-13]()

---

### 2. Three Layers Work Together Inside One Container

The runtime is not a monolith and not a microservice cluster — it is **three processes inside one container**, orchestrated by a single Node.js supervisor:

```text
┌───────────────────────────── Docker container (port 80) ──────────────────────────────┐
│                                                                                        │
│   nginx (reverse proxy, port 80)                                                       │
│       │                                                                                │
│       ├──► Next.js (port 3000)  ── UI + server-side API proxying                      │
│       │                                                                                │
│       └──► FastAPI (port 8000)  ── presentation logic, LLM calls, DB, export          │
│                                                                                        │
│   FastMCP (port 8001) ── MCP server, auto-generated from FastAPI's OpenAPI spec       │
│                                                                                        │
│   start.js ─ launches and supervises all three; exits when any process exits          │
└────────────────────────────────────────────────────────────────────────────────────────┘
         │
         └── ./app_data/  (mounted volume — presentations, exports, fonts, uploads)
```

`start.js` is the entrypoint. It writes `userConfig.json` from environment variables, ensures `app_data/` directories exist with correct permissions, starts nginx, spawns FastAPI (`python server.py --port 8000`) and Next.js in parallel, and waits for both readiness signals before printing the startup banner. If either process exits, the container exits ([`start.js:468-588`]()).

The MCP server (`mcp_server.py`) is generated automatically from the FastAPI OpenAPI spec using `FastMCP.from_openapi`, meaning any API endpoint is immediately accessible over the Model Context Protocol without a separate implementation ([`servers/fastapi/mcp_server.py:38-42`]()).

Sources: [start.js:28-44](), [start.js:468-588](), [servers/fastapi/mcp_server.py:14-57]()

---

### 3. A Structured Generation Pipeline, Not Just Prompt → File

Presenton does not simply dump a prompt into an LLM and parse the output as a slide deck. The generation endpoint chains multiple steps:

| Step | What happens | Key file |
|---|---|---|
| **Outline** | LLM generates a structured outline (title, sections, per-slide bullet points) | `utils/llm_calls/generate_presentation_outlines.py` |
| **Structure** | Outline is mapped to a concrete slide-layout index sequence | `utils/llm_calls/generate_presentation_structure.py` |
| **Slide content** | Each slide's content is generated from its outline item and layout type | `utils/llm_calls/generate_slide_content.py` |
| **Assets** | Images are fetched or generated per slide; icons are resolved | `utils/process_slides.py`, `services/image_generation_service.py` |
| **Export** | Final deck is rendered to PPTX or PDF | `utils/export_utils.py` |

The `GeneratePresentationRequest` model exposes the user-facing knobs for this pipeline: `content`, `n_slides`, `tone` (default/casual/professional/funny/educational/sales_pitch), `verbosity` (concise/standard/text-heavy), `web_search`, `language`, `template`, and `export_as` ([`servers/fastapi/models/generate_presentation_request.py:8-47`]()).

The same generation request is reachable over three surfaces simultaneously:

- **Web UI** — served by Next.js, calls FastAPI internally
- **REST API** — `POST /api/v1/ppt/presentation/generate` with HTTP Basic auth
- **MCP** — any MCP-compatible AI agent can call the same endpoint through `mcp_server.py`

Sources: [servers/fastapi/models/generate_presentation_request.py:8-47](), [servers/fastapi/api/v1/ppt/endpoints/presentation.py:1-80]()

---

## How the Pieces Fit: Architecture at a Glance

```mermaid
flowchart LR
    subgraph Input["Input surfaces"]
        Browser["Browser / Next.js UI"]
        API["REST API client"]
        MCPClient["MCP agent"]
    end

    subgraph Core["FastAPI backend (port 8000)"]
        PresentationEndpoint["/api/v1/ppt/presentation/generate"]
        OutlineGen["Outline generation"]
        StructureGen["Structure mapping"]
        SlideGen["Slide content generation"]
        ImageFetch["Image & icon resolution"]
        ExportUtil["PPTX / PDF export"]
    end

    subgraph Providers["External / local providers"]
        LLMProvider["LLM\n(OpenAI · Gemini · Ollama · Anthropic · …)"]
        ImgProvider["Image\n(DALL-E · Pexels · ComfyUI · …)"]
    end

    subgraph Storage["app_data volume"]
        DB["SQLite / Postgres DB"]
        Files["exports · images · fonts"]
    end

    Browser --> PresentationEndpoint
    API --> PresentationEndpoint
    MCPClient -->|"FastMCP port 8001"| PresentationEndpoint

    PresentationEndpoint --> OutlineGen --> StructureGen --> SlideGen --> ImageFetch --> ExportUtil
    OutlineGen & SlideGen --> LLMProvider
    ImageFetch --> ImgProvider
    ExportUtil --> Files
    PresentationEndpoint --> DB
```

Sources: [start.js:28-44](), [servers/fastapi/api/v1/ppt/endpoints/presentation.py:1-80](), [docker-compose.yml:1-14]()

---

## Deployment Shapes

Presenton ships in three mutually compatible forms:

| Form | Command / entry | Best for |
|---|---|---|
| **Docker** | `docker run … ghcr.io/presenton/presenton:latest` | Zero-dependency self-hosting |
| **Docker Compose** | `docker compose up production` | Team or cloud deployment with `.env` config |
| **Electron desktop app** | `npm run dev` in `electron/` | Local development, offline use |

In all three forms, the same `start.js` entrypoint runs the same FastAPI + Next.js + MCP stack. The Electron app simply embeds this stack inside a native desktop window ([README.md:161-191]()).

GPU support (for local Ollama models) is a single flag: `--gpus=all` on Docker, or `START_OLLAMA=true` to install Ollama at container startup ([docker-compose.yml:96-110]()).

Sources: [README.md:161-212](), [docker-compose.yml:96-110](), [start.js:268-277]()

---

## Summary

Presenton is an open-source, self-hosted AI presentation engine — a structured pipeline (outline → layout → content → images → export) wrapped in a web UI, REST API, and MCP server, all running inside a single Docker container. Its defining commitment is provider neutrality: any LLM and any image backend can be swapped by changing one environment variable, with no code changes and no data leaving your infrastructure. Every other concept in this wiki — templates, memory, chat editing, export formats, authentication — is built on top of these three pillars: model-agnosticism, a three-process runtime, and a multi-step structured generation pipeline.

Sources: [VISION.md:3-17](), [servers/fastapi/enums/llm_provider.py:4-19]()
