Claude Codeにngrokプラグインを入れてローカルを公開しwebhookを受ける
ngrokのagent skillsをClaude Codeのプラグインとして入れ、ローカルの公開・webhook受信・認証付き共有を任せる手順と、auth tokenやsigning secretを扱うときの境界をまとめます。
ngrokはagent skillsのリポジトリ(ngrok/skills)を公開しており、Claude Codeではプラグインとして入れられます。入れると /ngrok:* のスラッシュコマンドが加わり、「ローカルのアプリを公開する」「Stripeのwebhookをローカルで受ける」といった依頼をClaude Codeに任せられます。
導入は2コマンドで済みます。気をつけたいのは、auth tokenやwebhookのsigning secretをClaude Codeに渡さない点です。
ngrokプラグインで何ができるようになるか
リポジトリはAgent Skillsの標準化の流れに沿った形式で書かれた、ngrok操作のスキル集です。ローカルサービスの公開、トラフィックのルーティングと保護、webhookの受信などを扱います。Claude Code、Cursor、ChatGPT、Codexのプラグインとして使えるほか、プラグインを介さず単体のスキルとしても入れられます。
タスク用のスキルは次の7つです。
| スキル | 担当 | 呼び出しの例 |
|---|---|---|
| expose-localhost | 担当ローカルサービスに公開URLを付ける(HTTP、SSH・RDP・DB向けの生TCP) | 呼び出しの例「ローカルサーバーを公開して」 |
| secure-endpoint | 担当アプリを変えずに認証・レート制限・IP制限・カスタム応答を前段に置く | 呼び出しの例「ngrokのURLにGoogleログインを付けて」 |
| receive-webhooks | 担当StripeやGitHubなど70以上のプロバイダーのwebhookを、署名検証つきで受ける | 呼び出しの例「Stripeのwebhookをローカルでテストしたい」 |
| run-mcp-gateway | 担当開発中のMCPサーバーを、Claudeなど各プロバイダーが別々の資格情報でつなげるようにする | 呼び出しの例「ローカルのMCPサーバーにClaudeをつなぎたい」 |
| provision-sandbox-access | 担当サンドボックスやテナントごとに独立したエンドポイントをプログラムで払い出す | 呼び出しの例「顧客ごとにエンドポイントが要る」 |
| troubleshoot-ngrok | 担当ngrokのエラーを診断する | 呼び出しの例「ERR_NGROK_3200とは」 |
| ngrok-setup | 担当認証と、CLI・SDK・API・IaCのどの面を使うかの切り分け | 呼び出しの例「ngrokの認証が通らない」 |
ほかに、参照資料としての ngrok-engine(エンドポイントの種類とTraffic Policy)と ngrok-surfaces(CLI・SDK・REST API・Terraform・Kubernetes Operatorでの適用方法)が一緒に入ります。この2つはタスクではなく参照用で、上のスキルが自動で読み込みます。直接呼ぶものではありません。
Claude Codeへの導入手順
Claude Codeでは、マーケットプレイスとして追加してからプラグインを入れます。
/plugin marketplace add ngrok/skills
/plugin install ngrok@ngrok/plugin marketplace add は owner/repo 形式のGitHubリポジトリを受け取る、Claude Code標準のコマンドです。/plugin install は プラグイン名@マーケットプレイス名 で指定します。セッション内で実行すると即インストールではなく、プラグインの詳細パネルが開き、確認とスコープの選択ができます。マーケットプレイスの仕組みはClaude Codeプラグイン化の移行手順に、プラグインの動かし方はskills-directoryでプラグインを動かす手順にあります。
スキルだけを入れたいなら、プラグインを使わない経路もあります。
npx skills add ngrok/skillsこの方法はAgent Skills対応のエージェント全般向けです。Claude Codeで /ngrok:expose-localhost のような名前空間付きコマンドを使いたいなら、プラグイン経由で入れます。
公開を頼むと何が起きるか
expose-localhost が動くと、まず ngrok config check で準備状況を確かめます。その後、実行前にまとめて質問します。聞かれるのはポート番号、ドメイン、アクセス制御(誰でも開けるか、ログイン必須か)、設定を保存するかどうかの4点です。ポートは package.json の --port、.env の PORT=、docker-compose.yml のポートマッピングから推測し、確認を取ってから進みます。
ドメインについては、ngrokのアカウントには無料の固定開発ドメイン(something.ngrok-free.dev の形)が付くことが多く、ngrok http PORT はそれを自動で使います。新しいアカウントでまだ開発ドメインがない場合は ERR_NGROK_15013 が出るので、ダッシュボードで取得してから再実行します。
認証なしで公開するときに走るのは、次のようなコマンドです。
ngrok http 3000 &
sleep 3
curl -s http://localhost:4040/api/tunnels | grep -o '"public_url":"[^"]*"' | head -1起動後、ローカルのエージェントAPI(4040番)から公開URLを取り出して返す流れです。終了するときは pkill ngrok で止めます。
ログインを付けて共有する
「Googleログインを付けて、自社メールの人だけに見せたい」と頼むと、Traffic Policyのファイルを作ってから --traffic-policy-file つきでngrokを起動します。ドメイン制限の例は次の形です。
on_http_request:
- actions:
- type: oauth
config:
provider: google
- expressions:
- "!actions.ngrok.oauth.identity.email.endsWith('@your-company.com')"
actions:
- type: deny
config:
status_code: 403スキルの指示には癖がいくつかあります。OAuthを頼まれたときは、既定でOAuthだけを付け、OWASPルールやレート制限は明示的に頼まれない限り足しません。OAuthの時点で未認証のアクセスは止まるためです。OAuthのアクション自体に allow を足す書き方もしません。メールの絞り込みは、上のように別ルールで deny を返す形です。
ログインを使わない相手(外部のレビュワーなど)には、basic-auth によるパスワード共有も用意されています。URLとパスワードは、すでに信頼している経路で渡す前提です。固定IPがある相手なら、共有物のない restrict-ips が代案になります。
開発サーバーの400に当たったとき
ローカルでは動くのに、ngrokのURL経由だと400になることがあります。Vite、Next.js、webpackなどの開発サーバーは、Hostヘッダーがlocalhostでない要求を拒否するためです。スキルが持つ対処表は次のとおりです。
| フレームワーク | 設定 |
|---|---|
| Vite | 設定server.allowedHosts |
| Next.js | 設定allowedDevOrigins |
| webpack-dev-server | 設定allowedHosts |
| Angular CLI | 設定--allowed-hosts |
フレームワーク側で許可できない場合は、エッジでHostヘッダーを書き換える方法が案内されています。共有URLを渡す前にここを直しておくと、「開けない」と言われる往復を減らせます。
webhookをローカルで受ける
receive-webhooks の中核は、2つのアクションを順に並べるTraffic Policyです。
on_http_request:
- actions:
- type: verify-webhook
config:
provider: stripe
secret: "${secrets.get('webhooks', 'stripe-signing-secret')}"
- type: forward-internal
config: { url: https://billing.internal }verify-webhook が署名を検証し、通った要求だけを次のアクションが配送します。署名が合わなければ403で止まります(enforce: false を指定しない限り、失敗側に倒れる設計です)。アプリ側に署名検証のコードを書かずに済むのが、このスキルの狙いです。
形は目的で2つに分かれます。
- ローカルでのテスト・デバッグ: エージェントのエンドポイントからローカルのポートへ直接転送します。最短で試せます
- 本番・非公開・規制環境・複数チーム共有のゲートウェイ: 常時稼働のクラウドエンドポイントで検証とルーティングを行い、内部エンドポイントに受け口を隠します。受け口を公共インターネットに出さずに済みます
プロバイダーごとの準備は共通で、署名シークレットをVaultに保存し、ポリシーから参照し、プロバイダーのwebhook設定にngrokのURLを書く、の3手です。パスで振り分ければ、/stripe と /github を1つのポリシーに同居させ、別々の内部サービスへ送れます。
動作確認は、プロバイダーのダッシュボードからテストイベントを送るか、署名ヘッダー付きの curl で行います。有効な署名なら上流に届き、無効なら403です。リクエストのヘッダーと本文は、エージェントのWebインスペクター(既定で http://localhost:4040)で見られます。
認証情報はClaude Codeに渡さない
このスキル集で目を引くのは、機能の説明より先に、秘密情報の扱いを細かく縛っている点です。
- auth token:
ngrok-setupは、tokenをチャットに貼らせるなと明記しています。ユーザー自身がngrok config add-authtoken <TOKEN>を実行するか、環境変数NGROK_AUTHTOKENを設定し、完了を告げてからClaudeがngrok config checkで確かめる流れです。tokenに触れるのはこの1手だけで、ほかのngrokコマンドはClaudeが実行します - webhookのsigning secret:
receive-webhooksは、whsec_...のような値をチャットで受け取らないよう指示しています。VaultへはダッシュボードかAPI(ngrok api secrets create)から本人が入れ、ポリシーには参照だけを書きます - 誤って貼られた場合: 値を繰り返さず、設定済みとだけ受け止め、ローテーションを勧める扱いです
APIキーとauth tokenは別物です。APIキーはアカウントを管理でき、auth tokenはエージェントのセッションを開始するだけという違いがあります。Terraform、Kubernetes Operator、REST APIはAPIキーで認証するため、認証エラーが出たら、どちらの資格情報の話かを先に切り分けます。
運用では、プロンプトに秘密を書かないことに加え、スキルが作る .ngrok/traffic-policy.yml や .ngrok/expose.sh にsigning secretの平文を書かせないこと(Vault参照にすること)が要になります。設定を保存する選択肢を選ぶと、この2ファイルがプロジェクトに残るので、コミット前に中身を見てください。
動かないときの切り分け
troubleshoot-ngrok は、エラーコードから原因へ進む作りです。よく出るのは次の2つです。
- ERR_NGROK_3200(エンドポイントがオフライン): そのURLを担当するエージェントが動いていません。起動していないか、別のURLで動いています。トンネルの持ち主のエージェントが止まったとき、訪問者に表示されることが多く、訪問者側で直すことはありません
- ERR_NGROK_8012(上流への接続拒否): エージェントは生きているのに、転送先のポートで何も待ち受けていません。ローカルサービスが、転送先と同じポートで動いているかを確認します
コードが出ない場合は症状から探します。エージェントが起動直後に終了するなら、認証か設定ファイルの構文を疑います。ポリシーが効かないなら、アクセスしているエンドポイントに添付されていない可能性があります。
使い分けの早見表
| やりたいこと | 向くスキル | 補足 |
|---|---|---|
| 作業中の画面を同僚に見せる | 向くスキルexpose-localhost | 補足開発サーバーのHost許可を先に設定 |
| 特定の人だけに見せる | 向くスキルexpose-localhost + OAuth | 補足メールまたはドメインで絞る |
| SSHやDBに外から入る | 向くスキルexpose-localhost(TCP) | 補足固定アドレスは有料プランの予約が必要 |
| webhookを手元で試す | 向くスキルreceive-webhooks | 補足シークレットはVault経由 |
| MCPサーバーを外のAIに試す | 向くスキルrun-mcp-gateway | 補足ngrokのAPIキーも必要 |
生TCPの公開には注意が要ります。ngrok tcp が返すアドレスは再起動のたびに変わり、固定したければ予約が必要で、予約したTCPアドレスは削除するまで課金が続きます。OAuthやOWASPはHTTP専用で、TCPでは on_tcp_connect フェーズの restrict-ips が通常の制限手段です。
まとめ
ngrokプラグインは、公開・認証・webhook・MCP・診断をスキルに切り分けた構成で、Claude Codeからは /ngrok:* で呼べます。ローカルを外に出す作業は設定ミスが事故に直結します。その分、認証情報を人の手に残し、Traffic Policyを宣言として残す設計は、Claude Codeに任せる範囲を決める手本になります。導入前に、公開するポートと許可する相手を自分で言葉にしておくと、質問への答えも速くなります。