The presentation on your screen—streamed to your LLM. No save, no path, no handoff. One command reads what you're editing; another writes it back. Your terminal and PowerPoint finally speak the same language.
Your LLM can't see the deck you're staring at. You copy-paste, juggle paths, or give up. ppt-cli hooks into the active presentation—the one with the cursor blinking—and pipes it straight to stdout. Your AI reads live content, returns edits as JSON, and you apply them with a single update call. The deck you're editing is the only source of truth.
Why CLI instead of MCP? No server to run, no protocol to configure. Any tool that can run a shell command can use ppt-cli—your IDE, a script, a cron job, or an LLM that simply executes ppt get-content. Pipe the output, grep it, feed it to any model. CLI is universal; MCP locks you into its ecosystem.
Clone the repo, then:
cd ppt-cli
uv tool install .- Open a PowerPoint presentation.
- Run
ppt get-content --active --slides Allto read slide text. - Have your LLM produce edits as JSON.
- Run
ppt update --active --content-file edits.jsonto apply changes.
ppt --helpusage: ppt [-h] [-v] command ...
PowerPoint CLI for LLM. Read and update slide content via win32com on Windows. Outputs JSON by default for easy parsing. Commands: get-content, get-active-text, update, list-slides.
positional arguments:
command
get-content Get slide content as JSON
get-active-text Get selected textboxes with UUID keys
update Update text in slides
list-slides List slides with content summary
options:
-h, --help show this help message and exit
-v, --verbose Enable verbose logging to stderr
Use 'ppt <command> --help' for detailed help on each command.
| Command | Description |
|---|---|
get-content |
Get slide content as JSON (MCP: get_ppt_content) |
get-active-text |
Get selected textboxes with UUID keys (MCP: get_active_text_content) |
update |
Update text in slides (MCP: update_ppt_content) |
list-slides |
List slides with content summary |
Get content from active presentation (current slide):
ppt get-content --active --slides CurrentGet content from file:
ppt get-content --file C:\path\to\presentation.pptx --slides 1,2,3Get selected textboxes (user must have text selected in PowerPoint):
ppt get-active-text --activeUpdate content:
ppt update --active --content "{\"1\": {\"Title_1_1\": \"New Title\"}}"Or from file:
ppt update --active --content-file updates.json- All commands output JSON to stdout by default (except
list-slideswhich is human-readable). - Use
--output FILEto write JSON to a file. - Errors are written as
{"error": "..."}to stderr with exit code 1. - Use
--verbosefor debug logs to stderr.
get-content (default): Outputs actual text content. Keys are text identifiers; values are the real slide text.
{
"1": {"Title": "My Title", "Subtitle": "My Subtitle"},
"2": {"Title_2_1": "Slide 2 Title"}
}get-content --with-placeholders: Outputs {key: "spaceholder"} format for building update input. Use when the LLM needs the exact keys for update.
{
"1": {"Title_1_1": "spaceholder", "Subtitle": "spaceholder"},
"2": {"Title_2_1": "spaceholder"}
}Keys like Title_1_1 mean the first occurrence of "Title" with UUID suffix. Use these exact keys in update.
update input:
{
"1": {"Title_1_1": "New Title"},
"2": {"Subtitle": "Updated text"}
}Use "spaceholder" as value to keep existing text unchanged.
- Windows (PowerPoint + pywin32 COM automation)
- Python >= 3.10