KeynoteSAFE
A Model Context Protocol (MCP) server that enables AI assistants to control Keynote presentations through AppleScript automation.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
[](https://opensource.org/licenses/MIT) [](https://www.python.org/downloads/) [](https://www.apple.com/macos/)
https://github.com/user-attachments/assets/fb293e54-0795-434f-a811-7f850d36619f
⚠️ Development Notice: This project was developed using Cursor AI without human code review. It's provided for educational and experimental purposes only. Please use with caution in production environments and conduct thorough testing before deployment.
A Model Context Protocol (MCP) server that enables AI assistants to control Keynote presentations through AppleScript automation.
中文文档 | English
✨ Features
- 🎨 Complete Presentation Management - Create, open, save, and close presentations
- 📊 Rich Slide Operations - Add, delete, duplicate, and move slides
- 📝 Powerful Content Management - Add text, images, shapes, tables, and charts
- 📸 Flexible Export Options - Screenshot slides, export to PDF and images
- 🖼️ Unsplash Integration - Automatically search and add high-quality images
- 🔒 Secure & Reliable - Comprehensive error handling and permission management
- 🧪 Well Tested - Unit and integration test coverage
🚀 Quick Start
Prerequisites
- macOS 10.14 or later
- Keynote application
- Python 3.8 or later
Installation
- Clone the repository
git clone https://github.com/easychen/keynote-mcp.git cd keynote-mcp
- Install dependencies
pip install -r requirements.txt
- Configure environment (optional for Unsplash features)
cp env.example .env # Edit .env file and add your Unsplash API key
- Set up macOS permissions
- Go to System Preferences > Security & Privacy > **Privacy
8c7d3840507aOBSERVED · 2026-10-07Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add keynote-mcp --env UNSPLASH_KEY=${UNSPLASH_KEY} -- uvx keynote-mcp{
"mcpServers": {
"keynote-mcp": {
"command": "uvx",
"args": [
"keynote-mcp"
],
"env": {
"UNSPLASH_KEY": "${UNSPLASH_KEY}"
}
}
}
}Exposed tools (32)
16 read · 15 write · 1 destructive. Blast radius: 1 tool can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.
| Tool | Risk | Description |
|---|---|---|
add_bullet_list | write | 在幻灯片中添加项目符号列表 |
add_code_block | write | 在幻灯片中添加代码块 |
add_image | write | 在幻灯片中添加图片 |
add_numbered_list | write | 在幻灯片中添加编号列表 |
add_quote | write | 在幻灯片中添加引用文本 |
add_slide | write | 添加新幻灯片 |
add_subtitle | write | 在幻灯片中添加副标题 |
add_text_box | write | 在幻灯片中添加文本框 |
add_title | write | 在幻灯片中添加标题 |
add_unsplash_image_to_slide | write | 搜索Unsplash图片并添加到幻灯片 |
close_presentation | read | 关闭演示文稿 |
create_presentation | write | 创建新的 Keynote 演示文稿 |
delete_slide | destructive | 删除幻灯片 |
duplicate_slide | read | 复制幻灯片 |
export_pdf | read | 导出演示文稿为PDF |
get_available_layouts | read | 获取可用布局列表 |
get_available_themes | read | 获取可用主题列表 |
get_presentation_info | read | 获取演示文稿信息 |
get_presentation_resolution | read | 获取演示文稿分辨率信息 |
get_random_unsplash_image | read | 获取随机Unsplash图片并添加到幻灯片 |
get_slide_count | read | 获取幻灯片数量 |
get_slide_info | read | 获取幻灯片信息 |
get_slide_size | read | 获取幻灯片尺寸和比例信息 |
list_presentations | read | 列出所有打开的演示文稿 |
move_slide | write | 移动幻灯片位置 |
open_presentation | read | 打开现有的 Keynote 演示文稿 |
save_presentation | write | 保存演示文稿 |
screenshot_slide | read | 截图单个幻灯片 |
search_unsplash_images | read | 搜索Unsplash图片 |
select_slide | read | 选择指定幻灯片 |
set_presentation_theme | write | 设置演示文稿主题 |
set_slide_layout | write | 设置幻灯片布局 |
Trust audit
SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | PASS |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (2 observation(s))
- Network
- declared (3 observation(s))
- Shell
- none-observed
- Dependencies
- not all pinned
- Secrets in source
- none-found
Findings (3)
delete_slide
pytest, pytest-cov, pytest-asyncio, black, isort, flake8, mypy, bandit
mcp, asyncio-mqtt, pathlib, typing-extensions, aiohttp, aiofiles, Pillow, pytest
Gates applied: no_behavioural_pass.
8c7d3840507afull audit observations/trust-audit/mcp-server/easychen__keynote.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-07 | 8c7d3840507a | SAFE | B | 89 | first audit |
Questions
What is the Keynote MCP server?
A Model Context Protocol (MCP) server that enables AI assistants to control Keynote presentations through AppleScript automation.
What tools does Keynote expose?
32 in total: 16 read-only, 15 that write, and 1 that can delete or overwrite (delete_slide). Every one is listed on this page with its risk.
Is Keynote safe to connect to an agent?
The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean server reads B. Separately from the audit: 1 of its tools can destroy data, so scope the token you give it to what you actually need.
What credentials does Keynote need?
It reads UNSPLASH_KEY from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does Keynote run?
It speaks stdio, so it runs as a local process your client starts. It is published on PyPI as keynote-mcp.
How current is this page?
The grade is for one exact copy of the source (8c7d3840507a), read on 2026-10-07. The repository is watched and re-audited when it changes.