mcpField
G
google-maps-api

google-maps-api

github.com/tivojnその他6403 回インストール36 週間前に更新
リポジトリ

google-maps-api について

google-maps-apiは、Google Maps Platform REST APIを呼び出し、構造化JSONを取得するコマンドラインスキルです。地図、ルート、場所、環境、地理空間サービスを扱い、APIキーと対象APIの有効化が必要です。

主な機能

  1. 01住所や座標をジオコーディング
  2. 02場所を検索して詳細を取得
  3. 03ルートと距離マトリックスを取得
  4. 04天気、大気質、花粉を照会
  5. 05標高、太陽光、道路データを取得
  6. 06静的マップとStreet View画像を生成

活用シーン

  1. 01場所を探して詳細を確認
  2. 02ルートを計画し移動距離を比較
  3. 03地域の天気や環境状況を確認
  4. 04住所の検証とGPS軌跡の処理

インストール

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

$npx skills add https://github.com/tivojn/google-maps-api-skill --skill google-maps-api

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

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

.env.example
.gitignore
README.md
.claude-plugin/
plugin.json
examples/
trip-plan-example.html
scripts/
gmaps.py

詳細

Google Maps Platform - Universal API Skill

重要な動作ルール

このスキルでは、以下のルールがほかのすべての指示に優先します:

  1. 問題が発生したら、すぐに伝えてください。 API 呼び出しが失敗した場合(403、REQUEST_DENIED、「有効化されていない」など)、処理を止め、何が起きたかを分かりやすい言葉でユーザーに伝えてください。ウェブ検索やほかの代替手段で、黙って回避してはいけません。Playwright を使って解決する方法を提案してください(下記の「API の有効化をガイドする」セクションを参照)。

  2. HTML の生成前に確認してください。 ユーザーに確認せず、HTML ページの作成を始めてはいけません。ユーザーはテキストでの回答、JSON 出力、簡単な要約を求めているだけかもしれません。「これについてインタラクティブな HTML ページを作成しますか?それともテキストでの要約で十分ですか?」と尋ねてください。

  3. 出力形式を選ぶ前に確認してください。 ユーザーの依頼に対して、テキスト、JSON、ビジュアルページのいずれでも回答できる場合は、どれを希望するか尋ねてください。決めつけないでください。

概要

Google Maps Platform のすべての REST API に対応する、フル機能の CLI クライアントです。ブラウザベースの google-maps スキルとは異なり、このスキルは Google の API を直接呼び出すため、高速で構造化された JSON レスポンスを取得できます。マップ、ルート、場所、環境、地理空間サービスにわたる 20 以上の API に対応しています。

セットアップ

1. Google Maps API キーを取得する
  1. Google Cloud Console にアクセスします
  2. プロジェクトを作成するか、選択します
  3. 必要な API を有効にします(下記の API 一覧を参照)
  4. API とサービス > 認証情報に移動し、API キーを作成します
  5. (推奨)キーを必要な API のみに制限します
2. API キーを保存する

以下の場所のいずれかにある .env ファイルに追加します(上から順に検索されます):

# Option 1: Project directory .env
echo 'GOOGLE_MAPS_API_KEY=your_key_here' >> .env

# Option 2: Home directory .env
echo 'GOOGLE_MAPS_API_KEY=your_key_here' >> ~/.env

# Option 3: Environment variable
export GOOGLE_MAPS_API_KEY=your_key_here
3. 必要な API を有効にする

Google Cloud Console > API とサービス > ライブラリで、必要な API を有効にします:

API 名コンソール上の名称
ジオコーディングGeocoding API
ルートRoutes API
場所Places API (New)
標高Elevation API
タイムゾーンTime Zone API
大気質Air Quality API
花粉Pollen API
太陽光Solar API
天気Weather API
住所検証Address Validation API
道路Roads API
ストリートビューStreet View Static API
静的マップMaps Static API
位置情報Geolocation API
航空写真ビューAerial View API
ルート最適化Route Optimization API
場所の集計Places Insights API

スクリプトの場所

~/.claude/skills/google-maps-api/scripts/gmaps.py

外部依存関係は不要です。Python 標準ライブラリ(urllib、json、ssl)のみを使用します。

API リファレンス全体

1. ジオコーディング

フォワードジオコーディング - 住所から座標を取得:

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py geocode "1600 Amphitheatre Parkway, Mountain View, CA"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py geocode "Tokyo Tower" --language ja --region jp
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py geocode "Paris" --components "country:FR"

リバースジオコーディング - 座標から住所を取得:

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py reverse-geocode 37.4224 -122.0856
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py reverse-geocode 48.8584 2.2945 --language fr
2. ルートと経路案内

