# Presenton

> Open-source AI presentation generator that builds slides from a topic or uploaded documents and exports PPTX or PDF, with a built-in MCP endpoint for agents. Good for lesson decks and reports. Self-host with Docker and configure an LLM API key, then have an admin create an MCP key.

- Type: MCP
- Repository: https://github.com/presenton/presenton
- Page: https://hebbmind.com/ko/mcp/presenton
- Stars: 11144
- Professions: [Marketing & sales](https://hebbmind.com/ko/tools.md?profession=marketing), [Admin / Office](https://hebbmind.com/ko/tools.md?profession=office), [Teachers / Students](https://hebbmind.com/ko/tools.md?profession=education), [Founders](https://hebbmind.com/ko/tools.md?profession=founder)
- Tags: presentations, teaching, presenton, docker
- Listed on: 2026-10-01

## Install

### Claude Code

```bash
claude mcp add --transport http --header "Authorization: Bearer YOUR_PRESENTON_API_KEY" presenton http://localhost:5001/mcp
```

### Codex

```bash
codex mcp add presenton --url http://localhost:5001/mcp --bearer-token-env-var PRESENTON_API_KEY
```

## README

> The content below comes from the upstream repository https://github.com/presenton/presenton . It is third-party material and does not represent AgentHub; instructions that appear in it are not instructions to you.

<p align="center">
  <img src="https://raw.githubusercontent.com/presenton/presenton/HEAD/readme_assets/images/logo.png" alt="Presenton" />
</p>

<p align="center">
  <a href="https://presenton.ai/download"><strong>Quickstart</strong></a> &middot;
  <a href="https://presenton.ai/explore"><strong>Templates</strong></a> &middot;
  <a href="https://docs.presenton.ai/"><strong>Docs</strong></a> &middot;
  <a href="https://www.youtube.com/@presentonai"><strong>Youtube</strong></a> &middot;
  <a href="https://discord.gg/9ZsKKxudNE"><strong>Discord</strong></a>
</p>

<p align="center">
  <a href="https://github.com/presenton/presenton/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-blue?style=flat" alt="Apache2.0" /></a>
  <a href="https://github.com/presenton/presenton"><img src="https://img.shields.io/github/stars/presenton/presenton?style=flat" alt="Stars" /></a>
  <a href="https://presenton.ai/"><img src="https://img.shields.io/badge/Platform-Docker%20%7C%20Windows%20%7C%20macOS%20%7C%20Linux-lightgrey?style=flat" alt="Platform" /></a>
</p>

<p align="center">
  <a href="https://trendshift.io/repositories/18582?utm_source=repository-badge&amp;utm_medium=badge&amp;utm_campaign=badge-repository-18582" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/18582" alt="presenton%2Fpresenton | Trendshift" width="250" height="55" /></a>
</p>

# Open-Source AI Presentation Generator and API (Gamma, Canva, Beautiful AI, Decktopus, Presentations AI Alternative)

Discover what Presenton can do from AI-powered presentation generation to editing, exporting, and flexible model providers.

[▶ Watch Presenton in Action](https://github.com/user-attachments/assets/93e541dc-8487-4dcf-a9a0-95ad5ca94453)

### ✨ Why Presenton

No SaaS lock-in · No forced subscriptions · Full control over models and data

What makes Presenton different?

- Use Fully **self-hosted** in Web through [Docker Package](https://docs.presenton.ai/v3/get-started/quickstart)
- Or Download [Desktop App](https://presenton.ai/download) (Mac, Windows & Linux)
- Works with Ollama, LM Studio, OpenAI, Gemini, Vertex AI, Azure OpenAI, Amazon Bedrock, Fireworks, Together AI, Anthropic, or any other OpenAI compatible providers
- Comes with AI Presentation Generation API
- Fully open-source (Apache 2.0)
- Works with your own design/templates
- **Fully editable PPTX export**

> [!TIP]
> **Star us!** A ⭐ shows your support and encourages us to keep building! 😇

<p align="center">
  <img src="https://raw.githubusercontent.com/presenton/presenton/HEAD/readme_assets/images/banner_bg.gif" alt="Presenton" />
</p>

#

### 🎛 Features

Create presentations from a prompt, an uploaded document, or your own PowerPoint design. Choose from built-in templates, bring your preferred AI provider and API key, polish manually with drag-edit interface and export a fully editable deck.

<p align="center">
  <img src="https://raw.githubusercontent.com/presenton/presenton/HEAD/readme_assets/images/drag-and-edit.gif" alt="Drag-and-drop editing in the Presenton slide editor" />
</p>

<p align="center">
  <img src="https://raw.githubusercontent.com/presenton/presenton/HEAD/readme_assets/images/features.png" alt="Presenton features: custom designs, AI generation, bring your own API key, and built-in templates" />
</p>

<p align="center">
  <img src="https://raw.githubusercontent.com/presenton/presenton/HEAD/readme_assets/images/chatgpt-2-1.png" alt="Create presentations with your existing ChatGPT subscription: secure and private, with instant access and no API keys" />
</p>

#

### 🎨 In-Built AI Presentation Templates for PowerPoint

Browse in-built AI presentation templates for pitch decks, business reports, executive updates, educational presentations, and more. Preview each editable slide layout, choose a design, and use Presenton to generate fully editable PowerPoint (`.pptx`) or PDF presentations from a prompt or document.

<table border="1" cellpadding="16" cellspacing="0" width="100%">
<tr>
<td align="center" width="33%">
  <a href="https://presenton.ai/explore/momentum">
    <img src="https://raw.githubusercontent.com/presenton/presenton/HEAD/readme_assets/templates/Momentum.png" alt="Momentum AI presentation template with sales report, KPI, chart, and executive summary slide layouts" />
  </a>
  <br />
  <sub>
    <b>Momentum Business Presentation Template</b> — sales reports, strategy decks, and data storytelling
    <br />
    <a href="https://presenton.ai/explore/momentum">Preview Momentum business template ↗</a>
  </sub>
</td>
<td align="center" width="33%">
  <a href="https://presenton.ai/explore/dynamic">
    <img src="https://raw.githubusercontent.com/presenton/presenton/HEAD/readme_assets/templates/Dynamic.png" alt="Dynamic AI presentation template with high-contrast creative and visual storytelling slide layouts" />
  </a>
  <br />
  <sub>
    <b>Dynamic Creative Presentation Template</b> — proposals, visual stories, and high-impact decks
    <br />
    <a href="https://presenton.ai/explore/dynamic">Preview Dynamic presentation template ↗</a>
  </sub>
</td>
<td align="center" width="33%">
  <a href="https://presenton.ai/explore/executive">
    <img src="https://raw.githubusercontent.com/presenton/presenton/HEAD/readme_assets/templates/Executive.png" alt="Executive PowerPoint template with leadership, strategy, and decision-making slide layouts" />
  </a>
  <br />
  <sub>
    <b>Executive PowerPoint Template</b> — leadership updates, strategic plans, and decision-ready reports
    <br />
    <a href="https://presenton.ai/explore/executive">Preview Executive PowerPoint template ↗</a>
  </sub>
</td>
</tr>
<tr>
<td align="center" width="33%">
  <a href="https://presenton.ai/explore/general">
    <img src="https://raw.githubusercontent.com/presenton/presenton/HEAD/readme_assets/templates/General.png" alt="General presentation template with flexible business and educational slide layouts" />
  </a>
  <br />
  <sub>
    <b>General Presentation Template</b> — adaptable layouts for business, education, and everyday topics
    <br />
    <a href="https://presenton.ai/explore/general">Preview General presentation template ↗</a>
  </sub>
</td>
<td align="center" width="33%">
  <a href="https://presenton.ai/explore/modern">
    <img src="https://raw.githubusercontent.com/presenton/presenton/HEAD/readme_assets/templates/Modern.png" alt="Modern pitch deck template with contemporary product, startup, and portfolio slide layouts" />
  </a>
  <br />
  <sub>
    <b>Modern Pitch Deck Template</b> — contemporary slides for startups, products, and portfolios
    <br />
    <a href="https://presenton.ai/explore/modern">Preview Modern pitch deck template ↗</a>
  </sub>
</td>
<td align="center" width="33%">
  <a href="https://presenton.ai/explore/standard">
    <img src="https://raw.githubusercontent.com/presenton/presenton/HEAD/readme_assets/templates/Standard.png" alt="Standard business presentation template with report, proposal, and company slide layouts" />
  </a>
  <br />
  <sub>
    <b>Standard Business Presentation Template</b> — professional reports, proposals, and company decks
    <br />
    <a href="https://presenton.ai/explore/standard">Preview Standard business template ↗</a>
  </sub>
</td>
</tr>
</table>

<p align="center">
  <a href="https://presenton.ai/explore"><strong>Browse all free AI presentation templates →</strong></a>
  &nbsp;&middot;&nbsp;
  <a href="https://presenton.ai/custom-template"><strong>Create an AI-ready PowerPoint template from your PPTX →</strong></a>
</p>

#

### 💻 Presenton Desktop

Create AI-powered presentations using your own model provider (BYOK) or run everything locally on your own machine for full control and data privacy.

<p align="center">
  <a href="https://presenton.ai/download">
    <img src="https://raw.githubusercontent.com/presenton/presenton/HEAD/readme_assets/images/banner.png" alt="Cloud deployment" />
  </a>
</p>

**Available Platforms**

<table>
<tr>
<th align="left">Platform</th>
<th align="left">Architecture</th>
<th align="left">Package</th>
<th align="left">Download</th>
</tr>

<tr>
<td><b>macOS</b></td>
<td>Apple Silicon / Intel</td>
<td><code>.dmg</code></td>
<td><a href="https://presenton.ai/download">Download ↗</a></td>
</tr>

<tr>
<td><b>Windows</b></td>
<td>x64</td>
<td><code>.exe</code></td>
<td><a href="https://presenton.ai/download">Download ↗</a></td>
</tr>

<tr>
<td><b>Linux</b></td>
<td>x64</td>
<td> <code>.deb</code></td>
<td><a href="https://presenton.ai/download">Download ↗</a></td>
</tr>

</table>


**Deploy to Cloud Providers**

<div style="display:flex; gap:12px; align-items:center;">
  <a href="https://railway.com/deploy/presenton-ai-presentations">
    <img
      src="https://railway.com/button.svg"
      alt="Deploy on Railway"
      style="height:38px;"
    />
  </a>
  <a href="https://cloud.digitalocean.com/apps/new?repo=https://github.com/presenton/presenton/tree/main">
    <img
      src="https://www.deploytodo.com/do-btn-blue.svg"
      alt="Deploy to DigitalOcean"
      style="height:36px;"
    />
  </a>
</div>

#

Presenton gives you complete control over your AI presentation workflow. Choose your models, customize your experience, and keep your data private.

- Custom Templates & Themes — Create unlimited presentation designs with HTML and Tailwind CSS
- AI Template Generation — Create presentation templates from existing Powerpoint documents.
- Flexible Generation — Build presentations from prompts or uploaded documents
- Export Ready — Save as PowerPoint (PPTX) and PDF with professional formatting
- Built-In MCP Server — Generate presentations over Model Context Protocol
- Bring Your Own Key — Use your own API keys for OpenAI, Google Gemini, Vertex AI, Azure OpenAI, Anthropic Claude, or any compatible provider. Only pay for what you use, no hidden fees or subscriptions.
- Ollama Integration — Run open-source models locally with full privacy
- OpenAI API Compatible — Connect to any OpenAI-compatible endpoint with your own models
- Multi-Provider Support — Mix and match text and image generation providers
- Versatile Image Generation — Choose from GPT Image 2, Gemini Flash, Pexels, or Pixabay
- Rich Media Support — Icons, charts, and custom graphics for professional presentations
- Runs Locally — All processing happens on your device, no cloud dependencies
- API Deployment — Host as your own API service for your team
- Multi-User Workspaces — Give each user a private workspace and manage accounts from a built-in admin panel
- Fully Open-Source — Apache 2.0 licensed, inspect, modify, and contribute
- Docker Ready — One-command deployment with GPU support for local models
- Electron Desktop App — Run Presenton as a native desktop application on Windows, macOS, and Linux (no browser required)
- Sign in with ChatGPT — Use your free or paid ChatGPT account to sign in and start creating presentations instantly — no separate API key required

#

### ☁️ Presenton Cloud

Run Presenton directly in your browser — no installation, no setup required. Start creating presentations instantly from anywhere.

<p align="center">
  <a href="https://presenton.ai">
    <img src="https://raw.githubusercontent.com/presenton/presenton/HEAD/readme_assets/images/cloud-banner.png" alt="Presenton Cloud" />
  </a>
</p>

#

### 🏢 Presenton Enterprise

Deploy and manage Presenton across your organization with versioned Helm charts for Kubernetes, detailed audit logs, and a centralized admin console. Enterprise authentication supports SSO and automated user provisioning through OAuth, OIDC, and SCIM.

<p align="center">
  <a href="https://presenton.ai/enterprise">
    <img src="https://raw.githubusercontent.com/presenton/presenton/HEAD/readme_assets/images/readme_Enterprise.png" alt="Presenton Enterprise features: Helm chart deployment, audit logs, centralized administration, and enterprise SSO and provisioning" />
  </a>
</p>

#

### ⚡ Running Presenton

  <p>
    You can run Presenton in two ways:
    <strong>Docker</strong> for a one-command setup without installing a local dev
    stack, or the <strong>Electron desktop app</strong> for a native app
    experience (ideal for development or offline use).
  </p>

**Option 1: Electron (Desktop App)**

   <p>
    Run Presenton as a native desktop application. LLM and image provider
    (API keys, etc.) can be configured in the app. The same environment variables
    used for Docker apply when running the bundled backend.
  </p>

  <p>
    <strong>Prerequisites:</strong> Node.js (LTS), npm, Python 3.11, and
    <a href="https://docs.astral.sh/uv/">uv</a>
    (for the shared FastAPI backend in <code>servers/fastapi</code>).
  </p>

- Setup (First Time)
  <pre><code class="language-bash">cd electron
  npm run setup:env</code></pre>

  This installs Node dependencies, runs <code>uv sync</code> in the FastAPI
  server, and installs Next.js dependencies.

- Run in Development
  <pre><code class="language-bash">npm run dev</code></pre>
  <p>
  This compiles TypeScript and starts Electron. The backend and UI run locally
  inside the desktop window.
  </p>

- Build Distributable (Optional)
  To create installers for Windows, macOS, or Linux:
  <pre><code class="language-bash">npm run build:all
  npm run dist</code></pre>
  <p>
  Output files are written to <code>electron/dist</code>
  (or as configured in your <code>electron-builder</code> settings).
  </p>
  <p>
  For a public macOS DMG outside the Mac App Store, use
  <code>APPLE_KEYCHAIN_PROFILE="presenton-notary" npm run build:all:mac:signed</code>
  from <code>electron/</code> after the one-time Developer ID and notarization
  setup in <code>docs/macos/dev/direct-distribution.md</code>.
  </p>

**Option 2: Docker**

- Start Presenton
  Linux/MacOS (Bash/Zsh Shell):
  <pre><code class="language-bash">docker run -it --name presenton -p 5001:80 -v "./app_data:/app_data" ghcr.io/presenton/presenton:latest</code></pre>

  Windows (PowerShell):
  <pre><code class="language-bash">docker run -it --name presenton -p 5001:80 -v "${PWD}\app_data:/app_data" ghcr.io/presenton/presenton:latest</code></pre>

- Open Presenton
  <p>
  Open <a href="http://localhost:5001">http://localhost:5001</a> in the browser
  of your choice to use Presenton.
  </p>

  <blockquote>
  <p>
    <strong>Note:</strong> You can replace <code>5001</code> with any other port
    number of your choice to run Presenton on a different port number. If you use
    Docker Compose, set <code>PRESENTON_HTTP_HOST_PORT</code>, for example
    <code>PRESENTON_HTTP_HOST_PORT=8080 docker compose up production</code>.
  </p>
  </blockquote>

#

### ⚙️ Deployment Configurations

The tables below match the environment variables forwarded in this repository’s **`docker-compose.yml`** (`production`, `production-gpu`, `development`, and `development-gpu`). Put values in a `.env` file next to the compose file, or export them before `docker compose up`. The Electron app backend can read the same names when run outside Docker.

Other optional variables exist in code (for example advanced Mem0 paths, LiteParse runners, or `FAST_API_INTERNAL_URL` when Next.js and FastAPI are not same-origin); they are **not** wired in `docker-compose.yml`. Supported names are discoverable from `servers/fastapi/utils/get_env.py` and the Next.js server utilities under `servers/nextjs/`.

#### Air-gapped deployments

The Community gallery is enabled by default and reads presentation designs from
the Presenton community service. Air-gapped deployments must disable it:

```env
PRESENTON_COMMUNITY_ENABLED=false
```

For Docker Compose, add the value to the `.env` file next to
`docker-compose.yml` before starting Presenton. For `docker run`, pass
`-e PRESENTON_COMMUNITY_ENABLED=false`. This removes Community from the UI and
prevents the backend from sending Community gallery or design-reference
requests.

#### LLM and API keys

Provider settings are managed by account roles: admins can view and update
shared keys, while regular users receive only redacted runtime configuration.
The legacy `CAN_CHANGE_KEYS` variable is ignored and can be removed from existing
deployments. Missing provider configuration leaves login status and initial
account setup available so an admin can finish configuration in Settings.

| Variable | Values / default | Purpose |
| --- | --- | --- |
| **PRESENTON_PUBLIC_URL** | Optional URL | Browser-reachable Presenton origin, such as `http://localhost:5001` or `https://slides.example.com`. Generated download, edit, and preview links use this origin. |
| **PRESENTATION_GENERATION_MODE** | `both` (default), `standard`, `smart` | Controls the modes available in the UI and MCP server. A single-mode value hides the selector; `smart` also hides template features. See the **[presentation generation modes guide](https://github.com/presenton/presenton/blob/HEAD/docs/presentation-generation-modes.md)**. |
| **PRESENTON_COMMUNITY_ENABLED** | `true` (default), `false` | Controls the cloud-backed Community gallery and design references. Set to `false` for air-gapped deployments to hide the feature and prevent community API requests. |
| **LLM** | `openai`, `deepseek`, `google`, `vertex`, `azure`, `bedrock`, `openrouter`, `fireworks`, `together`, `cerebras`, `anthropic`, `litellm`, `lmstudio`, `ollama`, `custom`, `codex` | Selects the text LLM provider. |
| **OPENAI_API_KEY** | Required for `LLM=openai` | OpenAI API key. |
| **OPENAI_MODEL** | `gpt-4.1` (default) | OpenAI model. |
| **DEEPSEEK_API_KEY** | Required for `LLM=deepseek` | DeepSeek API key. |
| **DEEPSEEK_MODEL** | `deepseek-chat` (default) | DeepSeek model. |
| **DEEPSEEK_BASE_URL** | `https://api.deepseek.com` (default) | DeepSeek base URL. |
| **GOOGLE_API_KEY** | Required for `LLM=google` | Google API key. |
| **GOOGLE_MODEL** | `models/gemini-2.0-flash` (default) | Google model. |
| **VERTEX_MODEL** | `gemini-2.5-flash` (default) | Vertex AI model. |
| **VERTEX_API_KEY** | Optional | Vertex Express API key authentication. |
| **VERTEX_PROJECT** / **VERTEX_LOCATION** | Optional pair | GCP project credential authentication; do not combine with `VERTEX_API_KEY`. |
| **VERTEX_BASE_URL** | Optional URL | Vertex gateway or base URL override. |
| **AZURE_OPENAI_MODEL** | Required for `LLM=azure` | Azure deployment or model name. |
| **AZURE_OPENAI_API_KEY** | Required for `LLM=azure` | Azure OpenAI API key. |
| **AZURE_OPENAI_API_VERSION** | Required; for example `2024-10-21` | Azure OpenAI API version. |
| **AZURE_OPENAI_ENDPOINT** / **AZURE_OPENAI_BASE_URL** | At least one required | Azure OpenAI endpoint. |
| **AZURE_OPENAI_DEPLOYMENT** | Optional | Azure deployment override. |
| **BEDROCK_REGION** | `us-east-1` (default) | AWS Bedrock region. |
| **BEDROCK_MODEL** | Required for `LLM=bedrock` | Standard model ID or full inference-profile ARN, passed to Bedrock Converse as `modelId`. See the **[Amazon Bedrock guide](https://github.com/presenton/presenton/blob/HEAD/docs/amazon-bedrock.md)**. |
| **BEDROCK_API_KEY** | Optional | Bedrock API-key authentication; alternative to AWS keys. |
| **BEDROCK_AWS_ACCESS_KEY_ID** / **BEDROCK_AWS_SECRET_ACCESS_KEY** | Required together when `BEDROCK_API_KEY` is unset | AWS credential authentication for Bedrock. |
| **BEDROCK_AWS_SESSION_TOKEN** | Optional | AWS session token. |
| **BEDROCK_PROFILE_NAME** | Optional | AWS profile name. |
| **OPENROUTER_API_KEY** | Required for `LLM=openrouter` | OpenRouter API key. |
| **OPENROUTER_MODEL** | `openai/gpt-4o` (default) | OpenRouter model. |
| **OPENROUTER_BASE_URL** | `https://openrouter.ai/api/v1` (default) | OpenRouter base URL. |
| **OPENROUTER_PROVIDER_ORDER** | Optional comma-separated list | Provider routing order. |
| **OPENROUTER_ALLOW_FALLBACKS** | `true` / `false` | Optional provider fallback override. |
| **OPENROUTER_REQUIRE_PARAMETERS** | `true` / `false` | Only route to providers supporting every request parameter. |
| **OPENROUTER_DATA_COLLECTION** | `allow` / `deny` | Optional data-collection policy. |
| **OPENROUTER_ZDR** | `true` / `false` | Optional zero-data-retention requirement. |
| **FIREWORKS_API_KEY** | Required for `LLM=fireworks` | Fireworks API key. |
| **FIREWORKS_MODEL** | For example `accounts/fireworks/models/llama-v3p1-8b-instruct` | Fireworks model. |
| **FIREWORKS_BASE_URL** | `https://api.fireworks.ai/inference/v1` (default) | Fireworks base URL. |
| **TOGETHER_API_KEY** | Required for `LLM=together` | Together AI API key. |
| **TOGETHER_MODEL** | For example `openai/gpt-oss-20b` | Together AI model. |
| **TOGETHER_BASE_URL** | `https://api.together.ai/v1` (default) | Together AI base URL. |
| **CEREBRAS_API_KEY** | Required for `LLM=cerebras` | Cerebras API key. |
| **CEREBRAS_MODEL** | `llama-3.3-70b` (default) | Cerebras model. |
| **CEREBRAS_BASE_URL** | `https://api.cerebras.ai/v1` (default) | Cerebras base URL. |
| **ANTHROPIC_API_KEY** | Required for `LLM=anthropic` | Anthropic API key. |
| **ANTHROPIC_MODEL** | `claude-3-5-sonnet-20241022` (default) | Anthropic model. |
| **CODEX_MODEL** | Required for `LLM=codex` | Codex model. The OAuth flow maps host port `1455` for its callback. |
| **CUSTOM_LLM_URL** | Required for `LLM=custom` | OpenAI-compatible base URL. The server must implement `POST /v1/chat/completions`; a provider-specific completion endpoint is insufficient. |
| **CUSTOM_LLM_API_KEY** | Provider-dependent | Custom-provider API key. |
| **CUSTOM_MODEL** | Required for `LLM=custom` | Custom-provider model ID. |
| **LITELLM_BASE_URL** | Required for `LLM=litellm` | LiteLLM proxy or gateway base URL. |
| **LITELLM_API_KEY** | Optional | LiteLLM API key. |
| **LITELLM_MODEL** | `gpt-4.1` (default) | LiteLLM model. |
| **LMSTUDIO_BASE_URL** | `http://localhost:1234/v1` (default) | LM Studio base URL; `/v1` is appended when omitted. |
| **LMSTUDIO_API_KEY** | Optional | LM Studio API key. |
| **LMSTUDIO_MODEL** | For example `openai/gpt-oss-20b` | LM Studio model. |
| **DISABLE_THINKING** | `true` / `false` | Disables thinking for providers that support it, including DeepSeek. |
| **WEB_GROUNDING** | `true` / `false` | Enables web search by default. |
| **WEB_SEARCH_PROVIDER** | `auto`, `native`, `searxng`, `tavily`, `exa` | Selects the search mode. `auto` uses native search for OpenAI, Google, and Anthropic and otherwise leaves search off unless an external provider is selected. |
| **WEB_SEARCH_MAX_RESULTS** | `5` (default), maximum `10` | Maximum external search results added to model context. |
| **SEARXNG_BASE_URL** | Optional URL | Self-hosted SearXNG base URL. |
| **TAVILY_API_KEY**, **EXA_API_KEY** | Optional | Credentials for hosted search providers. |
| **EXTENDED_REASONING** | `true` / `false` | Enables extended reasoning where supported. |
| **LLM_GENERATION_PROFILE** | `fast`, `balanced` (default), `deep`, `model_max` | Global generation profile. |
| **LLM_MAX_OUTPUT_TOKENS** | Optional positive integer | Output-token override for every text provider. |
| **MAX_OUTLINE_WORDS** | `100` (default), positive integer | Maximum words in each generated, edited, or `slides_markdown` slide outline. |
| **LLM_REASONING_MODE** | `auto`, `enabled`, `disabled` | Global reasoning-mode override. |
| **LLM_REASONING_EFFORT** | `default`, `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max` | Reasoning-effort override. |
| **LLM_REASONING_BUDGET_TOKENS** | Optional non-negative integer | Reasoning token budget. |

<!-- Brave and Serper search providers and their credentials are hidden until they are tested. -->

All advanced text-provider settings are optional. Use **Reset advanced settings** in Settings or onboarding to remove overrides and inherit application/provider defaults.

#### Ollama

Use when **LLM** is **ollama**:

| Variable | Values / default | Purpose |
| --- | --- | --- |
| **OLLAMA_URL** | For example `http://host.docker.internal:11434` from Docker | Ollama HTTP API base URL. |
| **OLLAMA_MODEL** | For example `llama3.2:3b` | Ollama model name. |
| **START_OLLAMA** | `false` (default), `true` | Allows the container entrypoint (`start.js`) to install Ollama and run `ollama serve`. |

#### Presentation memory (Mem0 OSS)

Mem0 uses local Qdrant + SQLite (OSS); memory is scoped per presentation.

By default the Docker runtime now points Mem0 at a local Ollama-compatible LLM endpoint, so it no longer needs an OpenAI key just to initialize. If you want to use OpenAI instead, set `MEM0_LLM_BASE_URL`/`MEM0_LLM_API_KEY` to your OpenAI-compatible endpoint and key.
Docker images install the default spaCy model (`en_core_web_sm`) during build so Mem0 can start without extra setup on each run.

| Variable                     | Purpose                                                                                                          |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| **MEM0_ENABLED**             | **true**/false (compose default **true**).                                                                       |
| **MEM0_LLM_MODEL**           | Mem0 LLM model name (compose default **`llama3.1:latest`** or `OLLAMA_MODEL`).                                   |
| **MEM0_LLM_API_KEY**         | Mem0 LLM API key placeholder for OpenAI-compatible clients (compose default **`ollama`**).                       |
| **MEM0_LLM_BASE_URL**        | Mem0 LLM base URL (compose default **`OLLAMA_URL`** or `http://host.docker.internal:11434`).                     |
| **MEM0_DIR**                 | Root directory (compose default **`/app_data/mem0`**).                                                           |
| **MEM0_EMBEDDER_PROVIDER**   | Embedder backend (compose default **`fastembed`**).                                                              |
| **MEM0_EMBEDDER_MODEL**      | Model id (compose default **`BAAI/bge-small-en-v1.5`**).                                                         |
| **MEM0_EMBEDDING_DIMS**      | Vector size (compose default **384**).                                                                           |
| **MEM0_SPACY_MODEL**         | Optional spaCy model override (default **`en_core_web_sm`**).                                                    |
| **MEM0_REQUIRE_SPACY_MODEL** | Keep as **true** (default). Set to false only if you intentionally want Mem0 to run without spaCy lemmatization. |

#### Document parsing (LiteParse)

| Variable                  | Purpose                                   |
| ------------------------- | ----------------------------------------- |
| **LITEPARSE_DPI**         | OCR render DPI (compose default **120**). |
| **LITEPARSE_NUM_WORKERS** | Worker count (compose default **1**).     |

#### Database

| Variable | Values / default | Purpose |
| --- | --- | --- |
| **DATABASE_URL** | Optional SQLAlchemy URL | Configures the database; when unset, the app uses SQLite under app data. |
| **MIGRATE_DATABASE_ON_STARTUP** | `true` (default), `false` | Runs database migrations during startup. Set to `false` only when migrations are managed externally. |

#### Image generation

These variables match `docker-compose.yml`. **`IMAGE_PROVIDER`** selects the backend (`pexels`, `pixabay`, `gemini_flash`, `nanobanana_pro`, `gpt-image-2`, `gpt-image-1.5`, `comfyui`, `open_webui`). Use **OPENAI_API_KEY** for OpenAI image modes and **GOOGLE_API_KEY** for Gemini image modes (same keys as the LLM section).

| Variable | Values / default | Purpose |
| --- | --- | --- |
| **DISABLE_IMAGE_GENERATION** | `true` / `false` | Disables slide image generation. |
| **ENABLE_PARALLEL_IMAGE_GENERATION** | `true` (default), `false` | Allows concurrent image-provider requests. Set to `false` for providers with strict rate limits. |
| **IMAGE_PROVIDER** | `pexels`, `pixabay`, `gemini_flash`, `nanobanana_pro`, `gpt-image-2`, `gpt-image-1.5`, `comfyui`, `open_webui`, `openai_compatible` | Selects the image backend. |
| **PEXELS_API_KEY** | Required for `IMAGE_PROVIDER=pexels` | Pexels stock-image API key. |
| **PIXABAY_API_KEY** | Required for `IMAGE_PROVIDER=pixabay` | Pixabay stock-image API key. |
| **GPT_IMAGE_2_QUALITY** | `low`, `medium` (default), `high` | GPT Image 2 image quality. |
| **GPT_IMAGE_1_5_QUALITY** | `low`, `medium` (default), `high` | GPT Image 1.5 image quality. |
| **COMFYUI_URL** / **COMFYUI_WORKFLOW** | Required for `IMAGE_PROVIDER=comfyui` | Self-hosted ComfyUI endpoint and workflow JSON. |
| **OPEN_WEBUI_IMAGE_URL** / **OPEN_WEBUI_IMAGE_API_KEY** | Required for `IMAGE_PROVIDER=open_webui` | Open WebUI API root (`http://host:8080/api/v1`; a bare origin gets `/api/v1` appended) and API key. |
| **OPENAI_COMPAT_IMAGE_BASE_URL** / **OPENAI_COMPAT_IMAGE_API_KEY** / **OPENAI_COMPAT_IMAGE_MODEL** | Required for `IMAGE_PROVIDER=openai_compatible` | Sends image requests to an OpenAI-compatible `/v1/images/*` endpoint such as LiteLLM, Azure, or a vLLM gateway. |

Existing `IMAGE_PROVIDER=dall-e-3` configurations automatically migrate to `gpt-image-2`. Legacy `standard` quality maps to `medium`, and `hd` maps to `high`. Set `GPT_IMAGE_2_QUALITY` to choose a different quality.

The parallel image generation option applies everywhere images are generated: initial presentation generation, slide editing and regeneration, direct image requests, and assistant image tools.

#### Telemetry

| Variable | Values / default | Purpose |
| --- | --- | --- |
| **DISABLE_ANONYMOUS_TRACKING** | `true` / `false` | Set to `true` to disable anonymous telemetry. |

#### Multi-user authentication

Presenton supports multiple accounts with a private workspace for each user. The
first account becomes the primary administrator and can create, reset, or remove
other accounts from **Admin → Users**.

Existing single-user installations are upgraded automatically: the current account
becomes the primary administrator, while its presentations, templates, tasks, and
other owned data stay attached to the same account.

##### Set up the primary administrator

On a new installation, open Presenton and follow the account setup screen. For an
unattended Docker deployment, you can create the primary administrator on first boot
with environment variables:

```bash
docker run -it --name presenton \
  -p 5001:80 \
  -e AUTH_USERNAME=admin \
  -e AUTH_PASSWORD=change-this-password \
  -v "./app_data:/app_data" \
  ghcr.io/presenton/presenton:latest
```

Usernames must contain at least 3 characters, and new passwords must contain at least
8 characters. Older six- or seven-character passwords remain valid after an upgrade.

##### Authentication environment variables

| Variable | Purpose |
| --- | --- |
| **AUTH_USERNAME** | Username used to create the primary administrator on first boot. It can also change the username during a rotation or recovery. |
| **AUTH_PASSWORD** | Password used for first-time setup, rotation, or recovery. Required when using either flag below. |
| **AUTH_OVERRIDE_FROM_ENV**=[true/false] | Replace the primary administrator's credentials from the environment on the next startup. Use this for a deployment-managed credential rotation. |
| **RESET_AUTH**=[true/false] | Recover access to the existing primary administrator without replacing the account or its data. |

##### Presenton Cloud provider

Presenton Cloud is an optional, installation-wide generation provider. It is not an
authentication method for the self-hosted instance. Create or sign in to the local
administrator account first, then connect Presenton from provider onboarding.

Only the local administrator can connect, replace, or disconnect the provider. The
browser displays a short device code and opens the hosted Presenton approval page.
After approval, the delegated access and rotating refresh tokens are encrypted at rest
and stored as one global provider credential; they are never returned to the browser or
stored per local user.

Selecting Presenton as the text provider saves `LLM=presenton`. Presentation generation
and document uploads then use the Presenton Cloud API and its token. Connecting the
provider alone does not change generation: when another provider is selected, the
existing local generation pipeline remains unchanged. Disconnecting revokes and removes
the global credentials and deselects Presenton.

No OAuth client registration, client secret, or environment configuration is required.
Official builds contain the cloud URL and first-party public device-flow client ID.

To rotate credentials from the environment:

```bash
docker stop presenton
docker rm presenton
docker run -it --name presenton \
  -p 5001:80 \
  -e AUTH_USERNAME=admin \
  -e AUTH_PASSWORD=new-secure-password \
  -e AUTH_OVERRIDE_FROM_ENV=true \
  -v "./app_data:/app_data" \
  ghcr.io/presenton/presenton:latest
```

For account recovery, use the same command with `RESET_AUTH=true` instead of
`AUTH_OVERRIDE_FROM_ENV=true`. Both operations preserve the administrator's user ID
and owned data, and invalidate existing browser sessions and API keys. Remove the
one-time flag after the successful startup.

> [!IMPORTANT]
> Do not remove authentication fields from `app_data/userConfig.json` to reset
> access. Presenton stores a hashed recovery copy of the primary administrator
> credentials and the session-signing secret there. Use the recovery variables above
> to preserve the database account and its ownership links.

To sign out, open **Settings → Other → Sign out**.

#### API and MCP authentication

Presenton exposes a client-neutral MCP 2025-11-25 Streamable HTTP endpoint at
`/mcp`. When authentication is enabled, REST API and MCP clients use the same
administrator-provisioned, user-scoped API key. Browser JWT cookies are not
accepted as MCP credentials.

1. An administrator creates the target Presenton user, then calls
   `POST /api/v1/admin/api-keys` from an authenticated admin session with
   `{"user_id":"...","label":"My API client","expiry_days":90}`. The response
   contains the new key. Listing and revocation use
   `GET /api/v1/admin/api-keys` and
   `POST /api/v1/admin/api-keys/{api_key_id}/revoke`.
   An administrator can securely reveal a key again with
   `GET /api/v1/admin/api-keys/{api_key_id}/token`.

2. Configure any Streamable HTTP MCP client to send the generated
   `sk-presenton-...` key on
   every request:

```json
{
  "servers": {
    "presenton": {
      "url": "http://localhost:5001/mcp",
      "type": "http",
      "headers": {
        "Authorization": "Bearer sk-presenton-0123456789abcdef.REPLACE_WITH_SECRET"
      }
    }
  },
  "inputs": []
}
```

Notes:

- This example uses VS Code's `.vscode/mcp.json` format. Use the equivalent
  Streamable HTTP and bearer-header configuration in Open WebUI or any other
  conforming MCP client.
- API keys retain an Argon2 authentication hash and an encrypted, admin-only
  recoverable copy. They expire by default after 90 days and represent exactly
  the selected Presenton user. The same key authenticates general REST endpoints
  and MCP, but cannot sign in to the browser or change admin/provider settings.
- The API key is exchanged inside the MCP process for a short-lived internal
  user session. The long-lived key is never forwarded to presentation APIs.
- Revoking the key through the admin API takes effect immediately.
- Standard, Smart Mode, and template generation tools return an async task ID.
  Poll `get_job_status` until `completed` or `error`; template listing is immediate.
- MCP exposes only the polling Smart workflow (`start_smart_presentation` followed
  by `get_job_status`) so Standard and Smart generation use the same job model.
- `upload_template_assets` accepts one PPTX and its replacement fonts in a
  single call, then returns the data needed by `start_template_generation`.
- `upload_files` accepts reference documents and images as base64 and returns
  user-scoped paths that can be passed unchanged to Standard or Smart generation.
- External REST API and MCP access are not available in the Electron desktop app (`PRESENTON_ELECTRON=true`). Its local HTTP servers are internal application services. Electron runs without account login by default and supplies a private credential generated at each launch to its own app and export requests; anonymous local clients cannot access those services. The MCP server remains disabled there.
- Only asset subdirectories are served under `/app_data`; configuration, databases and logs are never web assets. Document preview readers accept `.txt` document files within the allowed asset/temp directories and reject export task JSON and private application files.

> Note: LLM and image variables above are forwarded from **`docker-compose.yml`** when set in `.env`.

<br>
<br>

**Docker Run Examples by Provider**

Same variables as compose; use `-e` instead of `.env` when running `docker run` directly.

- Using OpenAI
    <pre><code class="language-bash">docker run -it --name presenton -p 5001:80 -e LLM="openai" -e OPENAI_API_KEY="******" -e IMAGE_PROVIDER="gpt-image-2" -v "./app_data:/app_data" ghcr.io/presenton/presenton:latest</code></pre>

- Using Google
    <pre><code class="language-bash">docker run -it --name presenton -p 5001:80 -e LLM="google" -e GOOGLE_API_KEY="******" -e IMAGE_PROVIDER="gemini_flash" -v "./app_data:/app_data" ghcr.io/presenton/presenton:latest</code></pre>

- Using Vertex AI (API key mode)
    <pre><code class="language-bash">docker run -it --name presenton -p 5001:80 -e LLM="vertex" -e VERTEX_API_KEY="******" -e VERTEX_MODEL="gemini-2.5-flash" -e IMAGE_PROVIDER="gemini_flash" -v "./app_data:/app_data" ghcr.io/presenton/presenton:latest</code></pre>

- Using Azure OpenAI
    <pre><code class="language-bash">docker run -it --name presenton -p 5001:80 -e LLM="azure" -e AZURE_OPENAI_API_KEY="******" -e AZURE_OPENAI_MODEL="gpt-4.1" -e AZURE_OPENAI_API_VERSION="2024-10-21" -e AZURE_OPENAI_ENDPOINT="https://YOUR-RESOURCE.openai.azure.com" -e IMAGE_PROVIDER="pexels" -e PEXELS_API_KEY="******" -v "./app_data:/app_data" ghcr.io/presenton/presenton:latest</code></pre>

- Using Amazon Bedrock (on-demand model ID) — see **[docs/amazon-bedrock.md](https://github.com/presenton/presenton/blob/HEAD/docs/amazon-bedrock.md)** for inference profiles, IAM, and troubleshooting.
    <pre><code class="language-bash">docker run -it --name presenton -p 5001:80 -e LLM="bedrock" -e BEDROCK_REGION="us-east-1" -e BEDROCK_AWS_ACCESS_KEY_ID="******" -e BEDROCK_AWS_SECRET_ACCESS_KEY="******" -e BEDROCK_MODEL="us.anthropic.claude-3-5-haiku-20241022-v1:0" -e IMAGE_PROVIDER="pexels" -e PEXELS_API_KEY="******" -v "./app_data:/app_data" ghcr.io/presenton/presenton:latest</code></pre>

- Using Amazon Bedrock (inference profile ARN, e.g. Claude Sonnet 4.6)
    <pre><code class="language-bash">docker run -it --name presenton -p 5001:80 -e LLM="bedrock" -e BEDROCK_REGION="us-east-1" -e BEDROCK_AWS_ACCESS_KEY_ID="******" -e BEDROCK_AWS_SECRET_ACCESS_KEY="******" -e BEDROCK_MODEL="arn:aws:bedrock:us-east-1:YOUR_ACCOUNT_ID:inference-profile/us.anthropic.claude-sonnet-4-6" -e IMAGE_PROVIDER="pexels" -e PEXELS_API_KEY="******" -v "./app_data:/app_data" ghcr.io/presenton/presenton:latest</code></pre>

- Using Fireworks
    <pre><code class="language-bash">docker run -it --name presenton -p 5001:80 -e LLM="fireworks" -e FIREWORKS_API_KEY="******" -e FIREWORKS_MODEL="accounts/fireworks/models/llama-v3p1-8b-instruct" -e IMAGE_PROVIDER="pexels" -e PEXELS_API_KEY="******" -v "./app_data:/app_data" ghcr.io/presenton/presenton:latest</code></pre>

- Using Together AI
    <pre><code class="language-bash">docker run -it --name presenton -p 5001:80 -e LLM="together" -e TOGETHER_API_KEY="******" -e TOGETHER_MODEL="openai/gpt-oss-20b" -e IMAGE_PROVIDER="pexels" -e PEXELS_API_KEY="******" -v "./app_data:/app_data" ghcr.io/presenton/presenton:latest</code></pre>

- Using Ollama

> The README is long; the above is its first 40000 characters. Full content: https://github.com/presenton/presenton
