mcpField
P
plan-to-eat

plan-to-eat

ローカル
github.com/alex-zwingliヘルスケア12 週間前に更新

plan-to-eat について

plan-to-eatは、Plan to Eatのアカウントを操作するMCPサーバー、CLI、Nodeクライアントです。献立を管理する人や料理向けエージェントが、レシピ、予定、残り物、冷凍庫の在庫、買い物リストを読み書きできます。

主な機能

  1. 01レシピと食材のCRUD
  2. 02献立イベントの管理
  3. 03買い物リストの編集
  4. 04残り物と冷凍分の追跡
  5. 05CLIとNodeクライアント

活用シーン

  1. 01取り込んだレシピの保存と整理
  2. 02献立の予定と分量の調整
  3. 03予定に基づく買い物リストの更新
  4. 04冷凍分と残り物の記録

MCP 対応

MCPクライアントに、レシピ、献立項目、買い物リスト、冷凍記録を読み書きする36個のツールを提供します。stdioで接続し、アカウントへのログインとセッション復旧を処理します。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"alex-zwingli-plan-to-eat": {
"command": "npx",
"args": [
"-y",
"plan-to-eat-mcp"
],
"env": {
"PLAN_TO_EAT_USERNAME": "<PLAN_TO_EAT_USERNAME>",
"PLAN_TO_EAT_PASSWORD": "<PLAN_TO_EAT_PASSWORD>",
"PLAN_TO_EAT_SESSION_FILE": "<PLAN_TO_EAT_SESSION_FILE>"
}
}
}
}
起動コマンドnpx -y plan-to-eat-mcp
設定が必要な環境変数
PLAN_TO_EAT_USERNAMEPlan to Eat login email
PLAN_TO_EAT_PASSWORDシークレットPlan to Eat password
PLAN_TO_EAT_SESSION_FILEWhere the cookie session is cached. Set to "" to disable caching.

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npmplan-to-eat-mcp0.8.0

ツール

36

掲載時のツール一覧 · 2 週間前に更新

このツールにパラメーターはありません。

詳細

🍽️ plan-to-eat-mcp

レシピを入力するのはやめて、話して伝えましょう。 お気に入りの LLM に、Plan to Eat のレシピブック、プランナー、 買い物リストへのアクセス権を渡しましょう — Model Context Protocol 経由で。

Claude、 ChatGPT、MCP 対応のアシスタント、またはお使いのシェルから、Plan to Eat アカウントに完全な読み書きアクセスを提供する、すぐに使える MCP サーバー、CLI、スタンドアロンの Node クライアントです。

You:  "Save the Bon Appétit miso pasta from this URL and tag it weeknight."
LLM:  ✓ created recipe #48,872,094 — 7 ingredients, 25 min, tagged weeknight.

You:  "Plan dinner around it Tuesday and add the missing pantry items to my
       shopping list."
LLM:  ✓ event created 2026-05-05 / dinner / 4 servings.
      ✓ shopping list now reflects miso, mirin, and dashi.

…何かに話しかけたくない場合は、こちらです:

$ plan-to-eat get-planner-week 2026-05-04
start_date  2026-05-04
end_date    2026-05-10

ID        DATE        SECTION    KIND        RECIPE_ID  RECIPE_TITLE        DESCRIPTION            SERVINGS
────────  ──────────  ─────────  ──────────  ─────────  ──────────────────  ─────────────────────  ────────
67698872  2026-05-05  breakfast  recipe      17314561   Breakfast Sandwich                         8
67483177  2026-05-05  dinner     ingredient                                 Asparagus (in season)  0
67710784  2026-05-06  dinner     note                                       Cucumber salad         0

3 rows

これだけです。レシピを再入力する必要も、URL をスマートフォンアプリにコピー&ペーストする必要もありません。ただ話しかけるだけです。


❤️ Plan to Eat をおすすめする理由