2 つの地点間の経路案内を取得:

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py directions "New York, NY" "Boston, MA"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py directions "LAX" "SFO" --mode transit
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py directions "Seattle" "Portland" --alternatives --avoid-tolls
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py directions "A" "D" --waypoints "B" "C"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py directions "Home" "Work" --mode bicycling --units imperial

距離マトリックス - 複数の出発地と目的地:

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py distance-matrix \
  --origins "New York" "Boston" \
  --destinations "Philadelphia" "Washington DC"
3. 場所

テキスト検索 - クエリで場所を検索:

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py places-search "best pizza in Chicago"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py places-search "pharmacy" --location "40.714,-74.006" --radius 1000
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py places-search "5-star hotels" --min-rating 4.5 --open-now
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py places-search "EV charging" --type "electric_vehicle_charging_station"

周辺検索 - 座標付近の場所を検索:

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py places-nearby 40.7128 -74.0060 --type restaurant --radius 800
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py places-nearby 34.0522 -118.2437 --type cafe --max-results 5

場所の詳細 - 場所の詳しい情報:

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py place-details ChIJN1t_tDeuEmsRUsoyG83frY4

オートコンプリート - 入力中に候補を表示:

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py autocomplete "star" --location "37.7749,-122.4194"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py autocomplete "central p" --types "park"

場所の写真 - 写真の URL を取得:

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py place-photo "places/PLACE_ID/photos/PHOTO_REF" --max-width 800
4. 大気質

現在の状況:

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py air-quality 40.7128 -74.0060
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py air-quality 40.7128 -74.0060 --health --pollutants

過去のデータ(最大 30 日間):

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py air-quality-history 40.7128 -74.0060 --hours 48

予報(最大 96 時間):

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py air-quality-forecast 40.7128 -74.0060
5. 花粉

花粉予報(最大 5 日間、草本/雑草/樹木):

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py pollen 40.7128 -74.0060
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py pollen 34.0522 -118.2437 --days 5

返される情報:3 種類の植物タイプと 15 種の植物についての、世界花粉指数(UPI)。

6. 太陽光

建物の太陽光発電ポテンシャル:

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py solar 37.4219 -122.0841
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py solar 37.4219 -122.0841 --quality HIGH

返される情報:屋根の面積、日照時間、最適なパネル配置、エネルギー/コストの見積もり。

太陽光データレイヤー(DSM、フラックス、日陰ラスター):

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py solar-layers 37.4219 -122.0841 --radius 100
7. 天気

現在の状況:

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py weather 40.7128 -74.0060
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py weather 40.7128 -74.0060 --mode current

時間ごとの予報(最大 240 時間):

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py weather 40.7128 -74.0060 --mode hourly --hours 48

日ごとの予報(最大 10 日間):

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py weather 40.7128 -74.0060 --mode daily --days 7

直近の履歴(最大 24 時間):

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py weather 40.7128 -74.0060 --mode history --hours 12
8. 標高
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py elevation 39.7392 -104.9903
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py elevation --locations "39.7392,-104.9903|36.4555,-116.8666"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py elevation --path "36.578,-118.292|36.606,-118.099" --samples 20
9. タイムゾーン
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py timezone 40.7128 -74.0060
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py timezone 35.6762 139.6503 --language ja
10. 住所検証
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py validate-address "1600 Amphitheatre Pkwy, Mountain View, CA 94043"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py validate-address "123 Main St" --region US --enable-usps

返される情報:配達可能性の判定、修正済み住所、住所構成要素ごとの確認、USPS CASS データ。

11. 道路

道路にスナップ - GPS の軌跡を道路に合わせる:

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py snap-roads "60.170,-24.942|60.171,-24.941|60.172,-24.940"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py snap-roads "60.170,-24.942|60.172,-24.940" --interpolate

最寄りの道路:

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py nearest-roads "60.170,-24.942|60.171,-24.941"
12. ストリートビュー

CLI でのデータ利用(サーバー側で画像をダウンロード、料金は 1,000 件あたり $7):

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py streetview --lat 46.414 --lng 10.013 --heading 90
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py streetview --location "Eiffel Tower, Paris" --size 800x600
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py streetview --pano CAoSLEFGMVFpcE... --output paris_sv.jpg

HTML ページの場合 — 代わりに必ず Google マップへの直接リンクを使用してください(料金ゼロ、キーの露出ゼロ):

https://www.google.com/maps/@?api=1&map_action=pano&viewpoint={lat},{lng}&heading={heading}&pitch=0&fov=90

詳細については、下記の「HTML でのストリートビュー」セクションをご覧ください。

警告: 古い省略形式 @{lat},{lng},3a,75y,{heading}h,90t は使用しないでください。この形式は信頼性が低く、ストリートビューではなく、ズームアウトされた世界地図が表示されることがよくあります。必ず上記の map_action=pano 形式を使用してください。

