はじめに
こんにちは。(株) 日立製作所の Lumada Data Science Lab. の神谷 明弘です。
Model Context Protocol (MCP)を活用したAIエージェントの実装が、プロトタイプから実用化段階へと進んでいます。AWS公式のMCPサーバーも充実し、本番環境での採用も現実的になってきました。
そんな中、LangChainベースのAIエージェントアプリケーションをAWS Fargate上で動かし、同一コンテナ内でAmazon Neptune MCP Serverを起動してグラフデータベースにアクセスしようとしたところ、権限エラーに遭遇しました。
この記事では、その原因と解決方法、そして学んだ教訓を共有します。
システム構成
Amazon Neptune MCP Serverは現時点(2026年3月)でstdioトランスポートのみ対応しています。StreamableHTTPやSSEトランスポートには対応していないため、同一コンテナ内でプロセスを起動する構成となります。
技術スタック
- 実行環境: AWS Fargate (ECS)
- アプリケーション: Python + LangChain
-
MCPサーバー: Amazon Neptune MCP Server (
awslabs.amazon-neptune-mcp-server) - トランスポート: stdio (標準入出力) ※現時点でstdio専用
- 認証: ECS Task Role (IAM)
発生した問題
Neptune MCP Serverを起動してクエリを実行しようとすると、以下のエラーが発生しました:
botocore.exceptions.NoCredentialsError: Unable to locate credentials
不可解な点
- Fargateタスクには適切なIAMロールが設定されている
- 同じコンテナ内の他のAWSサービス呼び出し(Amazon Bedrockなど)は正常に動作
- ローカル開発環境(AWS CLI設定あり)では問題なく動作
原因調査
Fargateの認証メカニズム
AWS Fargate上のコンテナは、ECSタスクロールの認証情報を以下の環境変数経由で取得します:
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI=/v2/credentials/<token>
この環境変数は、ECSコンテナメタデータエンドポイントへの相対URIを指し、boto3/botocoreはこれを使って一時認証情報を取得します。
普段AWS SDKを使っている分には自動的に認証が通るため意識することはありませんが、子プロセスに環境変数を渡す必要がある場合、この仕組みを理解していないとハマります。
MCP Python SDKの環境変数継承
問題の核心は、MCP Python SDKのstdioトランスポート実装が、環境変数を選択的にしか継承しないことでした。
同じコンテナ内でプロセスを起動するのだから、環境変数は当然引き継がれるものだと思い込んでいましたが、実際には明示的に渡さない限り継承されません。
AgnoのMCPドキュメント(StdioServerParameters)によると:
By default, the subprocess inherits only a minimal set of environment variables (PATH, USERNAME, etc.) from the parent process.
つまり、StdioServerParametersで明示的にenvパラメータを指定しない限り、AWS_CONTAINER_CREDENTIALS_RELATIVE_URIは子プロセスに渡されません。
boto3の認証チェーン
boto3は、PythonでAWSサービスを操作するための公式SDKです。認証情報を以下の順序で探します:
- 環境変数(
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY) - 共有認証情報ファイル(
~/.aws/credentials) -
ECSコンテナメタデータ(
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI経由) - EC2インスタンスメタデータ
Fargate環境では3番目の方法が使われますが、環境変数が継承されないため認証に失敗していました。
解決方法
StdioServerParametersのenvパラメータで、必要な環境変数を明示的に渡します:
from mcp import StdioServerParameters
import os
# Neptune MCP Serverの起動パラメータ
server_params = StdioServerParameters(
command="uvx",
args=["awslabs.amazon-neptune-mcp-server@latest"],
env={
# Fargate認証に必須
"AWS_CONTAINER_CREDENTIALS_RELATIVE_URI": os.getenv(
"AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
),
# リージョン設定
"AWS_REGION": os.getenv("AWS_REGION"),
"AWS_DEFAULT_REGION": os.getenv("AWS_DEFAULT_REGION"),
# Neptune接続情報
"NEPTUNE_ENDPOINT": os.getenv("NEPTUNE_ENDPOINT"),
# ログレベル
"FASTMCP_LOG_LEVEL": "INFO",
}
)
重要なAWS環境変数
Fargateおよびコンテナ環境で認証に使用される環境変数:
| 環境変数 | 用途 | 環境 |
|---|---|---|
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI |
コンテナメタデータエンドポイントへの相対URI | ECS Fargate, ECS EC2 |
AWS_CONTAINER_CREDENTIALS_FULL_URI |
コンテナメタデータエンドポイントの完全URL | EKS |
AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE |
認証トークンファイルのパス | EKS Pod Identity |
AWS_REGION |
AWSリージョン | 全環境 |
AWS_DEFAULT_REGION |
デフォルトリージョン(フォールバック) | 全環境 |
学んだ教訓
1. stdioトランスポートは環境変数を自動継承しない
MCPのstdioトランスポートは、セキュリティと予測可能性のため、環境変数を選択的にしか継承しません。AWS認証情報などの重要な環境変数は明示的に渡す必要があります。
2. Fargateの認証は環境変数ベース
Fargateでは、IAMロールの認証情報は環境変数経由でのみアクセス可能です。EC2インスタンスメタデータサービス(IMDS)は利用できません。
3. ローカルとクラウドの認証方式の違い
-
ローカル開発:
~/.aws/credentialsやAWS_PROFILEを使用 -
Fargate:
AWS_CONTAINER_CREDENTIALS_RELATIVE_URIを使用
この違いにより、ローカルでは動作するがFargateでは失敗するという状況が発生します。
4. 困ったときはソースコードを読む
ドキュメントだけでは解決できない場合、OSSならソースコードを直接確認するのが最も確実です。今回の問題も、MCP Python SDKのStdioServerParameters実装を見れば環境変数の継承ロジックが明確にわかります。「なぜこうなるのか」を理解するには、実装を読むのが近道です。
トラブルシューティング
認証エラーが発生する場合
- 環境変数の確認
import os
print("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI:",
os.getenv("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"))
print("AWS_REGION:", os.getenv("AWS_REGION"))
- タスクロールの権限確認
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"neptune-db:*"
],
"Resource": "arn:aws:neptune-db:region:account:cluster-id/*"
}
]
}
注意: 上記は動作確認用の例です。本番環境では最小権限の原則に従い、必要なアクション(
neptune-db:ReadDataViaQuery、neptune-db:WriteDataViaQueryなど)のみを許可してください。詳細はNeptune Databaseのセキュリティドキュメントを参照してください。
-
ネットワーク接続の確認
- FargateタスクがNeptuneのVPCにアクセスできるか
- セキュリティグループの設定は適切か
デバッグ用のログ出力
import logging
# MCPサーバーのログレベルを上げる
server_params = StdioServerParameters(
command="uvx",
args=["awslabs.amazon-neptune-mcp-server@latest"],
env={
"FASTMCP_LOG_LEVEL": "DEBUG", # DEBUGレベルに変更
# ... その他の環境変数
}
)
まとめ
AWS Fargate上でMCPサーバーを動かす際は、以下の点に注意が必要です:
-
環境変数の明示的な継承:
StdioServerParametersのenvパラメータで必要な環境変数を渡す -
Fargate認証の理解:
AWS_CONTAINER_CREDENTIALS_RELATIVE_URIがキーとなる - ローカルとの違い: 開発環境とクラウド環境で認証方式が異なることを認識
この問題は、MCPの仕様とAWSコンテナ環境の認証メカニズムの両方を理解していないと解決が難しいものでした。同様の問題に遭遇した方の参考になれば幸いです。
参考リンク
AWS公式ドキュメント
MCP関連
- Model Context Protocol 仕様 - Transports
- Agno MCP Documentation - Understanding Server Parameters
- Amazon Neptune MCP Server - GitHub