{
  "markdown": "# Presio\n\nPresent PDFs from your browser — try it at **[presio.xyz](https://presio.xyz)**.\n\nUpload a PDF presentation, get a short link, and control the slideshow from one browser window while viewers watch in another. Presio is a hosted service; this repository is its source code.\n\n\n![Demo](https://github.com/benedict-armstrong/presio/releases/download/demo/presio.gif)\n\n![Demo](example/diagram.png)\n\n## Features\n\n- **Local by default** — your PDF stays in the browser and is never uploaded. Works offline; local presentations are kept for up to 7 days.\n- **Controller + viewer** — drive slides from the controller window while a viewer window mirrors it, kept perfectly in sync.\n- **Present across devices** — log in and sync online to get a 6-character session code. Viewers enter it on the home page and follow along live over WebSockets.\n- **Shared control** — hand out a controller passphrase to let someone else drive.\n- **Speaker notes** — written next to your current and next slide, rendered as markdown.\n- **Embedded media** — local videos and GIFs, direct video URLs, and YouTube/Vimeo. Playback, autoplay, and seeking all stay in sync with viewers.\n- **Presentation timer** — track how long you've been talking.\n- **Customizable controller** — rearrange the layout and remap keyboard shortcuts.\n- **Recent presentations** — pick up where you left off from the home page.\n- **Download** — anyone can grab the PDF from the presentation view.\n- **Agent APIs** — MCP server and REST API for AI agents; see [Use it from an AI agent](#use-it-from-an-ai-agent).\n\n## Adding videos and speaker notes\n\nPresio is agnostic to the typesetting engine used — any PDF works, and notes can also be embedded by hand from plain Typst or LaTeX (see [Embedding notes by hand](#embedding-notes-by-hand)). Official packages are available for the two most common ones:\n\n- **Typst** — [presio-typst-package](https://github.com/benedict-armstrong/presio-typst-package)\n- **LaTeX** — [presio-latex-package](https://github.com/benedict-armstrong/presio-latex-package)\n\n### Typst\n\n```typst\n#import \"@preview/presio:0.2.1\": media, speaker-notes\n\n= Introduction\n\nHello world.\n\n#speaker-notes[\n  Remember to mention the demo before moving on.\n]\n\n#media(\"https://www.youtube.com/watch?v=dQw4w9WgXcQ\", width: 60%, aspect-ratio: 16/9)\n```\n\n### LaTeX\n\n[![Open in Overleaf](https://img.shields.io/badge/Open%20in%20Overleaf-1F2A37?logo=overleaf&logoColor=white)](https://www.overleaf.com/docs?snip_uri[]=https://raw.githubusercontent.com/benedict-armstrong/presio-latex-package/main/starter/main.tex&snip_uri[]=https://raw.githubusercontent.com/benedict-armstrong/presio-latex-package/main/presio.sty&snip_uri[]=https://raw.githubusercontent.com/benedict-armstrong/presio-latex-package/main/starter/clip.gif&snip_uri[]=https://raw.githubusercontent.com/benedict-armstrong/presio-latex-package/main/starter/poster.png&snip_name[]=main.tex&snip_name[]=presio.sty&snip_name[]=clip.gif&snip_name[]=poster.png&engine=pdflatex)\n\n```latex\n\\documentclass{beamer}\n\\usepackage{presio}\n\n\\begin{document}\n\n\\begin{frame}{Introduction}\n  Hello world.\n  \\presionote{Remember to mention the demo before moving on.}\n\\end{frame}\n\n\\begin{frame}{The demo}\n  \\presiomedia[width=0.7\\linewidth]{https://www.youtube.com/watch?v=dQw4w9WgXcQ}\n\\end{frame}\n\n\\end{document}\n```\n\nFor LaTeX, copy `presio.sty` from the package repository next to your `.tex` file — that's the whole install.\n\n### Embedding notes by hand\n\nPrefer not to use the packages? Presio reads speaker notes from JSON files\nattached to the PDF (Typst) or from `note:` link annotations (LaTeX), and\nrenders them as markdown in the controller's notes panel.\n\nTypst — define a helper and call it on each slide:\n\n```typst\n#let speaker-notes(notes) = context {\n  // Page number keeps the attachment filename unique per slide\n  let page-num = counter(page).display()\n  let filename = \"notes-slide-\" + page-num + \".json\"\n\n  let json-string = json.encode((slide: page-num, notes: notes))\n\n  pdf.attach(\n    filename,\n    bytes(json-string),\n    description: \"Speaker notes for slide \" + page-num,\n    mime-type: \"application/json\",\n  )\n}\n\n#speaker-notes(\"Remember to mention the demo.\")\n```\n\nLaTeX — use `hyperref` to create an invisible `note:` link:\n\n```latex\n\\usepackage{hyperref}\n\n\\newcommand{\\speakernote}[1]{%\n  \\href{note:#1}{\\phantom{n}}%\n}\n\n% Usage on a slide:\n\\speakernote{Remember to mention the demo.}\n```\n\nValidate what you produced at [presio.xyz/check](https://presio.xyz/check) — it\nshows per-page thumbnails and reports whether the notes and media sidecars are\nvalid.\n\n## Self-hosting\n\nWant to run Presio yourself instead of using the hosted service? For a full\ndeployment (accounts, cross-device sync, your own domain) see\n[`deploy/README.md`](deploy/README.md).\n\nFor a single offline container with no accounts and no Supabase — just present\nPDFs on your own machine or LAN — nothing needs building:\n\n```bash\ndocker run -d -p 3001:3001 -e PRESIO_MODE=local -e LOCAL_DATA_DIR=/data \\\n  -e TRUST_PROXY=false -v presio-data:/data \\\n  ghcr.io/benedict-armstrong/presio-local:1\n```\n\nThe `:1` tag tracks the current major release line — fixes and features, no\nbreaking changes. See [Versions and upgrading](deploy/README.md#versions-and-upgrading).\n\nSee [\"Running fully local / offline\"](deploy/README.md#running-fully-local--offline)\nfor what this mode does and doesn't include.\n",
  "bytes": 5404,
  "sha": "2f3bea8d456bc0c271124e69c52f0cae19f4b5066fc570dd27264a7ba194efa3",
  "repo_slug": "benedict-armstrong/presio",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_xyz_presio_presio_413d9da9/readme"
}