13. 静的マップ
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py static-map --lat 40.714 --lng -74.006 --zoom 13
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py static-map --center "Tokyo" --maptype satellite --zoom 12
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py static-map --center "NYC" --markers "color:red|40.714,-74.006" --size 800x600
14. ジオロケーション
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py geolocation
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py geolocation --wifi "00:11:22:33:44:55,-65" "66:77:88:99:AA:BB,-72"
15. 航空ビュー(米国のみ)
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py aerial-view check --address "1600 Amphitheatre Pkwy, Mountain View"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py aerial-view render --address "1600 Amphitheatre Pkwy, Mountain View"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py aerial-view get --video-id VIDEO_ID
16. ルート最適化

車両ルーティング問題(VRP)を解決します:

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py route-optimize problem.json --project my-gcp-project

入力 JSON 形式:Google Route Optimization API 仕様に準拠した {"model": {"shipments": [...], "vehicles": [...]}}。

17. Places Aggregate(インサイト)

エリア内でフィルターに一致する場所の数を数えるか、一覧表示します:

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py places-aggregate --location "40.714,-74.006" --radius 5000 --type restaurant
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py places-aggregate --location "34.052,-118.244" --type cafe --min-rating 4.0 --insight INSIGHT_PLACES
18. Maps Embed URL(無料)

埋め込み可能な地図 URL を生成します(無料、無制限):

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py embed-url --mode place --query "Eiffel Tower"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py embed-url --mode directions --origin "NYC" --destination "Boston"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py embed-url --mode streetview --lat 46.414 --lng 10.013

Claude の使用パターン

ユーザーが位置情報、地理、環境に関する質問をした場合は、適切なコマンドを使用してください。

ユーザーの意図コマンド
「……はどこですか?」geocode
「……の住所は何ですか?」reverse-geocode
「A から B へはどう行けばよいですか?」directions
「A から B までの距離はどれくらいですか?」distance-matrix
「……の近くにあるレストランを探して」places-search または places-nearby
「……の営業時間は?」place-details
「……の空気質は?」air-quality
「今日は花粉が多いですか?」pollen
「……の天気は?」weather
「この住所は有効ですか?」validate-address
「……の標高は?」elevation
「……のタイムゾーンは?」timezone
「……の地図を見せて」static-map
「屋根にソーラーパネルを設置できますか?」solar
「配送ルートを最適化して」route-optimize
「エリア内にコーヒーショップはいくつありますか?」places-aggregate

インタラクティブ HTML の出力

重要:HTML を生成する前に、必ずユーザーに確認してください。 ユーザーの明示的な承認なしに、HTML ファイルの作成を開始してはいけません。結果をテキストで提示した後、次のように尋ねてください。

「ブラウザーで開けるインタラクティブな HTML ページにまとめましょうか?デフォルトのテーマは Warm Stone Sunrise(明るく、暖色系のプレミアムなテーマ)です。」

ユーザーが「はい」と答えた場合(または HTML、ページ、地図を明示的に依頼した場合)は、生成してください。返答がない場合や「いいえ」と答えた場合は、テキストまたは JSON の結果のみを提示してください。

デフォルトでは、Google Maps の埋め込み iframe(output=embed)を使用して、キー不要の HTML ページを生成してください — API キーは不要で、キーが露出するリスクもありません。埋め込みでは対応できない高度なインタラクティブ機能(カスタムマーカー、ポリライン、クラスタリングなど)をユーザーが明示的に求めた場合に限り、Maps JavaScript API(<script src="https://maps.googleapis.com/maps/api/js?key=...">)を使用してください。

ゼロキーの埋め込み iframe(デフォルト)

マップには次の iframe 形式を使用してください。API キーは不要で、無料です。

場所/スポットのマップ:

<iframe src="https://maps.google.com/maps?q=Oahu+Hawaii&z=10&output=embed"
  width="100%" height="400" style="border:0" allowfullscreen></iframe>

ルート案内マップ:

<iframe src="https://maps.google.com/maps?saddr=Los+Angeles+CA&daddr=San+Jose+CA&output=embed"
  width="100%" height="400" style="border:0" allowfullscreen></iframe>

パラメーター:

  • q — 場所の名前または住所(URL エンコードし、スペースには + を使用)
  • saddr / daddr — ルート案内の出発地/目的地
  • z — ズームレベル(1~20、デフォルトは約12)
  • output=embed — 必須。埋め込み可能にします
  • ll — 任意の中心座標 lat,lng

警告: Google Maps の埋め込み iframe では loading="lazy" を使用しないでください。遅延読み込みにより、画面外の iframe の読み込みが妨げられ、画面下部にあるマップが永久に空白で表示されることがあります。loading 属性は常に省略するか、loading="eager" を使用してください。