まだ使っていない方へ。Plan to Eat は、私が今まで使った中で本当に最高の献立計画アプリです:

  • どこからでも取り込めるレシピインポーター。実際のフードブログでもきちんと動作します。
  • ドラッグ&ドロップ式の週間プランナー。材料を自動的に買い物リストにまとめ、単位を賢く処理し、パントリー内の重複も排除します。
  • ずっと自分のもの — レシピブックは持ち運びやエクスポートが可能で、アルゴリズムに人質に取られることはありません。
  • 家族で使いやすい — アプリ内で友人とレシピやメニューを共有できます。
  • 14 日間の無料トライアル、クレジットカード不要。

👉 紹介リンクから登録 — トライアルを利用でき、私はささやかなお礼を受け取れます。お互いにうれしい仕組みです。


✨ できること

  • 🤖 すぐに使える MCP サーバー — Claude Desktop、Claude Code、OpenClaw、 または MCP 対応ホストから接続すれば、レシピブックに話しかけられます。
  • ⌨️ 同じツールを CLI からも利用可能 — すべての MCP ツールに plan-to-eat サブコマンドが用意されており、人間が読みやすい表形式と、スクリプト向けの --json に対応しています。両方のインターフェースで同じレジストリを使うため、食い違うことはありません。
  • 🔐 自動認証と自動復旧 — 認証情報を一度設定すれば、サーバーがログインを処理し、Cookie セッションをディスクにキャッシュして、Plan to Eat に無効化された際は自動で再認証します。
  • 🧰 重要な操作を網羅した 36 個のツール — レシピの完全な CRUD、食事プランナーの完全な CRUD(レシピ、メモ、材料項目の追加/移動/複製/削除)、同じ枠内のイベントの並べ替え、残り物を第一級のワークフローとして扱う機能、冷凍庫の管理、コース・料理ジャンル・タグの閲覧、キュー内の件数確認。
  • 🗓️ プランナーを自在に操作 — レシピ名をあらかじめ結合した週間プランの表示、日付を指定したレシピの予定登録、下ごしらえメモの追加、1 回のツール呼び出しでの予定変更、分量の変更、複製、重複検索、同じ枠内のイベントの並べ替え。
  • 🛒 実際に使いやすい買い物リスト — 各項目が登録されている店舗と売り場を含めて表示し、項目を追加(Plan to Eat が売り場を推測し、最後に選んだ店舗を再利用)、項目名や数量の変更、店舗間の項目の移動、削除、リストへの復元ができます。
  • ❄️ 冷凍庫の管理 — 調理後に freeze_recipe_portions で N 人分を冷凍済みとして記録できます。list_frozen_recipes で保管中のものを確認し、食べたら項目を消費済みにできます(ソフト削除され、履歴は保持されます)。
  • 🍳 本格的な CRUD — 適切な単位を使った材料リスト、作り方、下ごしらえ/調理時間、栄養情報、評価、タグを含みます。
  • 📦 軽量なランタイム — Playwright、ヘッドレスブラウザー、ネイティブモジュールは不要です。 fetch、MCP SDK、Zod のみを使用し、1 秒未満で起動します。
  • 🦺 TypeScript 100% — Recipe、Ingredient、PlannerEvent の各型と、汎用の _json<T> により、ツールが戻り値を推測する必要はありません。
  • 📚 ライブラリとしても利用可能 — core/client.ts は、あらゆるスクリプトに組み込める、シンプルな Node API クライアントです。
  • 🧠 Claude Code スキルを同梱 — .claude/skills/plan-to-eat/SKILL.md が、よくあるワークフローや注意点(supper と dinner の別名、description と title の不一致など)をエージェントに教えるため、ゼロから調べ直す必要がありません。

稼働中のウェブアプリをリバースエンジニアリングして作成しました。Plan to Eat の公開 API はありませんが、デスクトップサイトも内部では同じエンドポイントを使用しています。利用は自己責任でお願いします — これらはいつでも変更される可能性があります。


🚀 クイックスタート

npx -y plan-to-eat-mcp          # run the MCP server
npm i -g plan-to-eat-mcp        # …or install both bins on PATH

Node 18 以降(組み込みの fetch を使用するため)と、 Plan to Eat のアカウントが必要です。

