Claude Platform on AWS の Web Fetch / MCP Connector の egress IP を確認してみた

Claude Platform on AWS の Web Fetch / MCP Connector の egress IP を確認してみた

Claude Platform on AWS の Web Fetch / MCP Connector が外部サイトへアクセスする際の egress IP を、Lambda関数URLのアクセスログで観測。通信の出口はAWS内なのか、それとも外なのかを確認しました
2026.05.14

Claude Platform on AWS の Web Fetch や MCP Connector が外部サイトへアクセスする際、リクエストはどこから発信されるのか? Lambda関数URLのアクセスログから egress IP を観測し、AWS ネットワーク内に閉じているのかを実測で確認しました。

先行記事はこちら:

https://dev.classmethod.jp/articles/claude-platform-on-aws-ga-setup/

https://dev.classmethod.jp/articles/claude-platform-on-aws-bedrock-differences/

TL;DR

観測結果(2026年5月13日時点):

機能 egress IP 登録組織 Origin ASN
Web Fetch 34.162.xxx.xxx Google LLC AS396982 GOOGLE-CLOUD-PLATFORM
MCP Connector 160.79.106.xxx Anthropic, PBC AS396982 GOOGLE-CLOUD-PLATFORM
  • 両者とも GeoIP 上は Columbus, Ohio(US)
  • inference_geo: us / global による egress IP の差異は観測されなかった

背景

先行記事では Bedrock との判断フローチャートを示し、「データレジデンシー要件が厳格なら Bedrock」としました。Bedrock は AWS サービスとしてのデータ境界や管理モデルが明確です。

一方、Claude Platform on AWS の Web Fetch / MCP Connector については、外部通信時の egress がどこになるのか公式ドキュメントに明記がありません。本記事ではこれを実測で確認します。

inference_geo: Anthropic API のパラメータで、推論処理の地理的なルーティングに関する指定。2026年5月時点で "us" と "global" のみ選択可能。

検証方法

us-east-1 の自社検証アカウントに Lambda関数URL を2つ作成し、Claude Platform on AWS の Web Fetch / MCP Connector から呼び出しました。

  • echo-headers: requestContext.http.sourceIp、ヘッダー、タイムスタンプを返却
  • mcp-echo-server: MCP の initialize / tools/list / tools/call に応答する最小実装

本記事でいう egress IP は、Lambda 関数 URL のイベントに含まれる requestContext.http.sourceIp として観測された IP を指します。

検証パターン: 3モデル(Opus 4.7 = claude-opus-4-7, Sonnet 4.6 = claude-sonnet-4-6, Opus 4.6 = claude-opus-4-6)× 2 geo(us, global)= 6パターン。いずれも Web Fetch / MCP Connector をサポートしているモデルです。

Lambda関数: echo-headers
import json, logging, time

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def handler(event, context):
    body = {
        "source_ip": event.get("requestContext", {}).get("http", {}).get("sourceIp"),
        "headers": event.get("headers", {}),
        "timestamp_ms": int(time.time() * 1000)
    }
    logger.info(json.dumps(body))
    return {
        "statusCode": 200,
        "headers": {"content-type": "application/json", "cache-control": "no-store, max-age=0"},
        "body": json.dumps(body, indent=2)
    }
Lambda関数: mcp-echo-server
import json, logging, time

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def handler(event, context):
    source_ip = event.get("requestContext", {}).get("http", {}).get("sourceIp")
    headers = event.get("headers", {})
    ts_ms = int(time.time() * 1000)

    logger.info(json.dumps({"source_ip": source_ip, "headers": headers, "timestamp_ms": ts_ms}))

    if event.get("requestContext", {}).get("http", {}).get("method") != "POST":
        return {"statusCode": 405, "body": "Method not allowed"}

    req = json.loads(event.get("body", "{}"))
    req_id = req.get("id")
    method = req.get("method", "")

    if method == "initialize":
        result = {"protocolVersion": "2025-11-25", "capabilities": {"tools": {}},
                  "serverInfo": {"name": "echo-mcp", "version": "1.0.0"}}
    elif method == "tools/list":
        result = {"tools": [{"name": "get_server_info", "description": "Returns caller IP and headers",
                             "inputSchema": {"type": "object", "properties": {}, "required": []}}]}
    elif method == "tools/call":
        result = {"content": [{"type": "text", "text": json.dumps(
            {"caller_ip": source_ip, "caller_headers": headers, "timestamp_ms": ts_ms})}]}
    elif method.startswith("notifications/"):
        return {"statusCode": 202, "body": ""}
    else:
        return {"statusCode": 200, "headers": {"content-type": "application/json"},
                "body": json.dumps({"jsonrpc": "2.0", "id": req_id,
                                    "error": {"code": -32601, "message": f"Unknown: {method}"}})}

    return {
        "statusCode": 200,
        "headers": {"content-type": "application/json", "cache-control": "no-store, max-age=0"},
        "body": json.dumps({"jsonrpc": "2.0", "id": req_id, "result": result})
    }

Web Fetch の観測結果

