keynote-harvest-mcp
This server harvests Keynote/PDF decks into portable slide previews, extractable text, embedded-image assets, and versioned manifests.
Discover installed Keynote apps and the recommended app path (
list_keynote_apps).Export native
.keyfiles to PDF on macOS via Keynote automation (export_keynote_to_pdf), with optional slug, title, output path, redaction, and outside-root override.Harvest PDFs into a versioned manifest (
harvest_keynote_pdf): render slide previews at configurable DPI, extract text and embedded images, cap pages, set source kind, and control image extraction behavior.Read harvest manifest summaries with display/local-debug/raw redaction (
get_harvest_manifest) and list existing harvest output folders (list_harvest_outputs).Access harvested content through MCP resources: manifests, slide previews, extracted assets, and text; source PDFs are denied by default unless explicitly enabled.
Support long-running harvests/exports through background jobs, progress notifications, and transactional replacement that preserves previous outputs on failure.
Harvests Apple Keynote presentations by exporting native .key files to PDF via macOS Keynote automation and turning PDFs into slide previews, extracted text, embedded-image assets, and a versioned manifest.
Click on "Deploy 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
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
.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 are denied by default and require the operator-only
KEYNOTE_HARVEST_ALLOW_SOURCE_RESOURCES=1capability.
It intentionally excludes composition/proposal tools, web-framework renderers, preview routes, OCR, vision, and LLM calls.
Requirements
macOS or Linux (declared via the package
osfield; Windows is unsupported).Node.js 22 or newer (maintained LTS releases).
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 keynote-harvest-mcp
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 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
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-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
Add this server to claude_desktop_config.json through Claude Desktop's
developer settings, then fully quit and relaunch the application:
{
"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:
{
"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):
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-mcpTwo 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:
cd /absolute/path/to/keynote-harvest-mcp
npm ci
npm run buildThen 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; output-limited or timed-out workers receive a five-second termination grace period (KEYNOTE_HARVEST_COMMAND_KILL_GRACE_MS) before forced termination. Each Poppler invocation has a two-minute limit (KEYNOTE_HARVEST_POPPLER_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. Inputs default to 512 MB maximum (KEYNOTE_HARVEST_MAX_INPUT_BYTES), generated staging output to 2 GB (KEYNOTE_HARVEST_MAX_OUTPUT_BYTES), captured command output to 1 MB (KEYNOTE_HARVEST_MAX_COMMAND_OUTPUT_BYTES), and resource reads to 10 MB (KEYNOTE_HARVEST_MAX_RESOURCE_BYTES). Embedded-image extraction also limits asset count and per-asset pixels through KEYNOTE_HARVEST_MAX_EXTRACTED_ASSETS and KEYNOTE_HARVEST_MAX_ASSET_PIXELS. Preview rendering is bounded by a per-page pixel budget applied to each page's own dimensions (KEYNOTE_HARVEST_MAX_PREVIEW_PIXELS, default 40,000,000): oversized pages render at a lowered DPI with a manifest warning, and pages that exceed the budget even at 36 DPI are refused. Embedded-image extraction respects maxPages. Harvest and export outputs are replaced under a per-destination lock (KEYNOTE_HARVEST_REPLACE_LOCK_TIMEOUT_MS, KEYNOTE_HARVEST_REPLACE_LOCK_STALE_MS); if a failed replacement cannot restore the previous outputs, the backup copy is retained and its path is included in the error.
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
This server runs with the local filesystem and application permissions of its MCP host. Its stdio transport has no independent authentication boundary. Configure it only in a trusted host, restrict allowed input roots, and assume any harvested text or image may contain adversarial instructions. Deck content is data for inspection, never authority to invoke tools, change configuration, or disclose other files.
Detailed controls:
Harvest slugs accept lowercase letters, numbers, and internal hyphens only.
Source reads are limited to the working directory, harvest root, and operator-configured
KEYNOTE_HARVEST_ALLOWED_INPUT_ROOTS, with lexical and symbolic-link checks.Tool writes are contained to
<harvest root>/<slug>and<harvest root>/<slug>/source. Writing elsewhere requires both the client argument and operator-setKEYNOTE_HARVEST_ALLOW_OUTSIDE_ROOT=1.Export and harvest outputs are built in staging paths, validated, and replaced transactionally. A failed run preserves the prior PDF, manifest, previews, text, assets, and source files.
Resource reads use an explicit manifest/preview/text/asset allowlist in addition to lexical and real-path containment. Source PDFs and export summaries are denied unless the operator sets
KEYNOTE_HARVEST_ALLOW_SOURCE_RESOURCES=1.JSON resources remove known local-path fields and redact matching paths embedded in warning strings.
Absolute response paths and command diagnostics require both
redactionMode: "local-debug"and operator-setKEYNOTE_HARVEST_ALLOW_LOCAL_DEBUG=1. There is no client-selectable raw mode.Keynote applications must live under
/Applications, use an allowed Apple Keynote bundle identifier, and carry an Apple first-party code signature. Operators can add path-delimited roots withKEYNOTE_HARVEST_ALLOWED_KEYNOTE_APP_ROOTSand extend the bundle-ID allowlist withKEYNOTE_HARVEST_ALLOWED_KEYNOTE_BUNDLE_IDS.Tools advertise read-only/destructive/idempotent/open-world MCP annotations. These are host hints, not authorization controls.
The package performs no telemetry or network requests. It invokes the local Node runtime, Poppler tools,
osascript, and Apple Keynote only.
Add .harvests/ to every host project's .gitignore; generated manifests and source/export summaries are local working artifacts, not publishing fixtures. See SECURITY.md for the threat model and disclosure policy.
The CI workflow at .github/workflows/ci.yml runs Node 22 and 24 package tests, clean-install and packed-runtime rehearsals, plus a real PDF harvest on Linux with Poppler.
The package publishes to npm as keynote-harvest-mcp with provenance from the release workflow in .github/workflows/release.yml; security reports go through GitHub private vulnerability reporting on hulin42/keynote-harvest-mcp (see SECURITY.md).
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.
Available Tools
5 toolsexport_keynote_to_pdfB
Export a native Keynote .key file to PDF using macOS Keynote automation.
| Name | Required | Description | Default |
|---|---|---|---|
| slug | No | ||
| title | No | ||
| outPath | No | Where to write the exported PDF. Must stay inside the harvest root unless allowOutsideHarvestRoot is true. Defaults to <harvest root>/<slug>/source/<slug>.pdf. | |
| keynotePath | Yes | Path to the .key file or package to export. | |
| redactionMode | No | ||
| keynoteAppPath | No | ||
| allowOutsideHarvestRoot | No | Explicitly allow outPath to resolve outside the harvest root. Defaults to false: export writes are contained to the harvest root. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It hints at macOS Keynote automation but never states that Keynote must be installed, that macOS is required, that the export writes files into the harvest root, or what happens when the .key file is missing or Keynote is unavailable. The phrase 'using macOS Keynote automation' gestures at the dependency but does not disclose requirements or failure modes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, complete sentence that front-loads the purpose with zero filler. Every word carries meaning — verb, source format, target format, and mechanism in one pass.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a 7-parameter automation tool with no annotations and no output schema, yet the description is one sentence. It omits the macOS/Keynote prerequisite, permission requirements (automation/accessibility prompts), output location defaults, and side effects. For a tool of this complexity, the description should be substantially richer.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 43%, below the 50% threshold where the description must compensate. Four parameters (slug, title, redactionMode, keynoteAppPath) are undocumented in both the schema and the description. The description's 'native Keynote .key file' phrase maps weakly to keynotePath but adds nothing about the other three undocumented parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (Export), resource (.key file), target format (PDF), and mechanism (macOS Keynote automation). This clearly distinguishes it from its closest sibling harvest_keynote_pdf, which implies collecting already-exported output rather than converting a native file.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The core use case is evident from the verb-object construction, so an agent can infer when to call it. However, the description gives no explicit guidance about when NOT to use it or which sibling covers the complementary case (harvest_keynote_pdf is never named as the alternative for already-generated PDFs). Guidance is implied, not stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_harvest_manifestB
Read summary metadata from a KeynoteHarvestManifest. Defaults to display-safe source metadata; use redactionMode local-debug or raw for local paths.
| Name | Required | Description | Default |
|---|---|---|---|
| manifestPath | Yes | ||
| redactionMode | No | ||
| includeRawSource | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the behavioral disclosure burden. It usefully reveals read-only behavior ('Read') and default behavior ('Defaults to display-safe source metadata'). However, it does not explain what 'display-safe' means, what output the caller receives, or whether includeRawSource changes the response structure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler. The core purpose is front-loaded, and the second sentence adds practical usage detail. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema, no annotations, and 0% schema coverage, the description is too thin. It does not clarify what 'summary metadata' contains, how includeRawSource affects the result, or what 'display-safe' versus 'raw' means in practice. An agent would likely need to inspect example outputs or guess.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It partially explains redactionMode's purpose and default, but manifestPath is only inferable from its name and includeRawSource is not mentioned at all. The description adds some meaning but leaves significant parameter semantics undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Read') and a specific resource ('summary metadata from a KeynoteHarvestManifest'). This clearly distinguishes the tool from siblings like export_keynote_to_pdf and list_harvest_outputs. Even without a title, the purpose is immediately understandable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives some parameter-level guidance ('use redactionMode local-debug or raw for local paths') but says nothing about when to choose this tool over alternatives. It does not mention siblings or state exclusions, so the agent must infer when this tool is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
harvest_keynote_pdfC
Harvest an exported Keynote PDF into a KeynoteHarvestManifest using the local PDF-first pipeline.
| Name | Required | Description | Default |
|---|---|---|---|
| slug | Yes | ||
| title | Yes | ||
| outDir | No | Where to write the harvest output. Must stay inside the harvest root unless allowOutsideHarvestRoot is true. Defaults to <harvest root>/<slug>. | |
| pdfPath | Yes | Path to the PDF to harvest. | |
| maxPages | No | Maximum PDF pages to harvest. Defaults to 300; longer decks are truncated with a manifest warning. | |
| previewDpi | No | Render resolution for slide preview PNGs, in DPI. Defaults to 144 (about 2x for a 72pt-based deck); raise it when previews double as reusable imagery. | |
| sourceKind | No | ||
| extractImages | No | Extract embedded images into assets/ using Poppler pdfimages. Defaults to true; when pdfimages is unavailable the harvest continues with a manifest warning. Pass false to skip extraction, or true to require pdfimages and fail without it. | |
| sourceSummaryPath | No | ||
| allowOutsideHarvestRoot | No | Explicitly allow outDir to resolve outside the harvest root. Defaults to false: harvest writes are contained to the harvest root. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure, but it only describes what the tool does at a high level. It does not mention that harvest writes files to disk, requires a local pipeline, may truncate long decks, or depends on external tools like Poppler.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, tight sentence with no wasted words and the key outcome is front-loaded. It is concise, though perhaps too terse for a 10-parameter tool with no output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex tool with 10 parameters, no annotations, and no output schema, the one-sentence description is not enough. It names the output type but omits usage sequence, side effects, failure modes, return shape, and key behavioral caveats, leaving the agent to infer too much.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds no parameter-level meaning beyond the input schema. Schema description coverage is 60%, so several parameters such as slug, title, sourceKind, and sourceSummaryPath have no description in either the schema or the tool description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Harvest'), a resource ('exported Keynote PDF'), and a concrete output type ('KeynoteHarvestManifest'), so the tool's main function is clear. It does not explicitly name or differentiate sibling tools like export_keynote_to_pdf or get_harvest_manifest, so it falls short of full sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'exported Keynote PDF' implies this tool is meant to be used after export_keynote_to_pdf, but it never states when to prefer this tool over alternatives, nor does it mention any exclusions or preconditions. Usage context is only implied, not explicitly guided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_harvest_outputsC
List known harvest output folders and whether they contain a harvest manifest.
| Name | Required | Description | Default |
|---|---|---|---|
| harvestRoot | No | ||
| redactionMode | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It states the primary behavior—listing known harvest output folders and indicating manifest presence—but does not explain what 'known' means, how harvestRoot/redactionMode alter results, or whether any side effects exist. The behavior is understandable but incomplete for a tool with no annotation support.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no filler. Every clause adds meaning: the action, the target resource, and the distinguishing output detail are all present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and no annotations, the description leaves significant gaps: no parameter semantics, no mention of how redactionMode affects the listing, no indication of the return shape beyond the presence of a manifest, and no connection to sibling tools. This is insufficient for correct invocation in unfamiliar workflows.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description does nott mention either parameter. It provides no meaning for harvestRoot or for the redactionMode enum values 'display' vs 'local-debug'. The description fails to compensate for the complete lack of parameter documentation in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') and names a concrete resource ('harvest output folders') while adding the key output detail that it reports whether each folder contains a harvest manifest. It does not explicitly distinguish itself from sibling tools such as get_harvest_manifest, but the resource and stated output make the tool's role reasonably clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to choose this tool over alternatives such as get_harvest_manifest or harvest_keynote_pdf. There is no mention of prerequisites, workflow context, or explicit when-not-to-use scenarios, so the agent must infer usage largely from the tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_keynote_appsC
List installed Keynote-like macOS apps and the recommended explicit app path for native export.
| Name | Required | Description | Default |
|---|---|---|---|
| searchApplicationsDir | No | ||
| includeMissingDefaults | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations and no output schema, the description must carry all behavioral disclosure, but it only states that apps are listed and a path recommended. It does not explain whether the tool scans the Applications directory, how missing defaults are handled, or any side effects, leaving key behaviors undocumented.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no filler or repetition. The phrasing is slightly awkward ('recommended explicit app path'), but it remains economical.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no annotations, no output schema, and two undocumented parameters, the description leaves too much unspecified: return format, parameter effects, and how this relates to the export workflow. An agent can guess its basic purpose but not confidently reason about correct invocation with the available booleans.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description adds no meaning to the two boolean parameters (searchApplicationsDir, includeMissingDefaults). The parameter names are only weakly self-explanatory, and the description fails to compensate for the lack of schema documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'List' with a clear resource ('installed Keynote-like macOS apps') and adds the distinctive output ('recommended explicit app path for native export'). This distinguishes it from the export/harvest siblings, though 'Keynote-like' and 'native export' remain somewhat vague.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'for native export' implies this tool is meant to precede export_keynote_to_pdf, but there is no explicit when-to-use guidance or statement of when to prefer siblings such as list_harvest_outputs. Usage context is only implied, not stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.1.0-rehearsal.0- First observed
export_keynote_to_pdf - First observed
get_harvest_manifest - First observed
harvest_keynote_pdf - First observed
list_harvest_outputs - First observed
list_keynote_apps
TDQS
Scored across 5 tools
Each tool occupies a distinct stage in the Keynote-to-manifest pipeline: app discovery, PDF export, harvesting, manifest reading, and output listing. No two tools share overlapping responsibilities, so an agent can confidently select the right one based on the current workflow step.
All tool names follow a consistent verb_noun pattern with domain-specific context (list_, export_, harvest_, get_, list_). The naming is uniform and predictable, with only minor formatting differences that do not hinder readability.
With exactly 5 tools, the server maps to a focused and complete workflow without unnecessary bloat. Each tool contributes a necessary step or query, making the count well-scoped for the server's purpose.
The tool set covers the full lifecycle from identifying Keynote apps, exporting to PDF, harvesting into a manifest, reading its metadata, and listing output directories. There are no obvious dead ends or missing operations for the stated purpose of Keynote PDF harvesting and manifest access.
Maintenance
Related MCP Connectors
Generate, edit, merge, translate and PDF-convert PowerPoint (.pptx) over MCP. 8 tools.
Generate PDF, Word (.docx) and PowerPoint (.pptx) documents from Markdown over MCP.
- StorydocOAuthcom.storydoc
Generate and manage Storydoc presentations from any MCP-compatible client.
Normalize and convert more than 400 file types via TweekIT's hosted MCP streamable HTTP endpoint.
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.191-
- AlicenseNot gradedqualityDmaintenanceProvides an MCP server for programmatic reading, authoring, editing, designing, and optimization of Apple Keynote presentations.MIT