このパッケージには、plan-to-eat-mcp(MCP サーバー)と plan-to-eat(CLI)の2つの実行ファイルが含まれています。インストールせずに npx で CLI を実行する場合は、 デフォルトの実行ファイルがサーバーなので、CLI を明示的に選択する必要があります。

npx -y -p plan-to-eat-mcp plan-to-eat --help
クローンからビルドする場合(開発用、または Claude Code プラグイン用)
git clone https://github.com/alex-zwingli/plan-to-eat-mcp.git
cd plan-to-eat-mcp
npm install
npm run build

ビルドでは CommonJS が dist/ に出力されます。

設定
変数必須デフォルト説明
PLAN_TO_EAT_USERNAMEはい—Plan to Eat のログイン用メールアドレス
PLAN_TO_EAT_PASSWORDはい—Plan to Eat のパスワード
PLAN_TO_EAT_SESSION_FILEいいえ~/.plan-to-eat-session.jsonCookie セッションのキャッシュ先です。キャッシュを無効にするには "" を設定します。

CLI は作業ディレクトリにある .env も読み込みます(シェル変数が優先されます)。MCP サーバーは読み込みません。以下に示すように、MCP ホストから環境変数を明示的に渡してください。


🤖 エージェントで使う

ローカル stdio MCP サーバーを起動できるホストであれば、どれでも動作します。サーバーに必要なのは1つのコマンドと2つの環境変数だけです。ポートも OAuth もデーモンも必要ありません。

Claude Code で簡単に使う:プラグインをインストールする

このリポジトリは Claude Code プラグインとして提供されており、MCP サーバーと両方のスキルを一度にインストールできます。

export [email protected]
export PLAN_TO_EAT_PASSWORD=hunter2

git clone https://github.com/alex-zwingli/plan-to-eat-mcp.git
cd plan-to-eat-mcp && npm install && npm run build

claude plugin marketplace add "$(pwd)"
claude plugin install plan-to-eat@plan-to-eat

次のコンポーネントがインストールされます。

コンポーネント内容
MCP サーバー plan-to-eat36 個すべてのツール
スキル plan-to-eatMCP ツールの効果的な使い方 — ワークフローと注意点
スキル plan-to-eat-cliCLI を操作するエージェント向けの同じ内容

claude plugin details plan-to-eat@plan-to-eat と claude mcp list で確認してください。 サーバーは Claude Code の起動時に設定されていた環境から PLAN_TO_EAT_USERNAME / PLAN_TO_EAT_PASSWORD を読み込みます。どこかにコミットするのではなく、シェルのプロファイルでエクスポートしてください。

Claude Code で手動設定する
claude mcp add plan-to-eat \
  --env [email protected] \
  --env PLAN_TO_EAT_PASSWORD=hunter2 \
  -- npx -y plan-to-eat-mcp

このプロジェクトだけでなく、すべてのプロジェクトで使えるようにするには --scope user を追加します。claude mcp list、またはセッション内で /mcp を実行して、接続を確認してください。

Claude Desktop

claude_desktop_config.json を編集します — Settings → Developer → Edit Config、または次の場所にあります。

  • macOS:~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows:%APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "plan-to-eat": {
      "command": "npx",
      "args": ["-y", "plan-to-eat-mcp"],
      "env": {
        "PLAN_TO_EAT_USERNAME": "[email protected]",
        "PLAN_TO_EAT_PASSWORD": "hunter2"
      }
    }
  }
}

Claude Desktop を再起動すれば、準備完了です。

その他の MCP ホスト

Cursor、Windsurf、Zed、Cline、Continue、OpenClaw、VS Code の MCP サポート、カスタム SDK クライアントは、いずれも同じ3つの項目を使います。次のように設定してください。

項目値
トランスポートstdio
コマンドnpx
引数["-y", "plan-to-eat-mcp"]
環境変数PLAN_TO_EAT_USERNAME、PLAN_TO_EAT_PASSWORD

多くのホストでは、上記の Claude Desktop と同じ mcpServers JSON ブロックを使います。設定場所は、多くの場合 .cursor/mcp.json、.vscode/mcp.json、またはホストの設定 UI です。

