mcpField
R
recipe-cleanup

recipe-cleanup

github.com/gkwa生産性073 回インストール2 日前に更新
リポジトリ

recipe-cleanup について

ローカルファイル、Web ページ、YouTube の説明欄、インラインテキストからレシピを整形するスキルです。材料、手順、下ごしらえ、出典を整理し、画像、作者メタデータ、材料リンクも扱います。

主な機能

  1. 01ローカルファイル、Web ページ、テキストの読み込み
  2. 02YouTube 説明欄からのレシピ抽出
  3. 03材料一覧と調理手順の整形
  4. 04下ごしらえと調理工程の整理
  5. 05作者メタデータの追加と画像検索
  6. 06材料ノートリンクの解決

活用シーン

  1. 01Web レシピを統一形式のファイルに整理
  2. 02YouTube の説明欄からレシピノートを作成
  3. 03材料リンクを既存の商品ノートに対応付け
  4. 04下ごしらえと調理工程ごとに手順を再構成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/gkwa/volcanicviper --skill recipe-cleanup

インストール後、Claude Code で/recipe-cleanupを入力して読み込まれたか確認します。

同梱ファイルtile.json

詳細

レシピの整理

入力を解析します。最初の引数は、ローカルのレシピファイルのパス、またはレシピページの URL のいずれかです。2 番目の引数は省略可能で、元のレシピのソース URL を指定します。URL またはファイルパスの後に続くテキストはすべて、インラインのレシピ内容(材料、手順、メモ)として扱います。

最初の引数から入力モードを判定します。

  • http:// または https:// で始まる場合は URL として扱います。ページを取得してレシピ内容を抽出し、その URL を暗黙のソース URL として扱います(2 番目の引数で上書きされた場合を除きます)。
    • YouTube の動画 URL(youtube.com/watch?v=VIDEO_ID):動画 ID を抽出し、サムネイルを https://i.ytimg.com/vi/VIDEO_ID/hq720.jpg に設定してから、次のフォールバック手順に従って説明文の取得を試みます。
      1. まず YouTube の URL に対して WebFetch を試します。使用可能な説明文が返された場合は、それを使用します
      2. WebFetch が失敗するか、説明文が返されない場合は、Playwright に切り替えます。ページに移動して読み込みを 3 秒待ち、「...more」ボタンをクリックして説明文全体を展開します
      3. いずれかの方法で説明文を取得したら、レシピ内容を確認します。
        • 説明文内のレシピ:説明文に材料や手順が直接記載されている場合は、それをレシピ内容として使用します
        • 説明文内のリンク:説明文に外部のレシピページ(ブログ記事や専用のレシピ URL など)へのリンクがある場合は、その URL を WebFetch で取得し、そこからレシピを抽出します。YouTube の URL とレシピページの URL の両方を記録します。どちらも出力ファイルに記載されます
        • インラインテキストへのフォールバック:説明文にレシピもリンクもない場合は、引数に指定されたインラインテキストを使用します
      4. チャンネル名と動画タイトルを使ってクリエイターを特定します
  • それ以外の場合は、ローカルのファイルパスとして扱い、そのファイルを読み込みます

チャンネル URL に基づくクリエイターの特定:

  • いずれかの引数が YouTube チャンネル URL(例:youtube.com/@Handle や youtube.com/c/name)の場合は、そのページを取得してクリエイターの本名を抽出します
  • 取得に失敗した場合は、大文字・小文字の切り替わりでハンドルを区切り、名前を推定します(例:@FastEasyRecipes → Fast Easy Recipes)
  • その名前を creator フロントマターのフィールドに使用します

レシピ内容に以下の書式ルールを適用します。