結果の種類デフォルトの HTML 要素
ストリートビューGoogle Maps への直接リンク(map_action=pano)— 新しいタブでインタラクティブなストリートビューを全画面表示します。「HTML でのストリートビュー」セクションを参照してください。
ルート案内saddr/daddr と output=embed を使った埋め込み iframe
場所の検索q=place+name と output=embed、情報カードを使った埋め込み iframe
周辺の検索位置を中心にした埋め込み iframe とスポットカード
静的マップq と z を使った埋め込み iframe(ズームとドラッグが可能)
天気/空気質位置の埋め込み iframe と気象状況カード、アイコン、グラフ
標高標高プロファイルのグラフと、経路マーカー付きの埋め込み iframe
太陽光建物の位置の埋め込み iframe と太陽光発電の可能性に関する統計
旅行プラン複数のセクションを組み合わせたページ:埋め込み iframe のマップ、スポットカード、天気ウィジェット

HTML ページを生成する場合:

  1. 自己完結型の単一の .html ファイルを使用します(CSS/JS をインライン化し、外部依存関係は使用しません)。
  2. すべてのマップでデフォルトとしてゼロキーの埋め込み iframe(output=embed)を使用します。HTML に API キーを含めないでください。
  3. **HTML ページで google.maps.StreetViewPanorama や Street View JS API を使用してはいけません。**ストリートビューには、常に map_action=pano を指定した Google Maps への直接リンクを使用してください。これは厳守するルールです。
  4. ユーザーが高度なインタラクティブ機能を明示的に求めない限り、Google Maps JS API の <script> タグを含めてはいけません。output=embed の iframe 方式なら、ほとんどの用途で API キーなしに対応できます。
  5. 説明的な名前を付けて現在の作業ディレクトリに保存します(例:marea-streetview.html、nyc-trip-plan.html)。
  6. 作成後、open <file> を使ってブラウザーで自動的に開きます(macOS)。
HTML でのストリートビュー — キーの露出ゼロ

厳守事項:HTML ページで JavaScript API または Embed API を使ってストリートビューを埋め込まないでください。 どちらの方法でも、クライアント側のコードに API キーが露出します。代わりに、ユーザーのブラウザーで完全なインタラクティブなストリートビューを開く Google マップへの直接リンクを必ず使用してください。費用も API キーの露出もありません。

直接リンクの形式(Google Maps URLs API — 信頼性の高い方法):

https://www.google.com/maps/@?api=1&map_action=pano&viewpoint={lat},{lng}&heading={heading}&pitch={pitch}&fov=90

パラメーター:

  • viewpoint={lat},{lng} — ストリートビューの場所の座標
  • heading — 度数で指定する方位角(0=北、90=東、180=南、270=西)
  • pitch — 仰角(-90=下、0=水平、90=上)
  • fov — 度数で指定する視野角(10~100、デフォルトは90)
  • map_action=pano — 必須 — ストリートビューのパノラマモードを明示的に起動します

警告: 古い省略形式 @{lat},{lng},3a,75y,{heading}h,{pitch}t は使用しないでください。この形式は信頼性が低く、ストリートビューが開かずにズームアウトされた世界地図が表示されることがよくあります。必ず map_action=pano 形式を使用してください。

例:

https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=40.76545,-73.98115&heading=90&pitch=0&fov=90
https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=48.8584,2.2945&heading=180&pitch=0&fov=90
https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=46.414,10.013&heading=270&pitch=-5&fov=90

HTML ページでの実装方法:

単独のストリートビューボタンの場合:

<a href="https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=40.76545,-73.98115&heading=90&pitch=0&fov=90"
   target="_blank" rel="noopener noreferrer"
   style="display:inline-block; padding:12px 24px; background:#4f46e5; color:white;
          border-radius:8px; text-decoration:none; font-weight:600;">
  Open Street View →
</a>

JavaScript 関数の場合(例:場所が多数ある旅行計画ページ):

function openStreetView(lat, lng, name) {
  window.open(
    `https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=${lat},${lng}&heading=0&pitch=0&fov=90`,
    '_blank'
  );
}

コンテキスト付きのカード/プレビューの場合:

<div class="streetview-card">
  <div class="sv-preview">
    
    <div class="sv-overlay">
      <span class="sv-icon">🔭</span>
      <span>Interactive Street View</span>
    </div>
  </div>
  <a href="https://www.google.com/maps/@?api=1&map_action=pano&viewpoint={lat},{lng}&heading=0&pitch=0&fov=90"
     target="_blank" rel="noopener noreferrer" class="sv-button">
    Open in Google Maps →
  </a>
  <p class="sv-note">Opens full 360° interactive Street View — pan, zoom, and walk around</p>
</div>