グローバルにインストールした場合(npm i -g plan-to-eat-mcp)、コマンドに plan-to-eat-mcp 実行ファイルを指定し、引数はすべて削除してください。クローンからビルドした場合、コマンドは node、引数は ["/absolute/path/to/plan-to-eat-mcp/dist/mcp/server.js"] です。

クローンから実行する場合は絶対パスが重要です。 MCP ホストはプロジェクトディレクトリからサーバーを起動しないため、相対パスでは解決できず失敗します。上記の npx コマンドを使えば、この問題を回避できます。

動作確認
[email protected] PLAN_TO_EAT_PASSWORD=hunter2 npx -y plan-to-eat-mcp

標準エラー出力に [plan-to-eat] mcp server ready on stdio (36 tools) と表示されます。これはサーバーがクライアントを待機している状態です。Ctrl-C で終了してください。認証情報エラーが表示された場合は、ホストを設定する前に修正してください。ホストに接続してからでは、問題を見つけにくくなります。

エージェントにワークフローを教える

よく使うフローと注意点(supper-vs-dinner のエイリアス、ノート項目の description と title の不一致、スケジュール設定前の重複チェック)を網羅した2つのスキルが .claude/skills/ に含まれています。

  • plan-to-eat — MCP ツールを呼び出すエージェント向けです。
  • plan-to-eat-cli — シェルは使えるものの、MCP サーバーがないエージェント向けです。同じ30の機能をサブコマンドから利用でき、解析用に --json を指定できます。

上記のプラグインをインストールすると、両方が登録されます。他のホストを使うエージェントは、プレーンなコンテキストとして読み込めます。ファイルを指定するか、いずれかをシステムプロンプトに貼り付けてください。

また、skills.sh CLI を使って、18種類以上のエージェントにスキルだけをインストールすることもできます。

npx skills add alex-zwingli/plan-to-eat-mcp

これにより、両方の SKILL.md ファイルが .agents/skills/ にコピーされ、Claude Code、Cursor、Codex、Copilot、Gemini CLI などから利用できるようシンボリックリンクが作成されます。片方だけをインストールするには、--skill plan-to-eat-cli を追加します。これはサーバーではなく、スキル をインストールする点に注意してください。MCP サーバーまたは CLI がまだない場合は、各スキルのセットアップセクションで、エージェントがその構築手順を確認できます。

OpenClaw エージェント向けに、両方のスキルが ClawHub で公開されています。

clawhub install plan-to-eat        # MCP tools
clawhub install plan-to-eat-cli    # shell / CLI

それぞれのスキルのフロントマターでは、必要な認証情報とバイナリが metadata.openclaw の下に宣言されているため、ClawHub はインストール時に環境を確認できます。


⌨️ ターミナルから使う

すべての MCP ツールはサブコマンドとしても利用できます。アンダースコアはダッシュに置き換えられますが、どちらの表記も使えます。

npm i -g plan-to-eat-mcp
plan-to-eat --help

インストールせずに使う場合は、パッケージのデフォルトの bin は CLI ではなく MCP サーバーなので、-p を指定してください。

npx -y -p plan-to-eat-mcp plan-to-eat --help
$ plan-to-eat list-frozen-recipes
ID      RECIPE_ID  COUNT  SERVINGS  FROZEN_ON
──────  ─────────  ─────  ────────  ──────────
227854  44676380   6      1.0       2025-05-04
227908  17314561   3      1.0       2025-05-05

2 rows

$ plan-to-eat add-planner-note "Defrost chicken" 2026-05-05 dinner
id       67710999
date     2026-05-05
section  dinner

$ plan-to-eat get-counts --json | jq .frozen
10
  • 位置引数またはフラグ — get-recipe 123 と get-recipe --id 123 は同じです。<command> --help で、どの引数が位置引数か確認できます。
  • --json を指定すると、テーブルの代わりに生のペイロードが出力され、jq にパイプで渡せます。
  • 配列 はフラグを繰り返す(--event_ids 11 --event_ids 22)か、JSON(--event_ids '[11,22]')で指定します。オブジェクト引数は JSON で指定します。 --ingredients '{"title":"bread","amount":"2"}'
  • 検証には MCP サーバーと同じ Zod スキーマが使われます。そのため、無効な列挙値や不正な日付は、どちらのインターフェースでも同じようにエラーになります。