フロントマター:

  • ファイルの先頭(ソース URL の行より前)に、次のフィールドを含む YAML フロントマターを生成します。
    ---
    creator: '[[Author Name]]'
    pic: <hero-image-url>
    tags:
    - recipe
    - <creator tag>
    ---
    
  • クリエイターのタグは、解決したページ名を小文字にし、すべてのスペースと区切り文字を取り除いたものにします(例:Andrea Geary → andreagreary、budgetbytes → budgetbytes、Fast Easy Recipes → fasteasyrecipes)
  • レシピページから著者/クリエイター名を抽出します(例:レシピカードの著者欄やブログの概要ページから)
  • 次の優先順位に従って、クリエイターのページ名を特定します。
    1. レシピが著者本人の個人ドメインからのものである場合は、TLD を除いたドメイン名をページ名として使用します(例:budgetbytes.com → budgetbytes、halfbakedharvest.com → halfbakedharvest)。これは本人が選んだ活動名です。
    2. 大手メディア(例:Bon Appétit、Serious Eats、NYT Cooking、Food Network、Epicurious、Tasty)からのレシピの場合は、そのメディアでクレジットされている著者名を使用します。コンテンツは個人のパーソナルブランドではなく、メディアに属するものです。
    3. 個人ドメインがない場合(例:YouTube のみで活動するクリエイター)は、著者の本名を使用します。
  • 解決したページ名を creator フロントマターのウィキリンクに使用します(例:[[budgetbytes]])
  • ファイルを書き込んだ後、レシピファイルと同じディレクトリに <page name>.md という名前のページがあるか確認します。存在しない場合は、# <page name> の後に空行を 1 行入れ、著者のソース URL(YouTube チャンネル URL、ウェブサイト、またはレシピの取得元など)を記載した最小限のスタブを作成します

書式ルール

材料:

  • 各材料の行は、チェック済みチェックボックスとして書式設定します:- [x] 分量 [[材料名]]
  • 材料名(分量や説明語句は含めません)を Obsidian のウィキリンクで囲みます:[[材料名]]
  • リポジトリ内の対応する製品ページにリンクできるよう、ウィキリンクには製品名全体を含めます
    • 例:1 cup julienned carrots → - [x] 1 cup julienned [[carrots]]
    • 例:2 teaspoons sesame oil → - [x] 2 teaspoons [[sesame oil]](sesame [[oil]] ではありません)
  • 材料にすでにウィキリンクがある場合は、そのままにします
  • ファイルを書き込んだ後、既存のノートにリンクしていない材料のウィキリンクをすべて解決します。下記の「材料のウィキリンクを解決する」セクションを参照してください

材料のウィキリンクを解決する:

  • 整理済みファイルを書き込んだ後、すべての材料名は [[ウィキリンク]] で囲まれていますが、その多くは Vault 内の既存の製品ノートにリンクしていません
  • 解決先を推測したり手作業で作成したりせず、唯一の標準リゾルバーである resolve-recipe-ingredient-link スキルに委任します
  • ターゲットのノートが Vault 内に存在しない材料のウィキリンクごとに、resolve-recipe-ingredient-link を呼び出して最適な製品ノートを見つけ、リンクを解決後の形式に書き換えます。ノートの存在は、Obsidian がリンクを解決する方法と同じく、ベース名で判断します
  • リゾルバーには、リンク部分だけでなく材料の行全体をコンテキストとして渡します。リンクされた名詞の周囲にある説明語句が、候補の絞り込みに役立ちます
  • 候補となる製品ノートは一度だけ列挙し、材料ごとに再列挙するのではなく、その一覧を使ってレシピ内の未解決リンクをすべて解決します
  • 既存のノートにすでにリンクしているウィキリンクは変更しません
  • リゾルバーが材料の行だけではリンク先を決定できない場合は、3段階ルールに従います。候補一覧を提示してユーザーに確認し、誤った候補を無理に選ばないでください