統合された旅行計画ページでは、 以前の StreetViewPanorama セクションを、スタイル付きのボタン/リンクカードに置き換えてください。ユーザーがクリックすると、新しいタブで完全なストリートビューが開きます。Google マップから直接、完全にインタラクティブな体験を利用できます。

この方法を採用する理由:

  • API キーの露出ゼロ — HTML ソースにキーが一切含まれません
  • 費用ゼロ — API 呼び出しも課金もありません
  • より優れた体験 — 制限付きの埋め込みではなく、ナビゲーション機能を備えた完全な Google マップのストリートビューを利用できます
  • あらゆるデプロイ方式に対応(個人利用、BYOK、プラットフォームキー)
統合型のワンストップページ

複数の要素を含むリクエスト(旅行計画、場所の調査、比較など)では、収集したすべてのデータを1つのインタラクティブなダッシュボードにまとめた、統合型 HTML ページの生成を必ず提案してください。 ターミナル出力をスクロールし続けるのではなく、ユーザーがすべての情報を1か所で確認できるようにします。

統合型ページには、会話中に収集したデータをすべて含めます。たとえば、旅行計画ページには次のような情報をまとめられます。

  • 運転ルートのポリラインを含むインタラクティブなルートマップ
  • 目的地の天気ウィジェット
  • 写真、評価、営業時間を含むホテル/場所のカード
  • Google マップで完全な360°ビューを開くストリートビューリンク付きのレストランのおすすめ
  • タイムライン/旅程セクション
  • レンタカーと空港の情報

統合型ページのデザイン原則:

  • セクションを明確に分けた、すっきりとしたモダンなダッシュボードレイアウトを使用します
  • 各セクションは、テキストだけでなく、マップ、カード、アイコン、バッジなどを使って視覚的に充実させます
  • スムーズなスクロールナビゲーションを含めます(アクティブなリンクを強調表示する、すりガラス風の固定ナビゲーション)
  • スクロールに合わせてアニメーションを表示します(IntersectionObserver を使って各セクションを下からフェードイン)
  • あらゆる画面サイズに完全対応させます。デスクトップ(>1024px)、タブレット(641~1024px)、モバイル(<=640px)、小型スマートフォン(<=380px)
  • モバイルでは、カード、ボタン、旅行チップ、統計グリッドを1列に並べます
  • モバイルでは、マップの高さを縮小し(280px)、ボタンを全幅にします
デフォルトテーマ:温かみのあるストーン・サンライズ

ユーザーが別のテーマを指定しない限り、すべての HTML ページでこのテーマがデフォルトで使用されます。

カラーパレット:

  • 背景:#fafaf9(温かみのあるオフホワイト)
  • サーフェス:カードは #ffffff、代替サーフェスは #f5f5f4
  • 境界線:#e7e5e4(温かみのあるストーン)、#f0eeec(明るい区切り線)
  • テキスト:メインは #1c1917、セカンダリは #57534e、ターシャリは #a8a29e
  • アクセント:#4f46e5(インディゴ)、ライトは #eef2ff、ミッドは #c7d2fe
  • セマンティックカラー:緑 #059669、アンバー #d97706、赤 #dc2626、青 #2563eb

タイポグラフィ:

  • 見出し:Playfair Display(セリフ体、ウェイト 700~900)— エディトリアルで高級感のある雰囲気
  • 本文:Inter(サンセリフ体)、フォントスムージングを全面適用
  • セクションのパターン:大文字のラベル(11px、アクセントカラー)→ セリフ体のタイトル(26px)→ 説明(14px、ターシャリカラー)

