经过身份验证的MCP服务器
OAuth 2.1具有认证功能的远程Model Context Protocol (MCP)服务器
目次
概要
本项目包括:MCP规格化Client ID Metadata Documents使用方法实现认证功能的远程MCP服务器。
主要组件
- 授权代理: API Gateway + Lambda中描述的相应参数的值OAuth 2.1管理授权流
- 亚马逊干邑:用户身份验证和令牌提交
- MCP服务器:令牌验证和MCP提供工具
快速启动
第一次的人Getting Started指南来修改标记元素的显示属性。
# 1. 依存関係のインストール
npm install
# 2. ビルド
npm run build
# 3. デプロイ
npm run deploy
# 4. テストユーザーの作成
./scripts/create-test-user.sh test@example.com TestPassword123!
# 5. 動作確認
curl https:///.well-known/oauth-protected-resource详细步骤入门指南来修改标记元素的显示属性。
项目结构
.
├── lib/ # CDKインフラストラクチャコード
│ ├── cdk-app.ts # CDKアプリケーションエントリーポイント
│ └── authenticated-mcp-stack.ts # メインスタック定義
├── src/ # Lambda関数ソースコード
│ ├── auth-proxy/ # 認可プロキシ
│ │ ├── authorize.ts # 認可エンドポイント
│ │ ├── token.ts # トークンエンドポイント
│ │ ├── callback.ts # Cognitoコールバック
│ │ ├── consent.ts # 同意画面
│ │ ├── consent-action.ts # 同意アクション
│ │ └── auth-server-metadata.ts # Authorization Server Metadata
│ ├── mcp-server/ # MCPサーバー
│ │ ├── metadata.ts # Protected Resource Metadata
│ │ ├── mcp-handler.ts # MCPプロトコルハンドラー
│ │ └── jwt-middleware.ts # JWT検証ミドルウェア
│ ├── config/ # 設定管理
│ │ └── index.ts # 集約設定
│ ├── types/ # 共有型定義
│ │ └── index.ts
│ ├── utils/ # ユーティリティ
│ │ ├── errors.ts # エラークラス
│ │ ├── error-handler.ts # 共通エラーハンドリング
│ │ └── validation.ts # OAuth2バリデーション
│ └── __tests__/ # テスト
│ └── helpers/ # テストヘルパー
│ ├── mocks.ts # モックデータ
│ └── assertions.ts # アサーションヘルパー
├── docs/ # ドキュメント
│ ├── getting-started/ # 入門ガイド
│ ├── configuration/ # 設定ドキュメント
│ ├── api/ # APIリファレンス
│ ├── guides/ # 使用ガイド
│ └── architecture/ # アーキテクチャドキュメント
├── scripts/ # デプロイ・管理スクリプト
├── package.json
├── tsconfig.json
├── cdk.json
└── vitest.config.ts安装,安装
前提条件
- Node.js 18.x以上
- AWS CLI已配置
- AWS-CDK-CLI(
npm install -g aws-cdk)
安装
npm install构建
npm run build测试
npm test部署
快速启动
# 依存関係のインストール、ビルド、デプロイを一括実行
make all
# または個別に実行
make install
make build
make deploy首次部署
# デプロイスクリプトを使用
./scripts/deploy.sh
# またはnpmスクリプトを使用
npm run deploy
# またはMakefileを使用
make deploy部署后,将输出以下信息:
Outputs:
AuthenticatedMcpStack.UserPoolId = us-east-1_XXXXXXXXX
AuthenticatedMcpStack.UserPoolClientId = 1234567890abcdefghijklmnop
AuthenticatedMcpStack.UserPoolDomain = mcp-auth-123456789012
AuthenticatedMcpStack.CognitoManagedUIUrl = https://mcp-auth-123456789012.auth.us-east-1.amazoncognito.com
AuthenticatedMcpStack.AuthProxyApiUrl = https://abc123xyz.execute-api.us-east-1.amazonaws.com/prod/
AuthenticatedMcpStack.McpServerApiUrl = https://def456uvw.execute-api.us-east-1.amazonaws.com/prod/
AuthenticatedMcpStack.AuthorizeEndpoint = https://abc123xyz.execute-api.us-east-1.amazonaws.com/prod/authorize
AuthenticatedMcpStack.TokenEndpoint = https://abc123xyz.execute-api.us-east-1.amazonaws.com/prod/token
AuthenticatedMcpStack.AuthServerMetadataEndpoint = https://abc123xyz.execute-api.us-east-1.amazonaws.com/prod/.well-known/oauth-authorization-server
AuthenticatedMcpStack.CallbackEndpoint = https://abc123xyz.execute-api.us-east-1.amazonaws.com/prod/callback
AuthenticatedMcpStack.ConsentEndpoint = https://abc123xyz.execute-api.us-east-1.amazonaws.com/prod/consent
AuthenticatedMcpStack.ProtectedResourceMetadataEndpoint = https://def456uvw.execute-api.us-east-1.amazonaws.com/prod/.well-known/oauth-protected-resource
AuthenticatedMcpStack.McpEndpoint = https://def456uvw.execute-api.us-east-1.amazonaws.com/prod/mcp这些值MCP Client请用于设置。
检查堆栈输出
# スクリプトを使用
./scripts/get-outputs.sh
# またはnpmスクリプトを使用
npm run outputs
# またはMakefileを使用
make outputs更新堆栈
# 更新スクリプトを使用(変更の確認プロンプト付き)
./scripts/update.sh
# またはMakefileを使用
make update删除堆栈
# 削除スクリプトを使用
./scripts/destroy.sh
# またはMakefileを使用
make destroy创建测试用户
部署后,必须创建测试用户。
方法1:使用脚本
./scripts/create-test-user.sh
# 例:
./scripts/create-test-user.sh us-east-1_XXXXXXXXX test@example.com TestPassword123!
# またはMakefileを使用
make create-user USER_POOL_ID=us-east-1_XXXXXXXXX EMAIL=test@example.com PASSWORD=TestPassword123!方法2:AWS CLI直接使用
# ユーザーを作成
aws cognito-idp admin-create-user \
--user-pool-id \
--username \
--user-attributes Name=email,Value= Name=email_verified,Value=true \
--message-action SUPPRESS
# パスワードを設定
aws cognito-idp admin-set-user-password \
--user-pool-id \
--username \
--password
\
--permanent方法3:AWS Console使用
- AWS控制台→ 干邑→ 用户池
- 已创建User Pool列表框中,此格式对应于条目“无”
- “用户”タブ → “创建用户”
- 输入电子邮件地址和密码
- "Mark email address as verified" 查看项目中可用的所有族
- “创建用户”
Cognito确认设置
# スクリプトを使用
./scripts/verify-cognito-setup.sh
# またはMakefileを使用
make verify-cognito USER_POOL_ID=us-east-1_XXXXXXXXX已部署Cognito User Pool具有以下设置:
- 认证方式:电子邮件/用户名+密码
- OAuth 2.1心流:授权码授予(PKCE必須)
- 范围:
- openid -基本用户身份 - email -用户的电子邮件地址 - profile -用户配置文件信息
- 回调URL:
- http://localhost:3000/callback - https://localhost:3000/callback
- 管理UI: 有効
注意:在当前实施中为标准OAuth仅使用作用域。如果需要自定义作用域,请在部署后Cognito可以从控制台添加。
开発
目录结构
lib/: AWS CDK基础架构定义src/auth-proxy/: OAuth 2.1授权代理Lambda函数src/mcp-server/: MCP服务器Lambda函数src/config/:集约设定管理src/types/:共有型定义src/utils/:共享实用程序函数
- errors.ts:自定义错误类 - error-handler.ts:通用错误处理 - validation.ts: OAuth2参数验证
src/__tests__/helpers/:测试辅助对象
- mocks.ts:公用拖车数据 - assertions.ts:测试断言
测试策略
- 单元测试:Vitest使用
- 通用测试辅助对象:提供莫克数据和断言函数
- 基于属性的测试:验证正确性属性
- 集成测试:端到端流程验证
编码质量
- TypeScript严格模式
- 常见错误处理:
withErrorHandling包装 - 统一验证:OAuth2验证参数
- 测试范围:全面测试关键功能
CI/CD
此项目包括:GitHub Actions使用CI/CD包含管线。
工作流程
- 测试工作流程 (
.github/workflows/test.yml):拉式请求和main按分支运行测试 - 部署工作流 (
.github/workflows/deploy.yml): main通过向分支推送执行自动部署
安装,安装
- GitHub在动态输入提示中单击Settings > Secrets and variables > Actions 中设置:
- AWS_ROLE_ARN:用于部署IAM角色ARN - AWS_REGION:部署到AWS区域
- AWS IAM的OIDC配置供应商和角色(详细信息请参见
docs/DEPLOYMENT.md),模板名称将采用不同的格式
单击功能区上的部署指南来修改标记元素的显示属性。
可用命令
npm脚本
npm run build # TypeScriptをビルド
npm run test # テストを実行
npm run deploy # CDKスタックをデプロイ
npm run synth # CDKスタックをシンセサイズ
npm run diff # スタックの変更を表示
npm run destroy # スタックを削除
npm run bootstrap # CDKブートストラップを実行
npm run deploy:ci # CI用デプロイ(承認なし)
npm run outputs # スタック出力を表示发出命令
make help # 利用可能なコマンドを表示
make install # 依存関係をインストール
make build # TypeScriptをビルド
make test # テストを実行
make deploy # スタックをデプロイ
make update # スタックを更新
make destroy # スタックを削除
make outputs # スタック出力を表示
make create-user # テストユーザーを作成
make verify-cognito # Cognito設定を確認
make all # すべて実行MCP Client设定例
部署后MCP Client中描述的相应参数的值。
获取所需信息
部署后,可以通过以下命令获取端点信息:
./scripts/get-outputs.sh
# または
make outputsClaude Desktop设定例
~/Library/Application Support/Claude/claude_desktop_config.json (macOS) 或 %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"authenticated-mcp": {
"url": "https://YOUR_MCP_SERVER_ID.execute-api.us-east-1.amazonaws.com/prod/mcp",
"transport": {
"type": "http"
},
"auth": {
"type": "oauth2",
"authorizationUrl": "https://YOUR_AUTH_PROXY_ID.execute-api.us-east-1.amazonaws.com/prod/authorize",
"tokenUrl": "https://YOUR_AUTH_PROXY_ID.execute-api.us-east-1.amazonaws.com/prod/token",
"clientId": "https://your-domain.com/client-metadata.json",
"scopes": ["openid", "email", "profile"],
"pkce": true
}
}
}
}设置值说明
| 项目 | 说明 | 取得方法 |
|---|---|---|
url | MCP服务器端点 McpEndpoint的输出值 | |
authorizationUrl 批准端点 AuthorizeEndpoint的输出值 | ||
tokenUrl 令牌端点 TokenEndpoint的输出值 | ||
clientId | Client ID Metadata Document的,之URL | 必须自己主机 |
scopes 请求的作用域 ["openid", "email", "profile"] | ||
pkce | PKCE使用标志|始终true |
Client ID Metadata Documentの准备
MCP客户机HTTPS URL的Client ID Metadata Document中所述修改相应参数的值。
例: https://your-domain.com/client-metadata.json
{
"client_id": "https://your-domain.com/client-metadata.json",
"client_name": "My MCP Client",
"client_uri": "https://your-domain.com",
"logo_uri": "https://your-domain.com/logo.png",
"redirect_uris": [
"http://localhost:3000/callback",
"https://your-domain.com/callback"
],
"grant_types": ["authorization_code"],
"response_types": ["code"],
"token_endpoint_auth_method": "none",
"scope": "openid email profile"
}重要说明:
client_id将显示URL的总和redirect_uris在MCP客户机回调URL必须包含- HTTPS进行动态观察时的轴心点
http://localhost也可以)
简单测试设置
以开发、测试为目的GitHub Gist来修改标记元素的显示属性Client ID Metadata Document主机:
- GitHub Gist在中创建新文件
- 上述的JSON粘贴(
client_id的Gist的,之Raw URL),模板名称将采用不同的格式 - "Create public gist"来修改标记元素的显示属性
- "Raw"按钮,来查看主文件中将要发送的内容URL获得
- 那个URL的
clientId作为…使用
例:
https://gist.githubusercontent.com/username/gist-id/raw/client-metadata.json使用例
完整认证流程
以下MCP客户机MCP连接到服务器的完整验证流程示例。
1. Client ID Metadata Documentの准备
MCP客户机HTTPS URL的Client ID Metadata Document必须主机:
{
"client_id": "https://example.com/client.json",
"client_name": "My MCP Client",
"redirect_uris": [
"http://localhost:3000/callback"
],
"grant_types": ["authorization_code"],
"response_types": ["code"],
"token_endpoint_auth_method": "none"
}2. PKCE生成参数
// code_verifierの生成(ランダムな文字列)
const codeVerifier = generateRandomString(128);
// code_challengeの生成(SHA256ハッシュ、base64url エンコード)
const codeChallenge = base64url(sha256(codeVerifier));3.授权请求
将用户重定向至授权端点:
# 環境変数を設定(デプロイ後の出力から取得)
export AUTH_PROXY_URL="https://xxx.execute-api.us-east-1.amazonaws.com/prod"
export MCP_SERVER_URL="https://yyy.execute-api.us-east-1.amazonaws.com/prod"
# ブラウザで開く
open "${AUTH_PROXY_URL}/authorize?response_type=code&client_id=https://example.com/client.json&redirect_uri=http://localhost:3000/callback&code_challenge=${CODE_CHALLENGE}&code_challenge_method=S256&state=xyz123&scope=openid%20email%20profile&resource=${MCP_SERVER_URL}"4.用户身份验证
Cognito Managed UI中所述修改相应参数的值。
5.获取授权代码
认证成功后redirect_uri的明细栏样式中定义的设置
http://localhost:3000/callback?code=AUTH_CODE&state=xyz1236.交换令牌
将授权代码更换为访问令牌:
curl -X POST "${AUTH_PROXY_URL}/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=${AUTH_CODE}" \
-d "redirect_uri=http://localhost:3000/callback" \
-d "client_id=https://example.com/client.json" \
-d "code_verifier=${CODE_VERIFIER}"响应:
{
"access_token": "eyJhbGc...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "eyJjdH..."
}7. MCP访问服务器
使用获取的访问标记MCP访问服务器:
# Protected Resource Metadataの取得
curl "${MCP_SERVER_URL}/.well-known/oauth-protected-resource"
# ツールリストの取得
curl -X POST "${MCP_SERVER_URL}/mcp" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "tools/list",
"id": 1
}'
# ツールの実行(echoツール)
curl -X POST "${MCP_SERVER_URL}/mcp" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "echo",
"arguments": {
"message": "Hello, MCP!"
}
},
"id": 2
}'MCP Inspector使用测试
MCP检查员单击功能区上MCP这是一个可以视觉测试服务器行为的官方工具。
安装
npm install -g @modelcontextprotocol/inspector基本用法
1. MCP Inspector启动
mcp-inspector在浏览器中 http://localhost:5173 列表框中,此格式对应于条目“无”。
2.服务器连接设置
MCP Inspector在的设置画面中输入以下内容:
服务器URL:
https://YOUR_MCP_SERVER_ID.execute-api.us-east-1.amazonaws.com/prod/mcp运输类型:
HTTP列表框中,此格式对应于条目“无”
身份验证:
- 类型:
OAuth 2.0 - 授权URL:
https://YOUR_AUTH_PROXY_ID.execute-api.us-east-1.amazonaws.com/prod/authorize - 令牌URL:
https://YOUR_AUTH_PROXY_ID.execute-api.us-east-1.amazonaws.com/prod/token - 客户端ID:
https://your-domain.com/client-metadata.json - 范围:
openid email profile - PKCE:
Enabled
3.认证流程
- "Connect" 按钮关闭对话框
- 因为认证画面打开Cognito登录到
- 认证成功后,自动MCP Inspector列表框中,此格式对应于条目“无”
4.测试工具
连接后,可执行以下操作:
- Tools 标签:列出可用工具
- 执行:运行工具并检查响应
- Resources 标签:资源列表(如果已实现)
- Prompts 标签:提示列表(如果已实现)
故障排除
CORS 发生错误时
API Gateway的,之CORS请确认设置。在当前实施中Cors.ALL_ORIGINS中描述的场景,使用以下步骤创建明细表,以便在概念设计中分析体量的体积。
如果验证循环
- Client ID Metadata Document确认主机是否正确
redirect_uris的MCP Inspector回调URL(通常情况下http://localhost:5173/callback)来定义自定义外观- 浏览器缓存和Cookie清除
客户端ID元数据文档(MCP检查器用)
MCP Inspector使用时,如下所示Client ID Metadata Document请准备:
{
"client_id": "https://your-domain.com/mcp-inspector-client.json",
"client_name": "MCP Inspector",
"client_uri": "http://localhost:5173",
"redirect_uris": [
"http://localhost:5173/callback",
"http://localhost:5173/oauth/callback"
],
"grant_types": ["authorization_code"],
"response_types": ["code"],
"token_endpoint_auth_method": "none",
"scope": "openid email profile"
}相关视频
MCP Inspector的使用方法正式文档来修改标记元素的显示属性。
简单测试脚本
测试完整流程的简单脚本示例:
#!/bin/bash
# 環境変数の設定
export AUTH_PROXY_URL="https://xxx.execute-api.us-east-1.amazonaws.com/prod"
export MCP_SERVER_URL="https://yyy.execute-api.us-east-1.amazonaws.com/prod"
# 1. Protected Resource Metadataの確認
echo "=== Protected Resource Metadata ==="
curl -s "${MCP_SERVER_URL}/.well-known/oauth-protected-resource" | jq .
# 2. 認証なしでアクセス(401エラーを期待)
echo -e "\n=== Unauthenticated Request (should return 401) ==="
curl -s -w "\nHTTP Status: %{http_code}\n" "${MCP_SERVER_URL}/mcp" \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "method": "tools/list", "id": 1}'
# 3. 認可フローの開始(ブラウザで開く)
echo -e "\n=== Starting Authorization Flow ==="
echo "Opening browser for authentication..."
# PKCEパラメータは事前に生成しておく
open "${AUTH_PROXY_URL}/authorize?response_type=code&client_id=https://example.com/client.json&redirect_uri=http://localhost:3000/callback&code_challenge=YOUR_CODE_CHALLENGE&code_challenge_method=S256&state=xyz123&scope=mcp:tools&resource=${MCP_SERVER_URL}"
echo "After authentication, exchange the code for a token using:"
echo "curl -X POST \"${AUTH_PROXY_URL}/token\" \\"
echo " -H \"Content-Type: application/x-www-form-urlencoded\" \\"
echo " -d \"grant_type=authorization_code\" \\"
echo " -d \"code=YOUR_AUTH_CODE\" \\"
echo " -d \"redirect_uri=http://localhost:3000/callback\" \\"
echo " -d \"client_id=https://example.com/client.json\" \\"
echo " -d \"code_verifier=YOUR_CODE_VERIFIER\""环境变数
必须环境变数
部署后Lambda函数使用以下环境变量(CDK自动设置):
授权代理(/authorize,/token)
SESSION_TABLE_NAME: DynamoDB表名(PKCE会话数据用)COGNITO_DOMAIN: Cognito User Pool域前缀COGNITO_CLIENT_ID:Cognito用户池客户端IDCOGNITO_REGION: Cognito区域
MCPサーバー(/mcp,/.knowledge/oauth保护资源)
MCP_SERVER_URI: MCP服务器基础URIAUTH_PROXY_URI:基于授权代理URICOGNITO_USER_POOL_ID:Cognito用户池IDCOGNITO_REGION: Cognito区域SUPPORTED_SCOPES:支持OAuth作用域(逗号分隔)
确认环境变量
部署后,将自动设置环境变量,但如果要确认:
# Lambda関数の環境変数を確認
aws lambda get-function-configuration \
--function-name AuthenticatedMcpStack-AuthorizeFunction-XXXXX \
--query 'Environment.Variables'了解更多信息 首选项文档 来修改标记元素的显示属性。
故障排除
常见问题
1.部署错误:“CDK bootstrap required”
# CDKブートストラップを実行
cdk bootstrap aws://ACCOUNT_ID/REGION2.授权错误:“client_id mismatch”
Client ID Metadata Document中的client_id将条目添加到文档注册表client_id URL中描述的相应参数的值。
3.标记错误:“invalid_grant”
PKCE验证失败。code_verifier已正确用于授权请求code_challenge中描述的相应参数的值。
4. 401エラー:“令牌无效或已过期”
访问标记过期或无效。请从令牌端点获取新令牌。
检查日志
# Lambda関数のログを確認
aws logs tail /aws/lambda/AuthenticatedMcpStack-AuthorizeFunction-XXXXX --follow
# 特定の時間範囲のログ
aws logs filter-log-events \
--log-group-name /aws/lambda/AuthenticatedMcpStack-McpHandlerFunction-XXXXX \
--start-time $(date -u -d '1 hour ago' +%s)000DynamoDB确认会话
# セッションテーブルの内容を確認
aws dynamodb scan --table-name mcp-auth-sessions
# 特定のセッションを削除
aws dynamodb delete-item \
--table-name mcp-auth-sessions \
--key '{"sessionId": {"S": "SESSION_ID"}}'详细的故障排除 快速参考 来修改标记元素的显示属性。
文档
前言
- 入门指南 -第一个安装指南
主要文档
配置文档
API文档
基础架构
- 基础架构 - AWS CDK堆栈详细信息
安全注意事项
OAuth 2.1最佳实践
- PKCE必须:在所有授权代码流中PKCE使用
- HTTPS必须: Client ID Metadata DocumentsはHTTPS経由で提供
- redirect_uri検证:精确redirect_uri验证防止授权代码监听
- 会话TTL:会话10分钟过期
- JWT検证:所有访问令牌Cognito的,之JWKS验证
AWS 安全性
- IAM最小権限: Lambda函数仅具有所需的最低权限
- VPC分离:根据需要Lambda打开VPC可在中放置
- 暗号化: DynamoDB保存时加密表
- CloudWatch日志:记录所有请求
貢献
欢迎拉式请求。在大的变更的情况下,首先issue中所述修改相应参数的值。
文档
详细的文档docs/在目录中:
入门指南
配置部署
认证・认可
API 引用
実装详细
许可证
麻省理工学院