リクエスト例

curl -X POST "https://aws-external-anthropic.us-east-1.api.aws/v1/messages" \
  -H "x-api-key: ${ANTHROPIC_AWS_API_KEY}" \
  -H "anthropic-version: 2023-06-01" \
  -H "anthropic-workspace-id: ${ANTHROPIC_WORKSPACE_ID}" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-sonnet-4-6",
    "max_tokens": 1024,
    "inference_geo": "us",
    "tools": [{"type": "web_fetch_20250910", "name": "web_fetch", "max_uses": 1}],
    "messages": [{"role": "user", "content": "Fetch https://xxxxx.lambda-url.us-east-1.on.aws/?t=<timestamp>"}]
  }'

6パターンの結果

モデル inference_geo egress IP
claude-opus-4-7 us 34.162.xxx.xxx
claude-opus-4-7 global 34.162.xxx.xxx
claude-sonnet-4-6 us 34.162.xxx.xxx
claude-sonnet-4-6 global 34.162.xxx.xxx
claude-opus-4-6 us 34.162.xxx.xxx
claude-opus-4-6 global 34.162.xxx.xxx

モデルや inference_geo を変えても egress IP は同一でした。

IP の詳細:

項目 値
PTR逆引き *.bc.googleusercontent.com
whois OrgName Google LLC(NetName: GOOGL-2)
Origin ASN AS396982 GOOGLE-CLOUD-PLATFORM
GeoIP Columbus, Ohio, US
User-Agent Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Claude-User/1.0; +claude-user@anthropic.com)

なお、同一 URL ではキャッシュと思われる挙動が見られたため、クエリパラメータにタイムスタンプを付与して回避しました。

MCP Connector の観測結果

リクエスト例

curl -X POST "https://aws-external-anthropic.us-east-1.api.aws/v1/messages" \
  -H "x-api-key: ${ANTHROPIC_AWS_API_KEY}" \
  -H "anthropic-version: 2023-06-01" \
  -H "anthropic-beta: mcp-client-2025-11-20" \
  -H "anthropic-workspace-id: ${ANTHROPIC_WORKSPACE_ID}" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-sonnet-4-6",
    "max_tokens": 1024,
    "inference_geo": "us",
    "mcp_servers": [{"type": "url", "url": "https://xxxxx.lambda-url.us-east-1.on.aws/", "name": "echo-mcp"}],
    "tools": [{"type": "mcp_toolset", "mcp_server_name": "echo-mcp"}],
    "messages": [{"role": "user", "content": "Call get_server_info"}]
  }'

6パターンの結果

モデル inference_geo egress IP
claude-opus-4-7 us 160.79.106.xxx
claude-opus-4-7 global 160.79.106.xxx
claude-sonnet-4-6 us 160.79.106.xxx
claude-sonnet-4-6 global 160.79.106.xxx
claude-opus-4-6 us 160.79.106.xxx
claude-opus-4-6 global 160.79.106.xxx

Web Fetch と異なり、リクエストごとに末尾オクテットが変動しました。ただし、すべて 160.79.106.0/24 内に収まっています。

IP の詳細:

項目 値
PTR逆引き レコードなし
whois OrgName Anthropic, PBC(NetName: AP-2440)
Origin ASN AS396982 GOOGLE-CLOUD-PLATFORM
GeoIP Columbus, Ohio, US
User-Agent Claude-User
Accept application/json, text/event-stream
MCP Client Info Anthropic/API 1.0.0(initialize の params.clientInfo)

比較表

参考として、ローカル実行型の Claude Code から同じ URL にアクセスした場合も確認しました。

項目 Web Fetch MCP Connector Claude Code(参考)
egress IP 34.162.xxx.xxx 160.79.106.xxx 利用端末の出口IP
登録組織 Google LLC Anthropic, PBC ISP等
Origin ASN AS396982 AS396982 —
User-Agent Claude-User/1.0 Claude-User Claude-User (claude-code/2.1.139)

まとめ

Claude Platform on AWS の Web Fetch / MCP Connector が外部へアクセスする際の egress IP は、whois / PTR / Origin ASN の確認結果から、AWS ではなく Google LLC / Anthropic, PBC に関連する IP レンジとして観測されました。ただし、今回の検証は推論処理そのものの実行基盤や物理的な配置を直接証明するものではありません。

egress IP は今後サービス側で変わる可能性があります。データレジデンシー要件が厳格な場合は、AWS サービスとしてのデータ境界や管理モデルが明確な Amazon Bedrock を優先的に検討するのがよさそうです。一方で、Web Fetch や MCP Connector など Claude Platform の機能を重視する場合は、今回の egress の挙動も踏まえて Claude Platform on AWS を検討するとよいでしょう。

参考リンク


Claudeならクラスメソッドにお任せください

クラスメソッドは、Anthropic社とリセラー契約を締結しています。各種製品ガイドから、業種別の活用法、フェーズごとのお悩み解決などサービス支援ページにまとめております。まずはご覧いただき、お気軽にご相談ください。

サービス詳細を見る

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事