🧰 36 個のツール

各ツールは MCP ツールであると同時に CLI サブコマンドでもあります。たとえば、ツールの add_planner_recipe はシェルでは plan-to-eat add-planner-recipe です。入力スキーマと戻り値の形式を含む完全なリファレンスは、docs/TOOLS.md をご覧ください。

レシピ

ツール機能
list_recipesレシピブック全体を取得します。タイトルの単語(search)、course、owned_only で絞り込むこともできます。簡易的な行(id、タイトル、コース、タグなど)を返します(すべてのフィールドを含めるには full を指定します)。材料は含まれません。
get_recipe作り方、材料、タグ、prep_notes、コメントを含むレシピを 1 件取得します。
create_recipeレシピを作成します。必須なのは title だけです。
update_recipe任意のフィールドを一部だけ更新します。
delete_recipeid を指定して削除します。

プランナー — 読み取り

ツール機能
list_planner_events日付による絞り込みを行わず、プランナーのすべての予定を取得します。
get_planner_week日付範囲内の予定を取得し、recipe_title をあらかじめ結合して返します。end_date のデフォルトは start_date + 6 days です。

プランナー — 書き込み

ツール機能
add_planner_recipe日付とセクションを指定して、レシピを予定に追加します。
add_planner_ingredient自由形式の材料(「2 lbs ground beef」など)を食事枠に追加します。
add_planner_note自由形式のメモ(「鶏肉を解凍する」など)を食事枠に追加します。
add_leftover_meal以前予定したレシピの予定から、残り物を予定に追加します(plan_leftover で複製し、必要に応じて移動します)。
move_planner_event任意のプランナー予定を新しい日付/セクションに移動します。
reorder_planner_eventsセクション内の予定を並べ替えます(希望する順番で id を渡します)。
update_planner_entry_textメモまたは材料の項目テキストを編集します。
set_planner_servingsレシピの予定の人数分を変更します。
duplicate_planner_event任意の予定を複製します。plan_leftover は任意です。
delete_planner_eventid を指定して削除します。
find_planned_dates日付範囲内で、指定したレシピのプランナー予定を検索します。重複チェックに便利です。

冷凍庫

ツール機能
list_frozen_recipes現在冷凍庫にあるものを取得します。履歴も表示するには {include_consumed: true} を指定します。
freeze_recipe_portions調理済みレシピの N 人分を冷凍済みとして記録し、元となったプランナー予定に紐付けます。
delete_frozen_recipe冷凍項目を消費済みとして記録します(論理削除:API は数を 0 にしますが、行は残ります)。

買い物リスト

項目は単一の id ではなく、item_ids 配列で指定します。Plan to Eat は重複する材料を 1 行にまとめ、その行に元のすべての行 id を保持します。

ツール機能
get_shopping_listリストを取得します。各行には、登録先の店舗(store_title)と通路、項目を追加したレシピが含まれます。
add_shopping_list_items項目を追加します。必須なのは title だけです。通路は推測され、店舗はその項目で最後に使用した店舗がデフォルトになります。
update_shopping_list_items項目名や数量を変更したり、任意の数の行を別の店舗や通路に移動したりします。
remove_shopping_list_items項目をリストから削除します(論理削除)。
restore_shopping_list_items削除した項目を元に戻します。

参照テーブルとその他

ツール機能
list_courses / list_cuisines / list_main_ingredients / list_tags参照テーブルです。
list_stores / list_grocery_categories店舗と食料品の通路を取得します。必要な id は store_id と category_id です。
list_menus保存済みのメニューを取得します。
list_friends友達リストを取得します。
get_countsレシピブックのウィジェットから { friends, queued, frozen } を取得します。
update_planner_optionsプランナーの表示設定(タイムゾーン、週の開始日、栄養情報の列)を設定します。通常は必要ありません。

