はじめに:広告API、強力だが遠すぎる存在

Spotify Ads API v3は、30以上のリソースタイプ、ネストされたターゲティング構造、キャンペーン→広告セット→広告へと続くマルチステップのエンティティ階層を持っています。「コネチカット州のリスナーをターゲットにしたオーディオキャンペーンを作りたい」という単純な意図を実行に移すまでの認知的距離は、非常に大きいものです。

Spotifyエンジニアリングチームはこのギャップを埋めるために、Claude Codeプラグインを開発しました。ユーザーがプレーンな英語(または日本語)で希望を説明すると、システムが残りを自動的に処理する構造です。単一の自然言語リクエストが、完全で正しいキャンペーン構造に変換されます。

このプラグインはMarkdownファイル、bashスクリプト、2つの小さなPythonヘルパーで構成され、完全にオープンソースとして公開されています。この記事では、そのアーキテクチャ、技術的選択、そしてLLMベースのエージェント上で開発者ツールを構築する際に学んだ点を共有します。

Claude Code terminal showing natural language campaign creation for Spotify Ads API Software Concept Art

コアアーキテクチャ:Markdownですべてが完結する

このプラグインの最も驚くべき点は、コンパイルされたコードが一つもないことです。ビルドステップ、パッケージマネージャー、バンドラー、トランスパイラーが一切ありません。すべての構成要素が.mdファイルで記述されています。

4つの構成要素

構成要素役割実装方法
Skillsスラッシュコマンドの定義各コマンドの動作、APIエンドポイント、リクエストフォーマット、出力処理を説明するMarkdownファイル
Agents自由形式の自然言語処理ユーザーが広告タスクを会話形式で説明すると、それをAPI呼び出しに分解するMarkdownファイル
Hooksツール呼び出し前のインターセプトOAuthトークンの更新、HTTPヘッダーの注入を透過的に処理
Settingsユーザーごとの設定保存資格情報、広告アカウント、環境設定をgitignoredローカルファイルに保存

自然言語エージェント:ドメインエキスパート翻訳機

agents/spotify-ads-request-builder.mdという1つのMarkdownファイルが、LLMをSpotify Ads APIのスペシャリストに変身させます。このシステムプロンプトには以下の知識が含まれています:

  • 値の変換:ドル→マイクロ単位、日付の説明→ISO 8601、プラットフォーム名→API enum値
  • マルチステップオーケストレーション:「フルキャンペーン作成」をキャンペーン→広告セット→広告の3段階のAPI呼び出しに分解し、ステップ間でIDを渡す
  • ジオターゲティング検索:「コネチカットをターゲット」と言うと、ジオターゲティング検索エンドポイントを呼び出して地域IDを見つけ、正しい構造でgeo_targetsオブジェクトを構成
  • 事前検証:広告セット作成前にオーディエンス見積もりエンドポイントを呼び出し、ターゲティングが最小閾値を満たしているか確認
  • 実行制御:ユーザーのauto_execute設定に応じて、curlコマンドを表示して確認を求めるか、直接実行
# 例:自然言語リクエストがAPI呼び出しに変換される過程(概念コード)
# ユーザー:「25-44歳の米国在住者を対象に、1日100ドル予算のBack to School Promoオーディオキャンペーンを作成」

# ステップ1:ジオターゲティングIDを検索
# curl -X GET "https://api.spotify.com/v1/targets/geos?q=US"
# → レスポンスから「US」の地域IDを抽出

# ステップ2:通貨変換(100 USD → 10000000 マイクロ単位)
# ステップ3:キャンペーン作成 POST
# ステップ4:広告セット作成 POST(キャンペーンID、ターゲティング、予算を含む)
# ステップ5:広告作成 POST(広告セットID、クリエイティブアセットを含む)

これらのすべてのステップが、Markdownファイルに定義されたルールに従って自動実行されます。

Diagram of OpenAPI Links connecting campaign, ad set, and ad entities in Spotify Ads API Developer Related Image

なぜMCPではなくCLI + OpenAPI Specなのか?

Model Context Protocol(MCP)はLLMと外部ツールを接続する標準として台頭しています。しかし、Spotifyチームは複数の理由からMCPを選択しませんでした。

1. APIサーフェスが広すぎる

Spotify Ads APIは数十のエンドポイントとネストされたリクエストスキーマを持っています。それぞれをMCPツールとして定義すると巨大なツールレジストリが生成され、ユーザーがそのエンドポイントを必要としない場合でも、すべてのインタラクションで相当なコンテキストウィンドウを消費します。一方、Claude Codeプラグインアプローチでは、エージェントが必要なときにのみ関連する参照ドキュメントをロードします。

2. Curlコマンドは透過的でデバッグ可能

