はじめに
今更なんですが、MCPサーバ作ってみたいな!って思い、以下のページを元にMCPサーバーを作ってみたという記事です。
とある勘違いで、認可サーバをCognitoからAuth0に変えています。(詳細は後述します。)
MCPの中身をきちんと作ってから記事書きたかったのですが、今回は認証周りのみのお話です。
やってみる!
リモートMCPサーバは上記の公式ページに書いてあることだけで、簡単にできてしまうので、今回はAuth0周りについて書いていきます!
Auth0でAPI(Resource Server)を登録
最初に Auth0側の設定です。
今回はBedrock AgentCore Runtime上でMCPサーバを動作するので、https://bedrock-agentcore.us-west-2.amazonaws.com/
(オレゴン)を認可サーバとして登録しておきます。
この時、JSON Web Token(JWT)プロファイル
をAuth0
からRFC9038
に設定しておきます。
Auth0のままだとどうなるの?
ここでプロファイルをAuth0
のままだと、以下のエラーが出ます。
OAuth authorization failed: Claim 'client_id' value mismatch with configuration.
どうやら、Auth0の場合、アクセストークンにclient_id
含まれないことが原因で、Bedrock Agent Core Runtime(の裏で動いているサービス)が対応していないみたいです。
アプリケーションの作成
次にアプリケーションを作成していきます。
今回は、人による認証はないので、マンツーマンアプリケーション
を選択します。
次に先ほど作ったAPIを指定しておきます。
(パーミションの設定が入ってますが、これなくても動きました。)
作成できたら、クライアントIDと、OpenID Configurationのエンドポイントをメモしておきます。
エンドポイントは設定
-> 詳細設定
-> エンドポイント
にあるOpenID Configuration
確認可能です。
https://dev-ryrknqlogokmrtzf.us.auth0.com/.well-known/openid-configuration
みたいなURLです。
Agent Core RuntimeにOAuthの設定を入れる
以下のコマンドで、OAuthの設定を変更していきます。
agentcore configure -e mcp_server.py --protocol MCP --region us-west-2
対話式の設定の最後にAuthorization Configuration
のところがあるのでここで設定を入れてます。
リソースサーバ名は今回の場合はhttps://bedrock-agentcore.us-west-2.amazonaws.com/
です。
🔐 Authorization Configuration
By default, Bedrock AgentCore uses IAM authorization.
Configure OAuth authorizer instead? (yes/no) [yes]: yes
📋 OAuth Configuration
Enter OAuth discovery URL : [OpenID Configurationエンドポイント]
Enter allowed OAuth client IDs (comma-separated) : [クライアントID]
Enter allowed OAuth audience (comma-separated) : [リソースサーバ名]
✓ OAuth authorizer configuration created
設定後、入力内容がbedrock_agentcore.yaml
に反映されます。
(ので、変更がある場合はここを直接変更しても問題ないです。)
default_agent: mcp_server
agents:
mcp_server:
name: mcp_server
entrypoint: mcp_server.py
platform: linux/arm64
container_runtime: none
aws:
execution_role: null
execution_role_auto_create: true
account: '123456789012'
region: us-west-2
ecr_repository: null
ecr_auto_create: true
network_configuration:
network_mode: PUBLIC
protocol_configuration:
server_protocol: MCP
observability:
enabled: true
bedrock_agentcore:
agent_id: mcp_server-y2iy3YFsSN
agent_arn: arn:aws:bedrock-agentcore:us-west-2:123456789012:runtime/mcp_server-y2iy3YFsSN
agent_session_id: null
codebuild:
project_name: null
execution_role: null
source_bucket: null
authorizer_configuration:
customJWTAuthorizer:
discoveryUrl: https://dev-xxxxxx.us.auth0.com/.well-known/openid-configuration
allowedClients:
- xxxxxxxxxxxxxxxxxxxx
allowedAudience:
- https://bedrock-agentcore.us-west-2.amazonaws.com/
oauth_configuration: null
設定入れたら、agentcore launch
でデプロイしておきます。
動作確認
MCPエンドポイントの確認
設定できたので、動作確認していきます。
MCPサーバのエンドポイントですが、以下の通りです。
encoded_arn
はRuntimeのArnarn:aws:bedrock-agentcore:us-west-2:123456789012:runtime/mcp_server-y2iy3YFsSN
をURLエンコードしたものです。
(エンドポイントにアカウントIDが入ってしまいますね…)
https://bedrock-agentcore.us-west-2.amazonaws.com/runtimes/{encoded_arn}/invocations?qualifier=DEFAULT
アクセストークンの取得
Auth0では、UI上から簡単にアクセストークンを取得できます。
MCP Insepctorで確認
今回はMCP Insepctorで動作確認してみます。
以下コマンドでインストールするだけです。
npx @modelcontextprotocol/inspector
以下それぞれ設定し、接続状態がConnected
になり、History
にinitialize
となればOKです!
項目 | 設定内容 |
---|---|
Transport Type | Streamable HTTP |
URL | MCPエンドポイント |
Bearer Token | アクセストークン |
ツールもきちんと使えますね!
Claude Codeで動かしてみる。
ここまでできたので、Claude Codeで動作確認してみます。
こんな感じで、アクセストークンを指定して、MCP追加します。
claude mcp add --transport http \
bedrockAgentRuntime-MCP 'https://bedrock-agentcore.us-west-2.amazonaws.com/runtimes/arn%3Aaws%3Abedrock-agentcore%3Aus-west-2%3A123456789012%3Aruntime%2Fmcp_server-y2iy3YFsSN/invocations?qualifier=DEFAULT' \
-H 'Authorization: Bearer [アクセストークン]'
で、足し算してみると・・・動きます!
なお、削除はこちらから。
claude mcp remove bedrockAgentRuntime-MCP
動くけど、これでいい?
ここからは、私の勘違いが大いにある可能性もあります!
私がしたいこと。
今のMCPの追加方法だと認可に有効期限のあるアクセストークンを指定するため、デフォルトの場合、1時間経つとMCPが使えなくなってしまいます。
ちょっと不便ですよね。
ClaudeのリモートMCP追加みたいにしてみたい!
有効期限が短いアクセストークンを使わず、認可ができないのかな?と調べてると、ClaudeのリモートMCPを追加する方法を見つけました。
クライアントシークレットを使う方式だと、有効期限がないので、これを目指してみようと思いました。
が、これを使ったMCPサーバの追加は、Proプランでは対応しておらず、動作確認できませんでした。
Claudeはどうやって、認可サーバを見つけるの?
動作確認はできませんでしたが、そもそもどうやってクライアントIDとクライアントシークレットだけで認可ができるんだろう?どこに認可をもらうんだろう?という疑問が湧きました。
ヒントはここにありました。
As of July, users are also able to specify a custom client ID and client secret when configuring a server that doesn’t support DCR.
この方法は7月にできたのね。
で、どうやるんだ?
Claude’s OAuth callback URL is https://claude.ai/api/mcp/auth_callback and its OAuth client name is Claude.
This callback URL may change to https://claude.com/api/mcp/auth_callback in the future – if you choose to allowlist MCP client callback URLs, please allowlist this callback URL as well to ensure that your server continues to work with Claude.
Claude supports token expiry and refresh – servers should support this functionality in order to provide the best experience for users.
/.well-known/oauth-authorization-server
みたいなお決まりのエンドポイントをMCPサーバ側に用意しつつ、ClaudeのOAuthコールバックURLはhttps://claude.ai/api/mcp/auth_callback
にしろって感じかな。
よし、これでやろう!
AgentCore Runtimeでどう実施するんだ?
OAuthに必要なエンドポイントを作ろうと思うんだけど、私が調べた感じ、新しいエンドポイントを追加する方法がないみたいでした。
普通にエンドポイントにGETしても、以下のようなエラーになってしまい、そもそもバックエンドまでリクエストが届かない感じ。
< HTTP/2 404
< date: Thu, 21 Aug 2025 10:51:08 GMT
< content-length: 29
< x-amzn-requestid: 644553d2-a3e0-4447-8c2e-44200ba2bf7a
<
<UnknownOperationException/>
たぶん未対応だと思う。
また色々調べるうちに以下の記事がありました。
A runtime can only support either IAM SigV4 or JWT Bearer Token based inbound auth.
やっぱりインバウンドの認可は、IAM認証か、ベアラトークンしか対応してなさそう。
そうなると、DCR(Dynamic Client Registration)も対応してないですね。
Auth0なんで使うん?
上記調査で迷走しているときに、CognitoはDCRに対応していないので、 Auth0を使えばいいんだなと勘違いしたところが利用の始まりでした。
結果、DCRも対応していないので、 Auth0を使う理由がなくなってしまいました。
非推奨: Auth0はアクセストークンの期限が最大30日。
ただ、Auth0を使うメリットも残ってます。
CognitoとAuth0を比較すると、アクセストークンの有効期限の最大値が違いました!
サービス | 最大有効期限 |
---|---|
Cognito | 1日(86,400秒) |
Auth0 | 30日(2,592,000秒) |
良い方法ではないですが、これで再認可を1ヶ月に1回まで抑えることができます!
まとめ
ということで、ちょっと今回は闇に葬るか悩んだ検証ですが、少しは役に立つかなと思い、記事書いてみました!
勘違いしてそうなところ多いと思うので、ぜひご指摘お願いします!!