keynote-harvest-mcp について
keynote-harvest-mcp は、Keynote の書き出しファイルや PDF からプレビュー、テキスト、埋め込み画像、バージョン付きマニフェストを抽出するローカル stdio MCP サーバーです。OCR や LLM 処理を使わず、構造化されたスライド資料を扱うエージェント向けです。
主な機能
- 01macOS での Keynote から PDF への書き出し
- 02PDF のスライドプレビューとテキスト抽出
- 03埋め込み画像アセットの抽出
- 04バージョン付きマニフェストの生成と検証
- 05MCP 経由のマニフェストと成果物の読み取り
活用シーン
- 01スライドデッキのプレビュー画像作成
- 02スライドテキストと埋め込み画像の抽出
- 03マニフェストによる収集成果物の整理
- 04MCP 経由でのローカル収集結果の確認
MCP 対応
ローカルでの収集・書き出しツールと、マニフェスト、プレビュー、抽出画像、テキスト用の MCP リソースを提供します。ソース PDF はデフォルトで公開されません。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y keynote-harvest-mcpKEYNOTE_HARVEST_ALLOWED_INPUT_ROOTSシークレットPath-delimited directories the server may read decks from (e.g. your Keynote documents and Downloads). Required to harvest local files.KEYNOTE_HARVEST_ROOTシークレットDirectory where harvests are written. Defaults to .harvests under the working directory.KEYNOTE_HARVEST_WORKING_DIRECTORYシークレットDirectory relative paths resolve from. Defaults to the host's current directory.ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
5掲載時のツール一覧 · 3 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| redactionMode | enum | いいえ | display | local-debug |
| searchApplicationsDir | boolean | いいえ | |
| includeMissingDefaults | boolean | いいえ |
詳細
Keynote Harvest MCP
keynote-harvest-mcp は、Keynote のエクスポートデータや PDF を、持ち運び可能なスライドプレビュー、抽出可能なテキスト、埋め込み画像アセット、バージョン管理されたマニフェストに変換する、ローカルの stdio MCP サーバーです。
含まれるのは、収集を優先した MCP の境界のみです。
- Keynote アプリの検出。
- macOS でのネイティブな
.keyから PDF へのエクスポート。 - PDF を優先した収集によるプレビュー、抽出可能なテキスト、アセット、マニフェストの生成。
- 表示に安全なマニフェストの読み取り。
- ローカルの収集出力の一覧表示。
- マニフェスト、プレビュー、抽出した埋め込み画像アセット、抽出テキスト用の MCP リソース。ソース PDF はデフォルトで拒否され、オペレーター専用の
KEYNOTE_HARVEST_ALLOW_SOURCE_RESOURCES=1機能が必要です。
意図的に、作成・提案ツール、Web フレームワークのレンダラー、プレビュールート、OCR、ビジョン、LLM 呼び出しは含めていません。
要件
- macOS または Linux(パッケージの
osフィールドで宣言されています。Windows はサポート対象外です)。 - Node.js 22 以降(保守対象の LTS リリース)。
- PDF の収集には、Poppler のコマンド
pdfinfo、pdftoppm、pdftotextが必要です。 - 埋め込み画像アセットの抽出には Poppler の
pdfimagesが必要です。これはデフォルトで有効です。pdfimagesがない場合も収集は完了し、マニフェストに警告が記録されます。抽出をスキップするにはextractImages: false(CLI:--no-extract-images)を渡してください。pdfimagesがない場合に失敗させるには、extractImages: true(CLI:--extract-images)を渡してください。 - ネイティブな
.keyのエクスポートに限り、macOS、Keynote、Automation の権限が必要です。
PDF の収集は Keynote なしで実行できます。OCR、ビジョン、LLM 呼び出し、.key パッケージの解析、発表者ノートの抽出は意図的に含めていません。
マニフェストの契約
新しい収集では schemaVersion: "keynote-harvest-manifest-v1" を使用します。このパッケージでは、この契約に沿った 3 つの表現を管理しています。
src/types/にある TypeScript 型。src/schema/にある実行時の構造検証。schema/keynote-harvest-manifest-v1.schema.jsonにある配布可能な Draft 2020-12 JSON Schema。
実行時のバリデーターでは、デフォルトでバージョンが必須です。明示的な allowLegacyVersion オプションは、スキーマのバージョン管理導入前に作成された古い非公開マニフェストを検査する場合にのみ使用できます。新しく生成されるマニフェストには、常にバージョンが付与されます。
スキーマの進化
追加のみで省略可能なフィールドは、
keynote-harvest-manifest-v1 を変更せずに導入できます。互換性を損なう契約変更では、
別のスキーマファイルとともに keynote-harvest-manifest-v2 を新たに作成する必要があります。一方、
実行時のバリデーターでは、引き続き v1 の読み取りをサポートします。allowLegacyVersion は、
バージョン管理導入前の非公開マニフェストに限って使用でき、バージョン管理されたスキーマの
移行の代わりにはなりません。
インストール、ビルド、テスト
cd keynote-harvest-mcp
npm ci
npm run build
npm test
npm run test:clean-install はパッケージを一時ディレクトリにコピーし、npm ci を実行して再ビルドした後、このチェックアウトにインストール済みの依存関係から隔離された状態で、パッケージに含まれるテストを実行します。
npm run test:packed-runtime はローカルの tarball をビルドし、空のコンシューマープロジェクトにインストールして、インストールされたバイナリを起動し、パッケージ化されたツールのインターフェースを検証します。どちらのリハーサルでも、何かが公開されることはありません。
npm run test:pdf-runtime は一般公開しても安全な PDF を生成し、ローカルの Poppler コマンドを使って置換とクォータ超過による失敗を検証し、パスセーフな v1 マニフェストを検証して、一時出力をすべて削除します。
ビルド済みのサーバーとツールは dist/ の JavaScript を実行します。実行時にソースの TypeScript を実行することはありません。
クイックスタート
このパッケージは npm で公開されています。各 stdio MCP ホストに npx -y keynote-harvest-mcp を指定してください。
初回の実行時にダウンロードされ、以降はキャッシュが使用されます。GUI ホストではシェルの PATH が
引き継がれない場合があるため、npx の絶対パスを指定してください
(command -v npx)。代わりにローカルのチェックアウトから実行する場合は、このセクションの最後にある「ローカルビルド」を参照してください。
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-mcp
サーバーを現在のプロジェクト以外でも利用できるようにするには --scope user を使用し、
claude mcp get keynote-harvest で登録を確認してください。
Claude Desktop
Claude Desktop の開発者設定から claude_desktop_config.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 は各ツール呼び出しをおよそ 4 分で停止するため、長いデッキは
runInBackground: true で収集し、get_harvest_manifest をポーリングしてください。
Cursor
プロジェクト内に .cursor/mcp.json を作成するか、グローバル設定として
~/.cursor/mcp.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
stdio トランスポートを使用して、codex mcp add でサーバーを登録します:
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
知っておくべき Codex の動作が 2 つあります。収集ツールとエクスポートツールには
destructiveHint: true の注釈が付いているため、Codex は実行前に承認を求めます。
そのため、approval: never を指定した非対話型の codex exec セッションでは、承認を
回避しない限り、これらのツールはキャンセルされます("user cancelled MCP tool call")。
また、Codex が公開するのは MCP ツールのみで、リソースは公開しません。結果は
get_harvest_manifest と収集ディレクトリから読み取ってください。Codex のデフォルトの
呼び出しごとの制限時間は 300 秒です。長いデッキの場合は
mcp_servers.keynote-harvest.tool_timeout_sec で延長するか、
runInBackground: true を使ってポーリングしてください。
ローカルビルド
npm の代わりにチェックアウトから実行するには:
cd /absolute/path/to/keynote-harvest-mcp
npm ci
npm run build
その後、上記いずれかの設定で、コマンドに /absolute/path/to/node /absolute/path/to/keynote-harvest-mcp/dist/index.js
を指定し、同じ env を維持してください。
非対応:ChatGPT
ChatGPT が接続できるのはリモート(HTTP)MCP サーバーのみです。このパッケージは 設計上、ローカルの stdio サーバーです。ネットワーク接続はなく、ネイティブエクスポートには 同じ Mac 上の Keynote が必要なため、v0.1 では ChatGPT は対象外です。
このパッケージは、呼び出し元の現在のディレクトリを基準に相対パスを解決します。MCP ホストで
別の作業ディレクトリを使用する場合は、KEYNOTE_HARVEST_WORKING_DIRECTORY を設定してください。
ローカルのソースファイルは、作業ディレクトリ、収集ルート、またはパス区切りの
KEYNOTE_HARVEST_ALLOWED_INPUT_ROOTS エントリ内に配置する必要があります。サーバーは
絶対パスではなく、収集ルートからの相対アーティファクトパスとリソース URI を返します。
ネイティブエクスポートは exportedPdfHarvestPath を返します。この値は
harvest_keynote_pdf の harvestPdfPath として渡せます。get_harvest_manifest が受け取るのは
収集の slug であり、任意のマニフェストファイルパスではありません。
ツールの応答はマニフェストではなく要約です。すべての応答には responseKind が含まれます。
書き込みツールからは harvest-summary と export-summary、get_harvest_manifest からは
manifest-summary(その source ブロックは、マニフェストの source をフラット化して
投影したものです。フィールドは sourceId、sourceKind、sourceDisplayName、
harvestTool です)、バックグラウンドジョブからは job-record / job-status が返されます。
スキーマで定義されたフィールド名を持つマニフェスト本体は、
keynote-harvest://<slug>/keynote-harvest-manifest.json リソースにあります。
Keynote アプリの選択では、許可リストに登録された識別子と Apple ファーストパーティの
コード署名の両方を持つバンドルのみが信頼されます。codesign のリーフ権限は
"Apple Mac OS Application Signing" または "Software Signing" である必要があります。
Developer ID アプリも Apple Root CA までチェーンされるため、ルートだけでは何も証明できません。
また、バンドル識別子はどのアプリでも名乗ることができます。意図的に未署名のビルドに限り、
KEYNOTE_HARVEST_ALLOW_UNSIGNED_KEYNOTE=1 を設定してください。
GUI から起動された MCP ホストでは、サーバーの起動時に最小限の PATH が設定されることがよくあります。このパッケージでは、ワーカープロセスがサーバー自身の Node バイナリを使って実行され、Poppler の検索時には /opt/homebrew/bin、/usr/local/bin、/opt/local/bin も検索されます。Poppler がこれら以外の場所にある場合は、KEYNOTE_HARVEST_POPPLER_PATH にそのディレクトリを設定してください。ワーカーには、ホストの無関係なシークレットを引き継がず、最小限の環境変数のみが渡されます。Keynote のエラーまたはタイムアウトで終了したエクスポートでは、pdfinfo で新しいファイルが検証された後にのみ、以前の PDF が置き換えられます。そのため、部分的なエクスポートからの復旧には Poppler が必要です。ホストから要求された場合(呼び出しに progressToken が指定されている場合)、長時間実行されるツール呼び出しは MCP の進捗通知をストリーミングします。収集処理ではページごとの更新が、Keynote のエクスポートでは KEYNOTE_HARVEST_PROGRESS_HEARTBEAT_MS で調整可能なハートビートが送信されます。進捗通知によってリクエストタイマーをリセットするホストでのみ、この機能は役立ちます(Claude Code は対応しています。上限を引き上げるには、そこで MCP_TOOL_TIMEOUT を設定してください)。Claude Desktop のように実行時間に固定上限を設けているホストでは、すべてのツール呼び出しが約4分で停止します。その場合は harvest_keynote_pdf または export_keynote_to_pdf に runInBackground: true を指定してください。呼び出しはジョブレコードを返してすぐに終了し、ワーカーは <harvest root>/.jobs/ の下で切り離されて実行されます。同じ slug を指定した get_harvest_manifest は、結果が生成されるまでページの進捗とともに running を返し、その後、収集処理ではマニフェストを、エクスポートではエクスポート結果(exportedPdfHarvestPath)を返します。失敗した場合はジョブのエラーを返します。長時間実行されるワーカーは、デフォルトで10分後にプロセスグループごと終了します(KEYNOTE_HARVEST_COMMAND_TIMEOUT_MS)。切り離されたバックグラウンドワーカーは、各ステップの間に同じ合計実行時間の上限を適用し、上限を超えた場合はジョブを失敗として記録します。出力上限に達したワーカー、またはタイムアウトしたワーカーには、強制終了の前に5秒間の終了猶予期間が与えられます(KEYNOTE_HARVEST_COMMAND_KILL_GRACE_MS)。Poppler の各呼び出しには2分の制限があります(KEYNOTE_HARVEST_POPPLER_TIMEOUT_MS)。
スライドのプレビューは、デフォルトで144 DPIでレンダリングされます。プレビューを再利用可能な画像としても使う場合は、previewDpi(36~600、CLI:--preview-dpi)を指定して解像度を上げてください。収集処理は、デフォルトで300ページを超えると停止し、切り捨てに関する警告を記録します。上限を変更するには、maxPages(1~2000、CLI:--max-pages)を指定してください。入力の最大サイズはデフォルトで512 MB(KEYNOTE_HARVEST_MAX_INPUT_BYTES)、生成されるステージング出力は2 GB(KEYNOTE_HARVEST_MAX_OUTPUT_BYTES)、キャプチャされるコマンド出力は1 MB(KEYNOTE_HARVEST_MAX_COMMAND_OUTPUT_BYTES)、リソースの読み取りは10 MB(KEYNOTE_HARVEST_MAX_RESOURCE_BYTES)です。埋め込み画像の抽出では、KEYNOTE_HARVEST_MAX_EXTRACTED_ASSETS と KEYNOTE_HARVEST_MAX_ASSET_PIXELS によって、アセット数とアセットごとのピクセル数にも上限が設けられます。プレビューのレンダリングには、各ページ固有の寸法に適用されるページごとのピクセル数上限があります(KEYNOTE_HARVEST_MAX_PREVIEW_PIXELS、デフォルトは40,000,000)。上限を超えるページは DPI を下げてレンダリングされ、マニフェストに警告が記録されます。36 DPI でも上限を超えるページはレンダリングされません。埋め込み画像の抽出では maxPages が適用されます。収集およびエクスポートの出力は、出力先ごとのロックの下で置き換えられます(KEYNOTE_HARVEST_REPLACE_LOCK_TIMEOUT_MS、KEYNOTE_HARVEST_REPLACE_LOCK_STALE_MS)。置き換えに失敗し、以前の出力を復元できなかった場合は、バックアップコピーが保持され、そのパスがエラーに含まれます。
ツールの引数は、tools/list で公開されるものと同じスキーマに対して zod で検証されます。無効な呼び出しは、フィールドごとのエラーメッセージとともに即座に失敗します。
セキュリティ
このサーバーは、MCP ホストのローカルファイルシステムとアプリケーションの権限で動作します。stdio トランスポートには独立した認証境界がありません。信頼できるホストでのみ設定し、許可する入力ルートを制限してください。また、収集したテキストや画像には敵対的な指示が含まれている可能性があるものとして扱ってください。デッキの内容は調査対象のデータであり、ツールの呼び出し、設定の変更、ほかのファイルの開示を許可するものではありません。
詳細な制御:
- 収集スラッグに使用できるのは、小文字、数字、途中のハイフンのみです。
- ソースの読み取りは、作業ディレクトリ、収集ルート、オペレーターが設定した
KEYNOTE_HARVEST_ALLOWED_INPUT_ROOTSに制限され、字句解析とシンボリックリンクのチェックが行われます。 - ツールによる書き込み先は
<harvest root>/<slug>と<harvest root>/<slug>/sourceに限定されます。それ以外への書き込みには、クライアント引数とオペレーターが設定したKEYNOTE_HARVEST_ALLOW_OUTSIDE_ROOT=1の両方が必要です。 - エクスポートと収集の出力はステージングパスで作成、検証され、トランザクション方式で置き換えられます。実行に失敗しても、以前の PDF、マニフェスト、プレビュー、テキスト、アセット、ソースファイルは保持されます。
- リソースの読み取りには、字句解析と実パスの包含チェックに加えて、明示的なマニフェスト/プレビュー/テキスト/アセットの許可リストが適用されます。オペレーターが
KEYNOTE_HARVEST_ALLOW_SOURCE_RESOURCES=1を設定しない限り、ソース PDF とエクスポートの概要は拒否されます。 - JSON リソースから既知のローカルパスフィールドが削除され、警告文字列に含まれる一致パスも秘匿化されます。
- 絶対パスを含む応答とコマンド診断を出力するには、
redactionMode: "local-debug"と、オペレーターが設定したKEYNOTE_HARVEST_ALLOW_LOCAL_DEBUG=1の両方が必要です。クライアントが選択できる未加工モードはありません。 - Keynote アプリケーションは
/Applications内にあり、許可された Apple Keynote バンドル識別子を使用し、Apple のファーストパーティコード署名を持つ必要があります。オペレーターはKEYNOTE_HARVEST_ALLOWED_KEYNOTE_APP_ROOTSでパス区切りのルートを追加し、KEYNOTE_HARVEST_ALLOWED_KEYNOTE_BUNDLE_IDSでバンドル ID の許可リストを拡張できます。 - ツールは、読み取り専用/破壊的/冪等/オープンワールドを示す MCP アノテーションを提供します。これらはホスト向けのヒントであり、認可制御ではありません。
- このパッケージはテレメトリやネットワークリクエストを一切実行しません。呼び出すのはローカルの Node ランタイム、Poppler ツール、
osascript、Apple Keynote のみです。
すべてのホストプロジェクトの .gitignore に .harvests/ を追加してください。生成されたマニフェストとソース/エクスポートの概要はローカルの作業用アーティファクトであり、公開用のフィクスチャではありません。脅威モデルと開示ポリシーについては SECURITY.md を参照してください。
.github/workflows/ci.yml の CI ワークフローでは、Node 22 と 24 のパッケージテスト、クリーンインストールとパッケージ化済みランタイムのリハーサルに加え、Poppler を使用した Linux 上での実際の PDF 収集を実行します。
このパッケージは keynote-harvest-mcp として npm に公開され、.github/workflows/release.yml のリリースワークフローに由来するプロベナンスを伴います。セキュリティレポートは、hulin42/keynote-harvest-mcp の GitHub プライベート脆弱性報告を通じてお送りください(SECURITY.md を参照)。
トランスポート
このサーバーは、公式の @modelcontextprotocol/sdk stdio トランスポートを使用します(改行区切りの JSON-RPC、プロトコルバージョンのネゴシエーション、SDK が処理する ping)。スモークテストとパッケージ化済みランタイムのリハーサルでは、公式 SDK クライアントを使って接続するため、すべてのテスト実行で仕様に準拠した MCP ハンドシェイクが検証されます。以前の非公開の試作では独自に実装した Content-Length フレーミングを使用していましたが、主流の MCP ホストはこれに対応しておらず、このレイヤーは廃止されています。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。