📚 クライアントをライブラリとして使う

import { PlanToEat, type Recipe } from 'plan-to-eat-mcp';

const pte = new PlanToEat();
await pte.login(process.env.PLAN_TO_EAT_USERNAME!, process.env.PLAN_TO_EAT_PASSWORD!);
// Or restore: pte.importSession(JSON.parse(fs.readFileSync('session.json', 'utf8')));

const recipes = await pte.listRecipes();                    // every active recipe
const [dumplings] = await pte.listRecipes({ search: 'pork chive' });
const detail: Recipe = await pte.getRecipe(dumplings.id);  // ingredients + directions

const created = await pte.createRecipe({
  title: 'Grilled cheese',
  servings: 1,
  directions: 'Butter bread. Cheese. Pan. Flip.',
  ingredients: [
    { title: 'bread',  amount: '2', unit: 'slice', position: 1 },
    { title: 'cheese', amount: '1', unit: 'slice', position: 2 },
  ],
  tag_titles: 'easy,lunch',
});

await pte.updateRecipe(created.id, { rating: 5 });
await pte.deleteRecipe(created.id);

クライアントは初回ログイン時に認証情報を内部に保存するため、キャッシュされた Cookie の有効期限がセッション中に切れても、自動的に再認証できます。

同じ 36 種類の機能を使って独自のアダプターを構築する場合に備え、ツールレジストリもエクスポートされています。

import { toolsByName, createSession } from 'plan-to-eat-mcp';

const { pte, ensure } = createSession();
await ensure();

const getRecipe = toolsByName.get('get_recipe')!;
console.log(getRecipe.description);          // same text the MCP host sees
const recipe = await getRecipe.run(pte, { id: 123 });

🧪 API リファレンス(動作する部分)

すべてのパスのベースは https://app.plantoeat.com です。

