keynote-harvest-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@keynote-harvest-mcpExtract images and text from my keynote deck"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Keynote Harvest MCP
This directory is the standalone keynote-harvest-mcp package, currently private and pending extraction to its own repository. It is intentionally separate from the existing mcp/keynote-case-study compatibility server while both remain in this branch.
It contains only the harvest-first MCP boundary:
Keynote app discovery.
Native
.keyto 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 stay readable by URI but are unlisted by default (
KEYNOTE_HARVEST_LIST_SOURCE=1lists them); a full deck as a base64 blob can exceed MCP host message limits.
It intentionally excludes CaseStudyComposition, proposals, portfolio preview routes, React/Next.js, and host preview hints. The existing server remains the compatibility and portfolio-example host while this package is hardened.
Requirements
macOS or Linux (declared via the package
osfield; Windows is unsupported).Node.js 20 or newer.
Poppler commands
pdfinfo,pdftoppm, andpdftotextfor PDF harvests.Poppler
pdfimagesfor embedded-image asset extraction, which is on by default. Withoutpdfimagesthe harvest still completes and records a manifest warning; passextractImages: false(CLI:--no-extract-images) to skip extraction, orextractImages: true(CLI:--extract-images) to requirepdfimagesand fail when it is missing.macOS, Keynote, and Automation permission for native
.keyexport only.
PDF harvesting can run without Keynote. OCR, vision, LLM calls, .key package parsing, and presenter-note extraction are intentionally absent.
Related MCP server: keynote-mcp
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
cd mcp/keynote-harvest
npm ci
npm run build
npm testnpm run test:clean-install copies the package to a temporary directory, runs npm ci, rebuilds it, and executes the package-owned tests without access to the portfolio repo's 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 a public-safe one-page PDF, harvests it through the compiled tool and local Poppler commands, validates the resulting v1 manifest, and removes all temporary output.
The built server and tools execute JavaScript from dist/; they do not execute source TypeScript at runtime.
Quickstart
Until the package is published, build it locally and point each stdio MCP host at the compiled entrypoint:
cd /absolute/path/to/keynote-harvest-mcp
npm ci
npm run buildReplace /absolute/path/to/node with the output of command -v node. GUI
hosts should use that absolute executable path because they may not inherit
your shell's PATH.
Claude Code
Local build:
claude mcp add keynote-harvest \
-e KEYNOTE_HARVEST_WORKING_DIRECTORY=/path/to/your/working-directory \
-e KEYNOTE_HARVEST_ROOT=.harvests \
-- /absolute/path/to/node \
/absolute/path/to/keynote-harvest-mcp/dist/index.jsAfter publish:
claude mcp add keynote-harvest \
-e KEYNOTE_HARVEST_WORKING_DIRECTORY=/path/to/your/working-directory \
-e KEYNOTE_HARVEST_ROOT=.harvests \
-- npx -y keynote-harvest-mcpUse --scope user when the server should be available outside the current
project, and verify the registration with claude mcp get keynote-harvest.
Claude Desktop
For a local build, add this server to claude_desktop_config.json through
Claude Desktop's developer settings, then restart the application:
{
"mcpServers": {
"keynote-harvest": {
"command": "/absolute/path/to/node",
"args": ["/absolute/path/to/keynote-harvest-mcp/dist/index.js"],
"env": {
"KEYNOTE_HARVEST_WORKING_DIRECTORY": "/path/to/your/working-directory",
"KEYNOTE_HARVEST_ROOT": ".harvests"
}
}
}
}After publish, replace command and args with an absolute npx executable
and the package invocation:
{
"command": "/absolute/path/to/npx",
"args": ["-y", "keynote-harvest-mcp"]
}Keep the same env object in the published configuration.
Cursor
For a local build, create .cursor/mcp.json in a project, or
~/.cursor/mcp.json for a global configuration:
{
"mcpServers": {
"keynote-harvest": {
"command": "/absolute/path/to/node",
"args": ["/absolute/path/to/keynote-harvest-mcp/dist/index.js"],
"env": {
"KEYNOTE_HARVEST_WORKING_DIRECTORY": "/path/to/your/working-directory",
"KEYNOTE_HARVEST_ROOT": ".harvests"
}
}
}
}After publish, replace command and args as shown in the Claude Desktop
published configuration. Keep the same env object.
The package resolves relative input and output paths from the caller's current directory. Set KEYNOTE_HARVEST_WORKING_DIRECTORY when an MCP host should use a different working directory. KEYNOTE_HARVEST_ROOT, KEYNOTE_HARVEST_RESOURCE_SCHEME, and KEYNOTE_HARVEST_LIST_SOURCE are configurable.
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. Long-running harvests are killed after 10 minutes by default; tune with KEYNOTE_HARVEST_COMMAND_TIMEOUT_MS.
Slide previews render at 144 DPI by default; pass previewDpi (36-600, CLI: --preview-dpi) to raise the resolution when previews double as reusable imagery. Harvests stop after 300 pages by default and record a truncation warning; pass maxPages (1-2000, CLI: --max-pages) to change the cap. Resource reads refuse files over 10 MB by default (KEYNOTE_HARVEST_MAX_RESOURCE_BYTES tunes the limit) so oversized blobs fail with a clear error instead of breaking the host.
Tool arguments are validated with zod against the same schemas advertised in tools/list; invalid calls fail fast with a field-by-field error message.
Security
Tool writes stay inside the configured harvest root unless a caller explicitly opts out. Agent-facing responses redact local paths by default, with clearly named debug modes for deliberate local inspection. Resource reads enforce lexical and symbolic-link containment, and source PDFs are unlisted by default.
Detailed controls:
Harvest slugs accept lowercase letters, numbers, and internal hyphens only.
Tool writes are contained:
export_keynote_to_pdfoutPathandharvest_keynote_pdfoutDirmust resolve inside the harvest root (lexically and through symbolic links). PassallowOutsideHarvestRoot: trueto write elsewhere deliberately. Source reads (keynotePath,pdfPath) are intentionally unrestricted.Resource reads enforce both lexical containment and real-path containment, including symbolic links.
JSON resources remove known local-path fields before returning content.
get_harvest_manifestdefaults to display-safe source metadata;local-debugandrawmodes are explicit.list_harvest_outputsdefaults to relative/display-safe output metadata. PassredactionMode: "local-debug"to include absolute local directories.export_keynote_to_pdfdefaults to display-safe source and application metadata. PassredactionMode: "local-debug"for explicitly labeled local paths and command output.
Manifest and output paths used to continue a local pipeline remain classified as internal output paths. Resource URIs are the portable artifact identifiers exposed to MCP clients.
The package-scoped workflow at .github/workflows/keynote-harvest.yml runs Node 20, 22, and 24 package tests, clean-install and packed-runtime rehearsals, plus a real PDF harvest on Linux with Poppler.
This package remains private and unpublished.
Transport
The server runs on the official @modelcontextprotocol/sdk stdio transport (newline-delimited JSON-RPC, protocol version negotiation, and ping handled by the SDK). The smoke tests and the packed-runtime rehearsal connect with the official SDK client, so a spec-compliant MCP handshake is exercised on every test run. An earlier private iteration used hand-rolled Content-Length framing, which no mainstream MCP host speaks; that layer is gone.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol server that enables AI assistants to control Keynote presentations through AppleScript automation, supporting slide operations, theme-aware content management, and export functions.11MIT
- MIT
- FlicenseAqualityCmaintenanceLocal macOS MCP server that reads, edits, and exports Apple Keynote presentations via JXA. Enables Claude to visually analyze slides, apply design changes, and iterate on presentations directly.19
- AlicenseNot gradedqualityBmaintenanceProvides an MCP server for programmatic reading, authoring, editing, designing, and optimization of Apple Keynote presentations.MIT
Related MCP Connectors
Normalize and convert more than 400 file types via TweekIT's hosted MCP streamable HTTP endpoint.
List, share, upload, and manage Slideless HTML presentations from any MCP host.
Create App Store screenshots, icons, ASO copy, localization, and revisions via hosted MCP.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/hulin42/keynote-harvest-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server