手順:

  • 手順の各行は、先頭を必ず小文字にします

  • 手順の末尾にピリオドを付けないでください

  • 各文を独立した段落にします。複数の文からなる手順は、文ごとに分けて空行で区切ります

  • 太字、斜体、その他の強調書式はすべて削除し、プレーンテキストのみにします

  • 手順は必ず通常の段落で記述します。元の文章が番号付きリストまたは順序付きリストの場合は、各項目を通常の段落に変換します

  • 手順に複数の項目がカンマ区切りで列挙されている場合(例:「玉ねぎ、油、バター、塩を加える」)、周囲の文はそのままにして、列挙部分を Markdown の箇条書きサブリストに展開します

    入力例:

    add onions, oil, remaining butter, salt and pepper to pan
    

    出力例:

    add
    
    - onions
    - oil
    - remaining butter
    - salt
    - pepper
    
    to pan
    

ミザンプラス:

  • ミザンプラス(「すべてを所定の場所に」)とは、調理を始める前にすべての準備を済ませ、調理を中断せずに進められるようにすることです
  • 原則は、準備と調理を切り分けることです。フライパンが熱くなってからも食材を切っていると、料理も集中力も損なわれてしまいます
  • 手順から準備にあたる工程をすべて抜き出し、最初の調理セクションのすぐ上にある ## Mise en Place セクションに記載します。既存の ## Prep セクションがあれば、名前を ## Mise en Place に変更します
  • 準備の工程には、加熱や時間の計測を始める前に完了できる作業が含まれます。刻む、さいの目に切る、みじん切りにする、スライスする、皮をむく、計量する、水に浸す、洗う、生地を休ませる、材料を室温に戻す、予熱するなどです
  • レシピに異なる調理工程(例:ブロス作り、ソース作り、フィリングの準備)がある場合は、すべてを単一の ## Instructions セクションにまとめず、各工程に ## Broth や ## Sauce などの名前を付けたセクションを設けます。これにより、材料レベルだけでなく工程レベルでもミザンプラスの原則を適用できます
  • ## Instructions は最後の組み立て手順のみに使用します
  • 準備の工程は、箇条書きにせず通常の段落として記載し、段落の間に空行を入れます。手順と同じ形式です
  • 準備の工程に複数の項目が含まれる場合は、作業を通常の段落として記載し、その下に項目を箇条書きのサブリストとして列挙します(手順と同じカンマ展開ルールを適用します)
  • 手順と同じ書式ルールを適用します。小文字で始め、末尾にピリオドを付けません
  • 抜き出した工程は調理セクションから削除し、重複させないでください
  • ## Mise en Place セクションがすでにある場合は、新たに抜き出した工程をそこにまとめます

料理の画像:

  • レシピのメイン画像を探します(例:og:image のメタタグまたはメインのレシピ写真)
  • フロントマターブロックの直後、ソース URL の前に、インラインの Markdown 画像として配置します:![dish name](image-url)
  • すでにその位置に画像がある場合は、そのままにします

栄養セクション:

  • 栄養セクションがある場合は、セクション全体を削除します

YouTube リンク:

  • 長い YouTube URL は短い形式に変換します:https://youtu.be/VIDEO_ID
    • 例:https://www.youtube.com/watch?v=abc123 → https://youtu.be/abc123
    • 例:https://www.youtube.com/watch?v=abc123&t=45s → https://youtu.be/abc123?t=45
  • 既存の短い youtu.be URL はそのままにします
  • YouTube 動画 ID があり、ファイルに pic フロントマターフィールドがある場合は、サムネイル URL を使用する前に確認します。まず hq720.jpg に対して curl -s -o /dev/null -w "%{http_code}" URL を実行します。結果が 200 ならそれを使用し、404 なら hqdefault.jpg に切り替えます

タイムスタンプ:

  • 手順に [MM:SS] 形式の動画タイムスタンプがあり、関連する YouTube URL がある場合は、?t= パラメーターを秒数にして絶対 URL の Markdown リンクに変換します
    • 例:動画が https://youtu.be/Wnt90dkEwFs の場合、[00:17] → [00:17](https://youtu.be/Wnt90dkEwFs?t=17)
    • 例:[01:05] → ?t=65
  • リンクテキストは [MM:SS] 形式のタイムスタンプにします
  • タイムスタンプに対応する YouTube URL がない場合は、通常のテキストのままにします