ヒーロー: linear-gradient(160deg, #eef2ff, #faf5ff, #fff7ed) — インディゴからラベンダー、ピーチへ

マップ: デフォルトでは、埋め込み iframe を使った Google Maps スタイルを使用します。Maps JS API を使用する場合(オプトイン)は、明るいカスタムスタイルを適用します。落ち着いたストーン系の色調、柔らかな青の水域 #c9d7e4、緑の公園 #d4e9d4、白い道路を使用します。

影: 基本は控えめな 0 1px 2px rgba(0,0,0,0.04)、ホバー時は 0 4px 6px

ナビゲーション: すりガラス風の固定表示(rgba(255,255,255,0.85) と backdrop-filter: blur(20px))、アクティブリンクには下線アニメーション

インタラクション: ホバー時にカードが浮き上がる(translateY(-2px))、タイムラインのドットが塗りつぶされ、光彩リングが表示される、ホバー時にステップがインデントされる、ボタンが浮き上がり影が強くなる

API キーのセキュリティと本番環境のアーキテクチャ

問題点

クライアント側の HTML/JavaScript に埋め込まれた API キーは、ブラウザーの開発者ツールからユーザーに見えてしまいます。個人利用では問題ありませんが、複数のユーザーにサービスを提供する本番アプリでは重大な問題になります。

デプロイモード

このスキルは、セキュリティ特性の異なる 3 つのデプロイモードに対応しています。

モード 1:個人利用/CLI 利用(単一ユーザー)

ユーザー自身の API キーを .env に設定し、gmaps.py でローカルに使用します。キーがマシンの外部に出ることはありません。

User's Machine
├─ .env (GOOGLE_MAPS_API_KEY=...)
├─ gmaps.py → calls Google APIs directly
└─ HTML pages → zero-key embed iframes (preferred) or key embedded (acceptable)

リスク:低 — ユーザー自身のマシンで、ユーザー自身のキーを使用します。 キーの制限:不要(または、使用する API に限定します)。 ベストプラクティス:個人利用でも、HTML ページにはキー不要の output=embed iframe を優先してください。カスタムマーカー、ポリライン、クラスタリングなどの高度な機能が必要な場合に限り、Maps JS API を使用します。

モード 2:ユーザーが自身のキーを持ち込む(マルチユーザーアプリ)

ユーザーが自身の Google API キーを設定します。請求はユーザー自身が管理します。

Your App
├─ User configures their own API key in app settings
├─ Key stored in user's profile (encrypted at rest)
├─ Used server-side for data queries
└─ Frontend key: user creates a separate domain-restricted key

リスク:低~中 — ユーザー自身のキーであり、請求もユーザー自身が負担します。 重要:共有・エクスポート可能な HTML ページを生成する際、ユーザーのキーを埋め込んでは絶対にいけません。代わりに静的エクスポートを使用してください(下記の「共有可能なエクスポートモード」を参照)。 オンボーディング:GCP Console の設定と API の有効化をユーザーに案内してください(上記の「セットアップ」セクションを参照)。

モード 3:プラットフォームキー(ユーザーがあなたに支払う)— 重大

ユーザーはあなたのプラットフォームに料金を支払います。Google API キーを用意するのはあなたです。ユーザーにキーを見せては絶対にいけません。

アーキテクチャ:2 キー+バックエンドプロキシ

┌─────────────────────────────────────────────────────┐
│  User's Browser                                      │
│                                                       │
│  HTML Page (served from app.yourdomain.com)           │
│  ├─ Interactive Maps  ← Frontend Key (domain-locked)  │
│  ├─ Street View       ← Frontend Key (domain-locked)  │
│  └─ All data (weather, places, directions, etc.)      │
│       ↑ pre-rendered from backend, NO key in browser  │
│                                                       │
└──────────────────┬────────────────────────────────────┘
                   │ /api/geocode, /api/directions, etc.
                   ▼
┌──────────────────────────────────────────────────────┐
│  YOUR Backend Server                                  │
│                                                       │
│  Backend Key (env var, never sent to browser)         │
│  ├─ Geocoding, Directions, Places, Weather, etc.      │
│  ├─ Street View Static → returns image bytes          │
│  └─ All data APIs proxied with your key server-side   │
│                                                       │
│  Key restricted by: Server IP address                 │
│  Even if leaked: won't work from other IPs            │
└──────────────────┬────────────────────────────────────┘
                   │
                   ▼
            Google Maps Platform

フロントエンドキー(クライアント側、HTML 内):

  • 有効にするもの:Maps JavaScript API のみ(インタラクティブなマップの描画用)
  • 制限方法:HTTP リファラー → https://app.yourdomain.com/*
  • 誰かがキーをコピーしても、あなたのドメインからしか使用できません
  • データ API(ジオコーディング、場所など)は呼び出せません。このキーでは無効になっています

バックエンドキー(サーバー側、非公開):

  • 有効にするもの:すべてのデータ API(ジオコーディング、ルート案内、場所、天気、花粉、太陽光など)
  • 制限方法:サーバー IP アドレス
  • ブラウザーに送信されることはなく、サーバーの環境変数内にのみ保存されます
  • 漏えいした場合でも、あなたのサーバーの IP からしか使用できません

このモードでの HTML ページの動作:

// UNSAFE — key exposed, data fetched client-side:
const service = new google.maps.DirectionsService();
service.route({ origin: 'JFK', destination: 'The Plaza' });

// SAFE — data pre-fetched by backend, only map rendering in browser:
const routeData = /* injected by server from backend API call */;
const path = google.maps.geometry.encoding.decodePath(routeData.polyline);
new google.maps.Polyline({ path: path, map: map });
GCP Console で 2 つのキーを設定する
ステップ 1:フロントエンドキーを作成する
  1. GCP Console の APIs & Services > Credentials に移動します
  2. Create Credentials > API Key をクリックします
  3. キーをクリックして編集します
  4. Application restrictions で HTTP referrers を選択します
  5. ドメインを追加します:https://app.yourdomain.com/*
  6. API restrictions で Restrict key を選択します
  7. Maps JavaScript API のみを有効にします
  8. 保存します
ステップ 2:バックエンドキーを作成する
  1. Create Credentials > API Key をもう一度クリックします
  2. キーをクリックして編集します
  3. Application restrictions で IP addresses を選択します
  4. サーバーの IP アドレスを追加します
  5. API restrictions で Restrict key を選択します
  6. 次を有効にします:Geocoding、Routes、Places (New)、Weather、Air Quality、Pollen、Solar、Elevation、Time Zone、Address Validation、Roads、Street View Static、Geolocation、Aerial View、Route Optimization
  7. 保存します
ステップ 3:アプリを設定する
# Backend server environment
GOOGLE_MAPS_BACKEND_KEY=AIzaSy...xxx   # Server-side only, IP-restricted
GOOGLE_MAPS_FRONTEND_KEY=AIzaSy...yyy  # Injected into HTML, domain-restricted
共有可能なエクスポートモード

ユーザーが HTML ページをダウンロードまたは共有(メール、Slack など)する場合は、API キーを一切含まない静的エクスポートを生成します:

要素アプリ内(インタラクティブ)共有可能なエクスポート
地図Maps JavaScript API(フロントエンドキー)Maps Embed API <iframe>(無料、キーの不正使用リスクなし)
ストリートビューGoogle Maps への直接リンク(キー不要)Google Maps への直接リンク(キー不要)
ルート線DirectionsRenderer(フロントエンドキー)パスを重ねた静的地図画像(base64)
データ(天気、場所)バックエンドで事前レンダリング同じ事前レンダリング済み HTML — API 呼び出し不要
API キーの露出フロントエンドキー、ドメイン制限ありキーなし

埋め込み URL を生成するには(無料、無制限):

python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py embed-url --mode place --query "Marea Restaurant NYC"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py embed-url --mode directions --origin "JFK" --destination "The Plaza Hotel NYC"
python3 ~/.claude/skills/google-maps-api/scripts/gmaps.py embed-url --mode streetview --lat 40.76545 --lng -73.98115
セキュリティの概要
デプロイ方法データ API地図の描画キーの露出共有可能
個人 CLIユーザーのキーをローカルで使用キー不要の埋め込み iframe(デフォルト)なしはい(キーなし)
個人 CLI(上級者向け)ユーザーのキーをローカルで使用Maps JS API(ポリライン、クラスタリングなどをオプトイン)ユーザー自身の責任いいえ(キーが漏洩)
BYOK(ユーザーのキー)サーバー上でユーザーのキーを使用ユーザーがフロントエンドキーを作成ユーザー自身の責任静的エクスポートのみ
プラットフォームキー(費用はあなたが負担)バックエンドキー(IP 制限あり)フロントエンドキー(ドメイン制限あり)安全静的エクスポートのみ
レート制限と不正使用の防止(プラットフォームモード)

複数のユーザーに自分のキーを使ってサービスを提供する場合は、次も実装します:

  • ユーザーごとのレート制限:ユーザー 1 人あたりの API 呼び出し数を 1 時間または 1 日単位で制限します
  • 認証:認証済みの有料ユーザーのみが API 呼び出しを実行できるようにします
  • 使用状況の追跡:課金に備えて、どのユーザーがどの API 呼び出しを実行したかを記録します
  • 割り当てアラート:予期しない急増を検知できるよう、GCP の課金アラートを設定します
  • 予算上限:GCP Console で 1 日あたりの最大支出額を設定します

エラー処理と API 設定のガイド

重要:コマンドが失敗した場合は、必ずすぐにユーザーに伝えてください。 Web 検索やその他の回避策に黙って切り替えてはいけません。ユーザーが修正方法を判断できるよう、何が壊れているのかを知らせる必要があります。

コマンドが失敗した場合は、エラーの種類を検知して、次のように応答します:

  • 403 Forbidden / API not enabled:停止します。ユーザーに伝えます。Playwright を使った手順を案内します(下記参照)
  • REQUEST_DENIED:停止します。ユーザーに伝えます。Playwright を使った手順を案内します(下記参照)
  • 400 Bad Request:パラメーターが無効です — API ドキュメントを確認します
  • 429 Rate Limited:リクエストが多すぎます — 短い待機時間を追加します
  • ZERO_RESULTS:結果が見つかりません — より広い条件で検索します
  • INVALID_REQUEST:必須パラメーターが不足しています
  • キーが見つからない:.env または環境変数に GOOGLE_MAPS_API_KEY が設定されていることを確認します
  • RefererNotAllowedMapError:フロントエンドキーの HTTP リファラー制限が現在のドメインと一致していません
API の有効化ガイド(Playwright による操作)

API が有効になっていない場合は、必ず最初にこの手順を案内してください。 この手順を省略したり、黙って回避したりしないでください。

ユーザーの API 呼び出しが 403、REQUEST_DENIED、または「API が有効になっていません」というエラーで失敗した場合:

  1. 何が起きたのかをわかりやすく伝えます:

    「[API Name] がまだ Google Cloud プロジェクトで有効になっていないようです。ご安心ください。ブラウザーで有効にする手順をご案内できます。今すぐ進めてもよろしいですか?」

  2. ユーザーが「はい」と答えたら、Playwright MCP を使って有効化を自動化します:

    Step 1: Navigate to the specific API's enablement page:
            https://console.cloud.google.com/apis/library/[API_ENDPOINT]
    
    Step 2: If a project selector appears, let the user pick their project
            (or auto-select if there's only one)
    
    Step 3: Click the "Enable" button
    
    Step 4: Wait for the confirmation (loading spinner → "API enabled" or
            the button changes to "Manage")
    
    Step 5: Confirm to the user: "Done! [API Name] is now enabled.
            Let me retry your request."
    
    Step 6: Retry the original command automatically
    
  3. Playwright で移動するためのAPI エンドポイント URL(以下の正確なパスを使用します):

    APIGCP ライブラリの URL パス
    ジオコーディングgeocoding-backend.googleapis.com
    Routesroutes-backend.googleapis.com
    Places(新)places-backend.googleapis.com
    Elevationelevation-backend.googleapis.com
    Time Zonetimezone-backend.googleapis.com
    Air Qualityairquality.googleapis.com
    Pollenpollen.googleapis.com
    Solarsolar.googleapis.com
    Weatherweather.googleapis.com
    Address Validationaddressvalidation.googleapis.com
    Roadsroads.googleapis.com
    Street View Staticstreet-view-image-backend.googleapis.com
    Maps Staticstatic-maps-backend.googleapis.com
    Maps JavaScriptmaps-backend.googleapis.com
    Maps Embedmaps-embed-backend.googleapis.com
    Geolocationgeolocation.googleapis.com
    Aerial Viewaerialview.googleapis.com
    Route Optimizationrouteoptimization.googleapis.com

    URL の形式:https://console.cloud.google.com/apis/library/[path_from_table]

  4. ユーザーが「いいえ」と答えた場合(手動での設定を希望する場合)、直接 URL を案内します:

    「わかりました。こちらが直接リンクです。「有効にする」をクリックしてください。 https://console.cloud.google.com/apis/library/[API_ENDPOINT]」

  5. 複数 API の一括有効化:初めて設定するユーザーに複数の API の有効化が必要な場合は、まとめて有効にすることを提案します:

    「よく使われる API(Geocoding、Routes、Places、Weather、Elevation、Time Zone、Maps JavaScript)をまとめて有効にできます。すべて設定してもよろしいですか?」

    その後、Playwright で各 API のページを順に開き、それぞれの「有効にする」をクリックします。

  6. Playwright による操作の重要事項:

    • ユーザーは、ブラウザーで Google Cloud Console にログイン済みである必要があります
    • ログインしていない場合は、まず https://console.cloud.google.com でログインするよう伝えます
    • 一部の API(Weather、Solar)では、プロジェクトで課金を有効にする必要がある場合があります
    • 有効化後、API が使用可能になるまで約 30 秒かかる場合があります
    • 「有効にする」ボタンが表示されず、「管理」と表示されている場合は、API はすでに有効です

料金に関する注意事項

ほとんどの API はリクエストごとに課金されます。主な無料枠と有料枠は以下のとおりです:

  • Maps Embed API:常に無料(共有可能なエクスポートに使用)
  • Maps JavaScript API:読み込み 1,000 回あたり $7
  • Street View(JS):パノラマ読み込み 1,000 回あたり $7 — HTML ページでは絶対に使用せず、代わりに Google Maps の直接リンクを使用してください(無料、キー不要)
  • Google Maps Platform の月額 $200 の無料クレジット
  • Routes API:機能に応じてリクエスト 1,000 件あたり $5~15
  • Places API:リクエスト 1,000 件あたり $17~40
  • 環境 API(Air Quality、Pollen、Solar):料金は API によって異なります
  • 最新の料金は Google Maps の料金を確認してください

備考

  • 出力はすべて JSON です(画像のダウンロードはファイルに保存されます)
  • 外部の Python 依存関係はありません。標準ライブラリのみを使用します
  • スクリプトは次の場所で .env を検索します:CWD、ホームディレクトリ、スキルディレクトリ
  • 画像 API(streetview、static-map)では、ファイルはローカルに保存されます
  • Weather API では、別途課金の有効化が必要な場合があります
  • Aerial View は米国の住所のみ対応しています
  • Route Optimization には GCP プロジェクト ID が必要です
  • Roads の制限速度情報には Asset Tracking ライセンスが必要です

コメント