JSON エンドポイント(/api/v1/*)
メソッドパス備考
GET/api/v1/recipes/lite_plusレシピ一覧全体を、軽量なリスティングの単一配列として返します(タイトル、コース/料理ジャンル/主要食材のタイトル、タグ、フラグ。材料は含まれません)。Web アプリのレシピグリッドで使われています。非アクティブ/削除済み/非表示の行も含まれるため、active、remove、hidden で絞り込んでください。ページングパラメーターは無視されますが、指定する必要はありません。Web アプリでは、特定のカードを更新するために ?ids[]=1&ids[]=2 を使います。
GET/api/v1/recipes一覧取得には使わないでください。 ID が最も古いレシピ 500 件のみを、材料を含めて返します。試したすべてのページング/並べ替えパラメーター(page、per_page、offset、limit、start、after_id、page[number]、sort、order、q、search)は無視されます。/api/v1/recipes/search、/api/v1/recipes/count、/api/v2/recipes は 404、/recipes.json は 406 を返します。
GET/api/v1/recipes/:iddirections、ingredients、tags、prep_notes、comments を含む単一のレシピを返します。
POST/api/v1/recipes作成します。本文:{ "recipe": {...} }。201 と完全なレシピを返します。
PUT/api/v1/recipes/:id更新します。同じ形式の本文を使います。
DELETE/api/v1/recipes/:id削除します。削除したレシピを返します。
GET/api/v1/courses、/cuisines、/main_ingredients、/tags参照テーブルです。
GET/api/v1/eventsプランナーのエントリー(カレンダー)です。カレンダー全体を返します。クライアント側で日付による絞り込みを行ってください。
GET/api/v1/menus保存済みメニューです。
GET/api/v1/shopping_list同期メタデータ(updated_items、last_sync_time)のみを返します。リスト自体は返しません。
GET/api/v1/shopping_list/items買い物リスト自体を返します。統合された各行につき 1 エントリーです。
GET/api/v1/stores食料品店です。
GET/api/v1/grocery_categories食料品売り場のカテゴリーです。
GET/api/v1/friends友達です。
GET/api/v1/frozen_recipes冷凍庫:[{id, recipe_id, count, servings, frozen_on}]。
DELETE/api/v1/frozen_recipes/:id論理削除します(count: 0 に設定。行は残ります)。更新後の行を返します。
GET/recipes/counts/{ friends, queued, frozen }。(注:/api/v1 配下ではありません。)
プランナーの書き込みエンドポイント(/planner/*)

形式が異なり、本文はフォームエンコード、レスポンスは空の text/javascript です。サーバーが状態を変更し、UI は別途再取得します。必須ヘッダー:X-CSRF-Token、X-Requested-With: XMLHttpRequest、Accept: text/javascript。レスポンス本文が空のため、クライアントは /api/v1/events の実行前後を比較して、新しいイベント ID を特定します。

メソッドパス本文
POST/planner/createrid=<recipeId>&date=YYYY-MM-DD&section=...(レシピ)、または date=...&section=...&eventType=note|ingredient&title=<text>
POST/planner/create/rid=<id>&frozen_id=&date=...&section=...(冷凍レシピ用のバリエーション。末尾のスラッシュに注意)
POST/planner/updateeventid=<id>&date=...&section=...&readonly=false(移動/再スケジュール)
POST/planner/update/<id>description=<text>(メモ/材料のテキストを編集)
POST/planner/update_servingevent=<id>&serving=<n>
POST/planner/duplicateid=<id>&plan_leftover=true|false&readonly=false
POST/planner/update_orderids=e<id1>,e<id2> — セクション内のイベントを並べ替えます
POST/planner/destroyid=<id>&readonly=false
POST/planner/update_planner_optionsネストされた Rails キー:user[time_zone]=...&calendar_settings[show_calories]=1&...
POST/frozen_recipesid=<recipe_id>&eid=<event_id>&count=<n>&servings=<per-portion> — N 人分を冷凍します
GET/planner/search_datesレンダリング済み HTML を返します。JSON ではありません。クライアントでは使用しません。代わりに /api/v1/events を絞り込みます。

section の値は breakfast、lunch、dinner、snacks です。ユーザーごとのアカウント設定によって、サーバーが dinner を supper に正規化する場合があります。読み取り時には正規名が返されます。

認証

Cookie ベースです。クライアントは次の 2 つのフローに対応しています。

  1. ログイン。 GET /login のメタタグから取得した authenticity_token と、login[email] および login[password] を指定して POST /login を送信します。サーバーは 302 を返し、Cookie を設定します。
  2. Cookie の再利用。 「ログイン状態を保持する」ための ptermid2(ユーザー ID)と ptermxt2(有効期間の長いトークン)のペアだけで認証できます。これらを保存しておけば、無効になるまで再ログインを省略できます。

書き込みリクエストには X-CSRF-Token ヘッダーが必要です。クライアントは必要に応じて /recipes ページの <meta name="csrf-token"> タグから取得します。

/api/v1/... での HTTP Basic 認証には対応していません(401 が返されます)。

レシピのペイロード形式

単一レシピのレスポンスには 65 個のフィールドがあります。POST/PUT で書き込み可能な項目は、title、description、source、url、servings、yield、scaling、prep_time、cook_time、total_time(分)、course_id、cuisine_id、main_ingredient_id、tag_titles(カンマ区切りのリスト)、directions(自由形式のテキスト)、private、draft、rating、栄養情報の文字列(calories、sodium など)、および材料です。

材料には Rails のネスト属性を使用します。API 上のフィールド名は ingredients ではなく recipe_ingredients_attributes です。クライアントと create_recipe / update_recipe ツールは、わかりやすい ingredients という名前を受け付け、変換します。各エントリは次のとおりです。

{ "title": "water", "amount": "1", "unit": "cup", "note": "", "position": 1 }

更新時に既存の材料を削除するには、その id と "_destroy": true を指定します。サーバーは amount_float、metric_amount、metric_unit、similar_titles を補完します。


📁 構成

1 つのパッケージが 3 つのレイヤーで構成されています。ロジックは core/ にあり、MCP サーバーと CLI は同じレジストリを使用する薄いアダプターです。

src/
  core/
    client.ts     API client — no MCP, no CLI, no I/O beyond fetch
    tools.ts      the tool registry: name, description, Zod shape, handler
    session.ts    credentials + cookie-cache bootstrap, shared by both adapters
    version.ts    version read from package.json at runtime
  mcp/server.ts   registry -> MCP tools (stdio transport)
  cli/
    main.ts       registry -> subcommands, help, dispatch
    args.ts       argv -> Zod-validated arguments
    render.ts     results -> tables (or raw JSON under --json)
  scripts/        smoke tests and the docs coverage check
  tests/          offline unit tests (fetch is stubbed)
  index.ts        public entrypoint for library consumers
  server.ts       back-compat shim, see below

ツールを追加するには、src/core/tools.ts にエントリを 1 つ追加します。 MCP サーバーと CLI の両方に、同じ名前、スキーマ、説明で同時に反映されるため、互いに食い違うことはありません。

知っておくと便利なその他のファイル:

  • docs/TOOLS.md — 各ツールの入力・出力形式と注意点をまとめたリファレンスです。手書きのファイルであり、レジストリに登録されているツールと記載されているツールが一致しない場合、npm run check:docs は失敗します。
  • .claude/skills/plan-to-eat/SKILL.md — MCP ツールを効果的に使う方法です。
  • .claude/skills/plan-to-eat-cli/SKILL.md — CLI 向けの同じガイドです。
  • .claude-plugin/ — Claude Code プラグインとマーケットプレイスのマニフェストです。
  • .mcp.json — プラグインの MCP サーバー宣言です。
  • dist/ — npm run build で生成されます。

≤0.4 からアップグレードする場合:サーバーの場所が dist/server.js から dist/mcp/server.js に移動しました。旧パスも引き続き使用できます。新しいパスを読み込むシムになっているため、既存のホスト設定とデプロイはそのまま動作します。新しい設定では、新しいパスまたは plan-to-eat-mcp バイナリを使用してください。

リバースエンジニアリングには Playwright を使用し、今後の API 調査に備えて devDependency として残しています。実行時の依存関係は fetch、MCP SDK、Zod のみです。

スクリプト
コマンド説明
npm run buildsrc/**/*.ts を dist/ にコンパイルします。
npm run watch同じ処理をウォッチモードで実行します。
npm startコンパイル済みの MCP サーバー(dist/mcp/server.js)を実行します。
npm run cli -- <command>グローバルにリンクせずに CLI を実行します。
npm run verifyアカウントのレシピを使って、クライアントのエンドツーエンド動作をスモークテストします。
npm run verify:plannerプランナーの書き込みエンドポイントをスモークテストします(6 か月後の日付にテストイベントを作成し、削除します)。
npm testMCP サーバーを起動してツールを呼び出し、エンドツーエンドでスモークテストします。
npm run check:docsdocs/TOOLS.md に登録済みのすべてのツールが過不足なく記載されているか確認します。
npm run test:unitfetch をスタブ化したオフラインの単体テストです。何も変更せず、CI で実行されます。
npm run cleandist/ を削除します。

verify* スクリプトと test スクリプトは実際のアカウントに対して実行されます(test:unit は対象外です)。これらのスクリプトはテストデータを作成して削除しますが、ドライランではありません。CONTRIBUTING.md を参照してください。

🤝 コントリビューション

バグ報告、新しいエンドポイント、上流との互換性が壊れた場合の修正を歓迎します。詳しくは CONTRIBUTING.mdをご覧ください。事前に知っておいてほしいことが1つあります。テストスクリプトは実際のPlan to Eatアカウントを使って実行され、実際のデータを作成します (その後、クリーンアップします)。ご自身のアカウントをお使いください。


🙏 Plan to Eatを応援する

このプロジェクトは、Plan to Eatが素晴らしいサービスだからこそ存在しています。これが役に立ったら、ぜひ 紹介リンクからPlan to Eatをお試しください。 14日間の無料トライアルがあり、カード情報は不要です。

ライセンス

MIT — LICENSEをご覧ください。自由にお使いいただけますが、Plan to Eatが互換性を壊す変更をリリースしても、私に責任を問わないでください。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。