プラグインが行うすべてのAPI呼び出しはcurlコマンドとしてユーザーに表示されます。ユーザーは何が送信されているかを正確に確認し、コピーし、修正し、独立して実行できます。この透明性は、すべてのリクエストが実際の予算に影響を与える可能性がある広告システムにおいて、監査可能性とユーザーコントロールを提供します。

3. OpenAPI Specが真実の源泉(Source of Truth)

Spotify Ads APIは約8,600行の包括的なOpenAPI v3スペックを提供しています。これをMCPツールスキーマに翻訳し、APIが進化するたびにその翻訳を維持する代わりに、プラグインにスペックを直接搭載します。エージェントがエンドポイントのパラメータやレスポンス形式を理解する必要があるとき、このスペックを読みます。APIが変更されたら、ファイル1つを更新するだけです。

OpenAPI Links:エージェントのためのワークフローグラフ

ここで最も興味深い部分は、OpenAPI Linksの活用です。OpenAPI 3.xスペックの比較的使われていない機能であるLinksは、操作間の関係を定義します。特に、ある操作のレスポンスを別の操作の入力として使用する方法を明示します。

Spotify Ads APIスペックはLinksを通じてエンティティ階層全体をエンコードしています:

# 例:キャンペーン作成レスポンスが広告セット作成を指す
'201':
  links:
    createAdSet:
      operationId: createAdSet
      parameters:
        ad_account_id: '$request.path.ad_account_id'
        campaign_id: '$response.body#/id'

人間の開発者には暗黙的だったエンティティ階層(キャンペーン→広告セット→広告)が、LLMエージェントには機械可読な形式で明示的に宣言されます。$response.body#/idのようなランタイム式は、エージェントにどのフィールドを抽出して次のリクエストに注入すべきかを正確に伝えます。

graph LR
    A[自然言語リクエスト] --> B[エージェント分解]
    B --> C[キャンペーン作成 POST]
    C --> D[広告セット作成 POST]
    D --> E[広告作成 POST]
    C -.-> F[OpenAPI Links: レスポンスIDを渡す]
    D -.-> F

このアプローチは、根拠資料で確認できるように、単純な広告フローを超えて複雑なAPI統合に拡張可能なパターンを示しています。

Developer reviewing curl command output from LLM agent for Spotify Ads API Development Concept Image

日本市場での適用コンテキスト

日本の広告プラットフォーム(例:Yahoo!広告、LINE広告)も同様に複雑なAPI構造を持っています。このアプローチは以下のような日本の環境に直接適用できます:

  • 複雑な広告APIの自然言語インターフェース化:Yahoo!広告、LINE広告など複雑なターゲティング構造を持つAPIへのClaude Codeプラグインパターンの適用
  • SI案件におけるドキュメントベースの自動化:レガシーSI環境でMarkdownベースのエージェントを活用したAPI統合自動化
  • OpenAPI Linksの活用:日本のAPI提供者がOpenAPI Linksを積極的に活用すれば、LLMベースのツールとの互換性が大幅に向上

この技術の限界または注意点

  • エージェントの信頼性:現在は比較的単純な広告フローを基準にロジックが書かれているため、非常に複雑または例外的なケースでは追加のプロンプトエンジニアリングが必要です。
  • 冪等性キーの未サポート:現行バージョンではネットワーク再試行やエージェント再実行時に重複キャンペーンが生成されるリスクがあります。チームは冪等性キーの導入を計画中です。
  • プラットフォーム依存性:現在はClaude Codeに特化していますが、CodexやGemini CLIなど他のプラットフォームへの拡張を検討中です。

合わせて読みたい記事

次のステップとしての学習方向

  1. OpenAPI 3.x Linksスペックを深く学び、自分のAPIにLinksを適用してみてください。
  2. Claude Codeプラグイン開発に挑戦してみてください。数個のMarkdownファイルから始められます。
  3. 自然言語インターフェース設計の原則を学び、複雑なドメインを単純化するプロンプトエンジニアリングを練習してみてください。

このプラグインは一つの明確なテーゼに基づいています:複雑なAPIに対する最良のインターフェースは自然言語であり、詳細なドキュメントと透過的な実行がそれを支えるべきである。 ユーザーは欲しいものを伝えます。エージェントはAPI呼び出しを処理します。Hookレイヤーは認証を透過的に処理します。そしてすべてのcurlコマンドは表示可能で、コピー可能で、デバッグ可能です。

フレームワークも、ランタイムも、curl、jq、python3以外の依存関係もありません。真実の源泉はOpenAPIスペックです。ビジネスロジックは散文(prose)です。

このアプローチが最も複雑なAPI統合にまで拡張可能かどうかは、未解決の問いです。しかし、Spotify Ads APIのように、意図と正しいPOSTリクエストシーケンスの間の距離が大きい場合には、驚くほどよく機能します。

本コンテンツは、信頼性の高い情報源をもとにAIツールを活用して作成され、編集者によるレビューを経て公開されています。専門家によるアドバイスの代替となるものではありません。