出力例

crack the eggs into a bowl, see [00:05](https://youtu.be/Wnt90dkEwFs?t=5)

whisk until fully combined

pour into a heated, greased pan, see [00:17](https://youtu.be/Wnt90dkEwFs?t=17)

cook until edges begin to set

手順

  1. 最初の引数から入力モード(URL またはファイルパス)を判定します
  2. それに応じてレシピの内容を取得または読み込み、作者名とヒーロー画像の URL を抽出します
  3. レシピの内容にすべての書式ルールを適用します。手順の順序付きリストは通常の段落に変換し、手順行に限って手順固有のルール(小文字化、末尾のピリオドを付けない、文の分割)を適用します
  4. ファイルの最上部に、creator、pic、tags を含む YAML フロントマターを配置します
  5. フロントマターの直後にヒーロー画像を配置し、その次の行から空行までソース URL を配置します。ソース URL がすでに存在する場合は置き換えます。YouTube の説明欄にリンクされた外部ページからレシピを取得した場合は、YouTube の URL を先に、その下の行にレシピページの URL を配置します
  6. # Title 見出しは含めないでください。Obsidian ではファイル名がページタイトルになります
  7. ファイルモードの場合:整形した内容でファイルを上書きし、成功したことを確認します。レシピの全内容をチャットに出力してはいけません
  8. URL モードの場合:整形したレシピをチャットに表示し、確認を求めずにすぐファイルへ書き込みます。レシピのタイトルからファイル名を作成し、スペースを使い(ハイフンは使わず)、拡張子を .md にします。作者が判明している場合は、同じ料理名のレシピとの重複を避けるため、ファイル名の先頭に作者名を付けます(例:Fast Easy Recipes crepes.md)。Vault 内のほかのレシピファイルと同じディレクトリに保存します
  9. ファイルへの書き込み後、同じディレクトリに作者のページがあるか確認します。ない場合は、# <page name> だけを含む <page name>.md という名前のスタブページを作成します(上記のフロントマタールールに従って解決したページ名を使用します)
  10. ファイルへの書き込み後、「Resolving ingredient wikilinks」書式ルールを参照して、未解決の材料ウィキリンクの解決を resolve-recipe-ingredient-link スキルに委任します
  11. 書き込んだノートに対して outline-headings スキルを実行します。ソース URL、分量、キャプション、ヒーロー画像が最初の見出しより上にあり、アウトラインに表示されなくなるため、これは必須であり、省略できません
  12. pic フロントマターの値が空でないこと、同じ画像が最初の見出しの直下に埋め込まれていることを確認します。ヒーロー画像のないレシピノートは不完全です

作者の名前空間

作者の名前空間は、ハンドルまたは個人ドメインから導出し、小文字の英数字だけにして連結します。

同じトークンを次の3か所すべてで使用します。creator フロントマターのウィキリンク、tags エントリ、スタブページのファイル名です。

Instagram のハンドル chef.sam.black は、すべての箇所で chefsamblack になります。つまり、[[chefsamblack]]、タグ chefsamblack、ファイル chefsamblack.md です。個人ドメイン halfbakedharvest.com は halfbakedharvest になります。

タグにはピリオド、スペース、その他の区切り文字を含められず、実名は重複する可能性があるため、区切り文字を除いたハンドルを使うことで、タグ、ウィキリンク、ファイル名のすべてに使える一意の名前空間を作成できます。

ハンドルもドメインもない場合に限り、区切り文字を除いた実名を使用します。

既存の Vault での使用例:pantrymama、thesaltymarshmallow、ediblealchemyacademy、allrecipes

コメント