Swiss Groceries MCP について
Swiss Groceries MCP は、Migros、Coop、Aldi、Denner、Lidl などを対象に、商品検索、価格比較、買い物計画を行うスイス向け MCP サーバーです。セール情報や店舗在庫も扱い、条件を指定した複数店舗の計画を作成できます。
主な機能
- 01チェーン横断の商品検索と価格比較
- 02セール、店舗、在庫の検索
- 03単店・複数店舗の買い物計画
- 04標準化された商品栄養情報
- 05MCP 対応クライアントで利用
活用シーン
- 01スーパー各社の商品価格を比較
- 02場所と買い物リストから節約計画を作成
- 03近隣店舗と商品の在庫を確認
- 04週間セールやレシピ食材の特価を集約
MCP 対応
MCP クライアントに商品検索・詳細、セール、店舗、在庫、買い物計画のツールを公開し、プロンプトとチェーン機能を示すリソースも提供します。stdio クライアントに対応します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y @nicktcode/swissgroceries-mcpDENNER_JWTシークレットOptional pre-supplied Denner Bearer JWT. Without it, the adapter self-registers anonymously on first use and rotates the token automatically.LIDL_DEFAULT_STOREDefault Lidl store ID used when no storeIds are passed. Defaults to CH0149.SWISSGROCERIES_USER_AGENT_COOPOverride the User-Agent string for Coop calls if DataDome ever blocks the default.SWISSGROCERIES_LOG_LEVELLogging verbosity: silent, info (default), or debug.SWISSGROCERIES_DISABLE_CACHESet to 1 to bypass the in-memory HTTP response cache.ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
7掲載時のツール一覧 · 3 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| near | any | はい | 検索半径の中心です。座標、スイスの郵便番号、または自由形式の住所を渡します。 |
| chains | array | いいえ | 結果を指定したチェーンに限定します。省略すると、設定済みのすべてのチェーンを検索します。 |
| radiusKm | number | いいえ | 検索半径(キロメートル単位、1~50)です。デフォルトは 5 km です。 |
詳細
swissgroceries-mcp
Model Context Protocolを利用した、スイスの食料品をリアルタイムで買い物できるツールです。商品を検索し、Migros、Coop、Aldi、Denner、Lidl、Farmy、Volgshop、Otto's、Coop Cityの価格を比較したり、週間セールを確認したり、複数店舗を巡る買い物の計画を立てたりできます。MCP互換のあらゆるクライアント(Claude Desktop、Claude Code、Cursor、Cline、Continue、VS CodeのMCP拡張機能、カスタムクライアント)で動作します。
免責事項
これは個人の趣味のプロジェクトです。Migros、Coop、Aldi、Denner、Lidl、Farmy、Volg、Otto's、その他の小売業者とは提携しておらず、承認や支援も受けていません。一般にアクセス可能なモバイルアプリのエンドポイントを利用し、エンドユーザーがスイスでの食料品の買い物をより便利にできるようにしています。
これらの店舗の関係者で、懸念事項(APIの利用、ブランド表示、スクレイピングの頻度など)がある場合は、GitHubからメンテナーまでご連絡ください。話し合って解決します。問題を大きくする必要はありません。
APIの安定性:ここで使用しているチェーンのAPIは非公式であり、予告なく変更される可能性があります。上流の変更による障害について、メンテナーは責任を負いません。影響を受けるアダプターを更新できるよう、レスポンスのサンプルを添えてIssueを作成してください。
PRを歓迎します。 新しいチェーン、より優れたマッチャー、よりスマートな戦略、バグ修正、ドキュメントの改善など、あらゆる貢献を歓迎します。CONTRIBUTING.mdをご覧ください。
インストール
アカウント、トークン、APIキーは不要です。Dennerアダプターは初回使用時に匿名クライアントを自動登録し、それ以外はすべて公開エンドポイントを使用します。
Claude Desktop(ワンクリック)
リリースページからswissgroceries-mcp.mcpbをダウンロードし、次の手順でインストールしてください。
- macOS:ダブルクリックするか、Claude Desktopアプリのアイコンにドラッグします。
- Windows:設定 → 拡張機能 → 詳細設定 → 拡張機能をインストール → ファイルを選択します。
Claude Code(ワンライナー)
claude mcp add swissgroceries -- npx -y @nicktcode/swissgroceries-mcp
Cursor / Cline / Continue / VS Code / Claude Desktop(手動設定)
ほとんどのMCP互換クライアントでは、同じJSONサーバーエントリを使用できます。クライアントのMCP設定ファイルに追加してください(パスは異なるため、クライアントのドキュメントを参照してください)。
{
"mcpServers": {
"swissgroceries": {
"command": "npx",
"args": ["-y", "@nicktcode/swissgroceries-mcp"]
}
}
}
一般的な設定ファイルのパス:
- Claude Desktop:
~/Library/Application Support/Claude/claude_desktop_config.json(macOS)、%APPDATA%\Claude\claude_desktop_config.json(Windows)。 - Cursor:プロジェクト内の
.cursor/mcp.json、またはグローバル設定の~/.cursor/mcp.json。 - Cline / Continue / VS Code:各クライアントのMCPドキュメントを参照してください。
- カスタムクライアント:stdioベースのMCPクライアントであれば、
npx -y @nicktcode/swissgroceries-mcpを直接起動できます。
質問できること
価格比較
- 「8001 チューリッヒ付近で、今いちばん安く牛乳を買えるのはどこですか?」
- 「Migros と Coop のパスタの価格を比較してください。」
- 「3 CHF 未満のオーガニック牛乳を表示してください。」
買い物の計画
- 「8050 付近で牛乳、パン、卵、鶏肉、パスタが必要です。出費を抑えるには、どこで買い物をすればよいですか?」
- 「4052 バーゼル付近で、5品目の週の買い物を計画してください。立ち寄り先は1か所だけにしてください。」
- 「合計金額が最安になるように商品を店舗間で振り分けてください。ただし、立ち寄り先が1か所増えるごとに2 CHF のペナルティを加えてください。」
プロモーションとお得情報
- 「今週、Aldi では何がセール中ですか?」
- 「今週終了する Migros のチーズのお得情報はありますか?」
- 「各チェーンのパスタのプロモーションをすべて表示してください。」
店舗と在庫
- 「ベルン中央駅から3 km以内にある Coop の店舗を探してください。」
- 「近くの Migros で、商品 4389992 の在庫があるのはどこですか?」
- 「8050 付近の Denner の店舗を一覧表示してください。」
ツール
| ツール | 機能 |
|---|---|
find_stores | 場所の近くにある食料品店を、チェーンと半径で絞り込んで検索します。 |
search_products | 正規化された価格、単価、サイズ、タグを使って、複数チェーンの商品を検索します。 |
get_product | チェーンと商品 ID の組み合わせに対応する商品の詳細を取得します。 |
get_promotions | 現在のプロモーション情報を取得します。チェーン、キーワード、店舗、終了日で絞り込めます。 |
find_stock | 指定した商品を在庫しているチェーン店舗を検索します。 |
plan_shopping | 場所の近くで、買い物リストに基づいて複数店舗を回る計画を立てます。 |
health_check | 登録済みの各チェーンアダプターを確認し、ステータス、レイテンシ、機能を報告します。 |
各ツールはフィールドごとの説明を含む詳細な JSON Schema を公開するため、LLM はいつ、どのように呼び出せばよいかを把握できます。
プロンプト
| プロンプト | 機能 |
|---|---|
weekly_deals_digest | 設定済みのチェーンを対象に、今週のお得な食料品情報を要約します。カテゴリ、チェーン、場所による絞り込みは任意です。 |
compare_basket_across_chains | すべてのチェーンを対象に買い物かごの内容を比較し、1店舗での購入と店舗間での振り分けのどちらがよいかを提案します。 |
cheapest_recipe_ingredients | 食材リスト(またはレシピの URL)をもとに、各品目を最安で購入できる場所を探し、まとめて買い物プランを作成します。 |
プロンプトは、MCP 対応クライアント(Claude Desktop、Cursor、Cline)でワンクリックテンプレートとして表示されます。適切なツール呼び出しにつながる構造化されたユーザーメッセージを生成します。使い始める際や、サーバーでできることを確認する際に便利です。
リソース
| URI | 内容 |
|---|---|
swissgroceries://chains | 登録済みのチェーンアダプターと各機能(productSearch、productDetail、storeSearch、promotions、perStoreStock、perStorePricing)を列挙した JSON リストです。 |
チェーン対応状況
| チェーン | 商品検索 | プロモーション | 店舗ごとの在庫 | 栄養情報 | 認証 |
|---|---|---|---|---|---|
| Migros | 全カタログ | あり | あり | あり(商品詳細) | ゲストトークン(自動取得、有効期限切れ時にローテーション) |
| Coop | coop.ch カタログ(coopathome) | あり | あり(地域別) | あり(商品詳細) | なし |
| Aldi | 全カタログ | あり | なし | なし(API が公開するのはアレルゲンに関する表示のみ) | なし |
| Denner | 全カタログ | あり | なし | なし | 匿名のセルフ認証(登録+サインイン、ローテーション) |
| Lidl | lidl.ch ストアフロント経由のオンライン商品(現在および今後の週替わり商品、約600点。食品のみ、de/fr/it) | あり(週刊チラシ) | なし | なし | なし |
| Farmy | 全カタログ(オーガニック商品の配送) | あり(取り消し線付き価格のフィルター) | なし(配送のみ) | なし | なし |
| Volgshop | 全カタログ | あり(on_sale フィルター) | なし(配送のみ) | あり(自由記述属性から解析。基準量は100gと仮定) | なし |
| Otto's | 食料品関連(食品、ドラッグストア、ベビー用品) | あり(priceLabels ファセット) | あり(店舗ごとの stockLevel) | なし | なし |
| Coop City | 百貨店カタログ(coop-city.ch:化粧品、家庭用品、ファッション、電子機器)。オプトイン:chains に coopcity が含まれる場合のみ検索されます | あり(hasDiscount ファセット。現在価格のみで、通常価格や終了日はありません) | あり(店舗ごとの stockLevel、最大50件) | なし | なし |
NormalizedProduct.nutrition は、標準的なスイスの表示項目である energyKj、energyKcal、fat、saturatedFat、carbs、sugar、fiber、protein、salt を用いて、100g(または100ml)あたりの値に正規化されます。そのため、各チェーンの上流 API でデータの公開場所や形式が異なっていても、利用側でチェーンをまたいだ並べ替え(「ラザニアの100gあたりのタンパク質量が最も多い商品」など)ができます。欠落している項目や解析できない項目は undefined のままになり、アダプターが値を捏造することはありません。
設定
| 環境変数 | デフォルト | 効果 |
|---|---|---|
DENNER_JWT | (未設定) | Denner の Bearer JWT を事前に指定するオプションです。指定しない場合、アダプターは初回使用時に匿名で自動登録し、トークンを自動的にローテーションします。 |
LIDL_DEFAULT_STORE | CH0149 | storeIds が渡されない場合に使用する、デフォルトの Lidl 店舗 ID です。 |
SWISSGROCERIES_USER_AGENT_COOP | (デフォルトの iOS Safari UA) | DataDome がデフォルトの User-Agent をブロックした場合に、Coop の呼び出しで使う User-Agent を上書きします。 |
SWISSGROCERIES_LOG_LEVEL | info | silent、info、または debug を指定します。 |
SWISSGROCERIES_DISABLE_CACHE | (未設定) | 1 を設定すると、インメモリ HTTP キャッシュを無効にします(デバッグに便利です)。 |
仕組み
各食料品チェーンは独立したアダプター(src/adapters/<chain>/)でラップされ、認証、HTTP 呼び出し、未加工データから正規化データへのマッピングを処理します。すべてのアダプターは同じ形式の NormalizedProduct、NormalizedStore、NormalizedPromotion(src/adapters/types.ts で定義)を生成するため、システムのほかの部分は、どのチェーンと通信しているかを把握する必要がありません。
HTTP ユーティリティ(src/util/http.ts)は、migros-api-wrapper ライブラリに処理を委ねる Migros を除くすべてのアダプターを支えています。メモリ内でのレスポンスキャッシュ(TTL は 5 分)、指数バックオフによる再試行(3 回、基本間隔は 250 ms)、ホストごとのレート制限(1 秒あたり約 10 リクエスト)、および連続 5 回の失敗後に開き、60 秒後にリセットされるホストごとのサーキットブレーカーを備えています。
買い物プランナー(src/services/planner.ts)は、すべての有効なアダプターで店舗検索と商品検索を並列に実行し、その結果を 3 つのモードに対応した戦略ソルバー(src/services/strategy.ts)に渡します。
single_store:立ち寄り先の数を最小限にします。split_cart:停止ごとのペナルティを設定可能にし、チェーンを分けた場合の最安プランを選びます。absolute_cheapest:立ち寄り先の数を考慮せず、チェーンを分けた場合の最安プランを選びます。
チェーン間の比較を公平に保つため、カテゴリテキストの正規性フィルター(src/services/matcher.ts の isCanonical)を使用します。少なくとも 1 つのチェーンから、カテゴリテキストが検索語に一致する商品が返された場合、その商品について、関連性の低い商品(たとえば、「apfel」の検索時に返される Apfelschorle)だけを返したチェーンの結果は比較表から除外されます。
MCP client (any LLM)
│
│ MCP tool call
▼
src/index.ts ── buildRegistry() ────────────────────────────────────────┐
│ │
│ routes to tool handler │
▼ ▼
src/tools/ src/adapters/
find_stores.ts ──► geocoding ──► adapter.searchStores migros/
search_products.ts ──────────────► adapter.searchProducts coop/
get_product.ts ──────────────► adapter.getProduct aldi/
get_promotions.ts ──────────────► adapter.getPromotions denner/ (auto-auth)
find_stock.ts ──────────────► adapter.findStoresWithStock lidl/
plan_shopping.ts ──► geocoding ──► planner ──► strategy solver
│
NormalizedProduct
NormalizedStore
NormalizedPromotion
ソースからビルドする
node --version # requires Node.js >=20
git clone https://github.com/nicktcode/swissgroceries-mcp
cd swissgroceries-mcp
npm install
npm run build
.mcpb バンドルもローカルでビルドするには、次を実行します。
npx tsx scripts/build-mcpb.ts
トラブルシューティング
Coop の「DataDome challenge」エラー
Coop のボット対策に検知されています。SWISSGROCERIES_USER_AGENT_COOP に新たに取得した iOS Safari の User-Agent 文字列を設定して、もう一度お試しください。
Denner の「auth_expired」エラー
アダプターがトークンを自動的にローテーションするため、このエラーはまれです。解消しない場合は、独自に設定した DENNER_JWT を解除し、アダプターによる初期設定を最初からやり直してください。
Lidl の検索結果が 0 件になる
スイスの Lidl にはオンライン食料品店がありません。lidl.ch には、現在と次週の週間セール(食品と非食品を合わせて約 600 品目)のみが掲載されています。検索対象はその品ぞろえのため、今週または次週のセール対象でない商品は、検索結果が 0 件になります。これは想定どおりの動作です。
ZIP が不明というエラー
静的な参照テーブルには、スイスの公式郵便番号 3,190 件がすべて登録されています。お使いの郵便番号が見つからない場合は、{ lat, lng } を直接渡すか、不足している PLZ を添えて issue を作成してください。
Migros の店舗が現在地から遠く離れている
Migros の店舗検索 API は、クエリごとの結果を約 10 件に制限しています。アダプターは、ZIP から導出した都市のヒントを渡します。ZIP に基づくジオコーディングをせずにアダプターを直接呼び出す場合は、cityHint を明示的に渡してください。
開発
npm test # full test suite, no network calls
RUN_LIVE=1 npm test # also runs live smoke tests against real chain APIs
npm run dev # tsx watcher for local iteration
SWISSGROCERIES_DISABLE_CACHE=1 RUN_LIVE=1 npm test # cache off, useful for debugging
SWISSGROCERIES_LOG_LEVEL=debug npm run dev # verbose logging
テストスイートでは Vitest を使用します。フィクスチャ JSON ファイルは tests/fixtures/<chain>/ にあります。scripts/ のキャプチャスクリプトを使うと、フィクスチャを更新する方法を確認できます。
新しいチェーンの追加
詳しい手順については、CONTRIBUTING.md を参照してください。概要は次のとおりです。
- チェーンの iOS または Android アプリで Charles Proxy または mitmproxy を使い、API レスポンスを取得します。
- 既存のパターンに従って、
src/adapters/<chain>/{client,tags,normalize,index}.tsを作成します。最もシンプルな参考例としてsrc/adapters/aldi/を使用してください。 - 未加工のレスポンスを
NormalizedProduct、NormalizedStore、NormalizedPromotionにマッピングします。 - 機能フラグを正確に宣言します。
src/index.tsのbuildRegistry()にアダプターを登録します。tests/adapters/にフィクスチャベースのテストを追加します。
ライセンス
v0.10.0 以降は PolyForm Shield 1.0.0 です。このソフトウェアや、これを基にした作者自身の製品(スイスの食料品検索、価格比較、ショッピングアプリまたはサービス)と競合しない用途であれば、製品が無料であっても使用および改変できます。ご自身の MCP クライアントでの個人利用は問題ありません。LICENSING.md をご覧いただくか、[email protected] までお問い合わせください。
v0.7.5 から v0.9.0 は AGPL-3.0-only の下で、v0.7.4 以前は MIT の下でリリースされており、公開済みの各バージョンにはそれぞれ元のライセンスが適用されます。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。