MCP server that harvests Keynote and PDF slide decks into slide previews, extracted text, embedded-image assets, and a versioned manifest. PDF-first anywhere; native .key export via Keynote on macOS.
- ✓Open-source license (MIT)
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Documented (README)
claude mcp add keynote-harvest-mcp -- npx -y keynote-harvest-mcp{
"mcpServers": {
"keynote-harvest-mcp": {
"command": "npx",
"args": ["-y", "keynote-harvest-mcp"]
}
}
}Resumen de MCP Servers
# Keynote Harvest MCP
`keynote-harvest-mcp` is a local stdio MCP server for turning Keynote exports and PDFs into portable slide previews, extractable text, embedded-image assets, and a versioned manifest.
It contains only the harvest-first MCP boundary:
- Keynote app discovery.
- Native `.key` to PDF export on macOS.
- PDF-first harvest into previews, extractable text, assets, and a manifest.
- Display-safe manifest reads.
- Local harvest output listing.
- MCP resources for manifests, previews, extracted embedded-image assets, and extracted text. Source PDFs are denied by default and require the operator-only `KEYNOTE_HARVEST_ALLOW_SOURCE_RESOURCES=1` capability.
It intentionally excludes composition/proposal tools, web-framework renderers, preview routes, OCR, vision, and LLM calls.
## Requirements
- macOS or Linux (declared via the package `os` field; Windows is unsupported).
- Node.js 22 or newer (maintained LTS releases).
- Poppler commands `pdfinfo`, `pdftoppm`, and `pdftotext` for PDF harvests.
- Poppler `pdfimages` for embedded-image asset extraction, which is on by default. Without `pdfimages` the harvest still completes and records a manifest warning; pass `extractImages: false` (CLI: `--no-extract-images`) to skip extraction, or `extractImages: true` (CLI: `--extract-images`) to require `pdfimages` and fail when it is missing.
- macOS, Keynote, and Automation permission for native `.key` export only.
PDF harvesting can run without Keynote. OCR, vision, LLM calls, `.key` package parsing, and presenter-note extraction are intentionally absent.
## Manifest Contract
New harvests use `schemaVersion: "keynote-harvest-manifest-v1"`. The package owns three aligned representations of that contract:
- TypeScript types under `src/types/`.
- Runtime structural validation under `src/schema/`.
- A distributable Draft 2020-12 JSON Schema at `schema/keynote-harvest-manifest-v1.schema.json`.
The runtime validator requires the version by default. Its explicit `allowLegacyVersion` option exists only to inspect older private manifests created before schema versioning; newly generated manifests are always versioned.
### Schema Evolution
Additive, optional fields may be introduced without changing
`keynote-harvest-manifest-v1`. Any breaking contract change must mint
`keynote-harvest-manifest-v2` with a separate schema file, while the runtime
validator retains support for reading v1. `allowLegacyVersion` remains limited
to pre-versioned private manifests and is not a substitute for versioned schema
migrations.
## Install, Build, And Test
```bash
cd keynote-harvest-mcp
npm ci
npm run build
npm test
```
`npm run test:clean-install` copies the package to a temporary directory, runs `npm ci`, rebuilds it, and executes the package-owned tests in isolation from this checkout's installed dependencies.
`npm run test:packed-runtime` builds a local tarball, installs it into an empty consumer project, starts the installed binary, and verifies the packaged tool surface. Neither rehearsal publishes anything.
`npm run test:pdf-runtime` generates public-safe PDFs, exercises replacement and quota failures through local Poppler commands, validates path-safe v1 manifests, and removes all temporary output.
The built server and tools execute JavaScript from `dist/`; they do not execute source TypeScript at runtime.
## Quickstart
The package is on npm. Point each stdio MCP host at `npx -y keynote-harvest-mcp`;
the first run downloads it, later runs use the cache. GUI hosts may not
inherit your shell's PATH, so give them the absolute `npx` executable
(`command -v npx`). To run from a local checkout instead, see "Local build"
at the end of this section.
### Claude Code
```bash
claude mcp add keynote-harvest \
-e KEYNOTE_HARVEST_WORKING_DIRECTORY=/path/to/your/working-directory \
-e KEYNOTE_HARVEST_ROOT=.harvests \
-e KEYNOTE_HARVEST_ALLOWED_INPUT_ROOTS=/path/to/your/decks \
-- npx -y keynote-harvest-mcp
```
Use `--scope user` when the server should be available outside the current
project, and verify the registration with `claude mcp get keynote-harvest`.
### Claude Desktop
Add this server to `claude_desktop_config.json` through Claude Desktop's
developer settings, then fully quit and relaunch the application:
```json
{
"mcpServers": {
"keynote-harvest": {
"command": "/absolute/path/to/npx",
"args": ["-y", "keynote-harvest-mcp"],
"env": {
"KEYNOTE_HARVEST_WORKING_DIRECTORY": "/path/to/your/working-directory",
"KEYNOTE_HARVEST_ROOT": ".harvests",
"KEYNOTE_HARVEST_ALLOWED_INPUT_ROOTS": "/path/to/your/decks"
}
}
}
}
```
Claude Desktop stops every tool call at roughly four minutes, so harvest
long decks with `runInBackground: true` and poll `get_harvest_manifest`.
### Cursor
Create `.cursor/mcp.json` in a project, or `~/.cursor/mcp.json` for a global
configuration:
```json
{
"mcpServers": {
"keynote-harvest": {
"command": "/absolute/path/to/npx",
"args": ["-y", "keynote-harvest-mcp"],
"env": {
"KEYNOTE_HARVEST_WORKING_DIRECTORY": "/path/to/your/working-directory",
"KEYNOTE_HARVEST_ROOT": ".harvests",
"KEYNOTE_HARVEST_ALLOWED_INPUT_ROOTS": "/path/to/your/decks"
}
}
}
}
```
### Codex CLI
Register the server with `codex mcp add` (stdio transport):
```bash
codex mcp add keynote-harvest \
--env KEYNOTE_HARVEST_WORKING_DIRECTORY=/path/to/your/working-directory \
--env KEYNOTE_HARVEST_ROOT=.harvests \
--env KEYNOTE_HARVEST_ALLOWED_INPUT_ROOTS=/path/to/your/decks \
-- npx -y keynote-harvest-mcp
```
Two Codex behaviors to know: the harvest and export tools are annotated
`destructiveHint: true`, so Codex asks for approval before running them —
non-interactive `codex exec` sessions with `approval: never` cancel them
("user cancelled MCP tool call") unless approvals are bypassed. And Codex
exposes MCP tools only, not resources; read results through
`get_harvest_manifest` and the harvest directory. Codex's default per-call limit is 300 s; raise it
for long decks with `mcp_servers.keynote-harvest.tool_timeout_sec`, or use
`runInBackground: true` and poll.
### Local build
To run from a checkout instead of npm:
```bash
cd /absolute/path/to/keynote-harvest-mcp
npm ci
npm run build
```
Then use `/absolute/path/to/node /absolute/path/to/keynote-harvest-mcp/dist/index.js`
as the command in any of the configurations above, keeping the same `env`.
### Not supported: ChatGPT
ChatGPT connects only to remote (HTTP) MCP servers. This package is a local
stdio server by design — no network, and native export needs Keynote on the
same Mac — so ChatGPT is out of scope for v0.1.
The package resolves relative paths from the caller's current directory. Set `KEYNOTE_HARVEST_WORKING_DIRECTORY` when an MCP host should use a different working directory. Local source files must be inside the working directory, harvest root, or a path-delimited `KEYNOTE_HARVEST_ALLOWED_INPUT_ROOTS` entry. The server returns harvest-relative artifact paths and resource URIs rather than absolute paths.
Native export returns `exportedPdfHarvestPath`, which can be passed to `harvest_keynote_pdf` as `harvestPdfPath`. `get_harvest_manifest` accepts a harvest `slug`, not an arbitrary manifest file path.
Tool responses are summaries, not the manifest. Every response carries a `responseKind`: `harvest-summary` and `export-summary` from the write tools, `manifest-summary` from `get_harvest_manifest` (its `source` block is a flattened projection — `sourceId`, `sourceKind`, `sourceDisplayName`, `harvestTool` — of the manifest's `source`), and `job-record` / `job-status` for background jobs. The manifest itself, with its schema-defined field names, is the `keynote-harvest://<slug>/keynote-harvest-manifest.json` resource.
Keynote app selection trusts only bundles that carry an allowlisted identifier *and* an Apple first-party code signature — the `codesign` leaf authority must be "Apple Mac OS Application Signing" or "Software Signing"; Developer ID apps chain to Apple Root CA too, so the root alone proves nothing, and a bundle identifier alone is a claim any app can make. Set `KEYNOTE_HARVEST_ALLOW_UNSIGNED_KEYNOTE=1` only for deliberately unsigned builds.
GUI-launched MCP hosts often start servers with a minimal PATH. The package compensates: worker processes run under the server's own Node binary, and Poppler lookups also search `/opt/homebrew/bin`, `/usr/local/bin`, and `/opt/local/bin`. If Poppler lives elsewhere, set `KEYNOTE_HARVEST_POPPLER_PATH` to its directory. Workers receive a minimal environment rather than inheriting unrelated host secrets. Exports that finish with a Keynote error or timeout replace a previous PDF only after `pdfinfo` verifies the new file, so partial-export recovery requires Poppler. Long-running tool calls stream MCP progress notifications when the host requests them (a `progressToken` on the call): per-page updates during harvests, and a heartbeat during Keynote exports tunable via `KEYNOTE_HARVEST_PROGRESS_HEARTBEAT_MS`. Progress only helps hosts that reset their request timer on it (Claude Code does; set `MCP_TOOL_TIMEOUT` there to raise its ceiling). Hosts with a fixed cap — Claude Desktop stops every tool call at roughly four minutes — should pass `runInBackground: true` to `harvest_keynote_pdf` or `export_keynote_to_pdf`: the call returns immediately with a job record, the worker runs detached under `<harvest root>/.jobs/`, and `get_harvest_manifest` with the same slug reports `running` with page progress until the result lands, then returns the manifest for harvests or the export result (`exportedPdfHarvestPath`) for exports, or the job's error. Long-running workers are killed as a process group after 10 minutes by default (`KEYNOTE_HARVEST_COMMAND_TIMEOUT_MS`), and detached background workers enforce the same total budget themselves between steps, recording a failed job when it is exceeded; outpuLo que la gente pregunta sobre keynote-harvest-mcp
¿Qué es hulin42/keynote-harvest-mcp?
+
hulin42/keynote-harvest-mcp es mcp servers para el ecosistema de Claude AI. MCP server that harvests Keynote and PDF slide decks into slide previews, extracted text, embedded-image assets, and a versioned manifest. PDF-first anywhere; native .key export via Keynote on macOS. Tiene 0 estrellas en GitHub y su última actualización registrada es del 2026-09-02.
¿Cómo se instala keynote-harvest-mcp?
+
Puedes instalar keynote-harvest-mcp clonando el repositorio (https://github.com/hulin42/keynote-harvest-mcp) o siguiendo las instrucciones del README en GitHub. ClaudeWave también te ofrece bloques de instalación rápida en esta misma página.
¿Es seguro usar hulin42/keynote-harvest-mcp?
+
Nuestro agente de seguridad ha analizado hulin42/keynote-harvest-mcp y le ha asignado un Trust Score de 87/100 (tier: Trusted). Revisa el desglose completo de comprobaciones superadas y flags en esta página.
¿Quién mantiene hulin42/keynote-harvest-mcp?
+
hulin42/keynote-harvest-mcp es mantenido por hulin42. La última actividad registrada en GitHub es del 2026-09-02, con 0 issues abiertos.
¿Hay alternativas a keynote-harvest-mcp?
+
Sí. En ClaudeWave puedes explorar mcp servers similares en /categories/mcp, ordenados por popularidad o actividad reciente.
Despliega keynote-harvest-mcp en tu cloud
Lleva este repo a producción en minutos. Cada plataforma genera su propio entorno con variables de entorno editables.
¿Mantienes este repo? Añade un badge a tu README
Pega el badge en tu README de GitHub para mostrar que está auditado por ClaudeWave. Cada badge enlaza de vuelta a esta página y muestra el Trust Score actual.
[](https://claudewave.com/repo/hulin42-keynote-harvest-mcp)<a href="https://claudewave.com/repo/hulin42-keynote-harvest-mcp"><img src="https://claudewave.com/api/badge/hulin42-keynote-harvest-mcp" alt="Featured on ClaudeWave: hulin42/keynote-harvest-mcp" width="320" height="64" /></a>Más MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
The fastest path to AI-powered full stack observability, even for lean teams.
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!