blog-zero-secrets-mcp

blog-zero-secrets-mcp

Demonstrates deploying an MCP server on AgentCore in standalone or gateway mode, using Cognito public client with PKCE for zero-secret user authentication.

Category
访问服务器

README

AgentCore + Cognito Public Client MCP PoC

End-to-end proof of concept demonstrating two deployment modes for an MCP server on AgentCore:

  1. Standalone — Runtime with Cognito JWT auth directly (no gateway)
  2. Gateway — Runtime behind an AgentCore Gateway with Cognito PKCE inbound auth and IAM outbound auth

Both modes use a public Cognito client (no client_secret) with PKCE for user authentication.

Architecture

Mode A: Standalone (Runtime with direct JWT auth)

Claude Code / Kiro
    │ PKCE → Cognito Hosted UI → browser
    │ Bearer JWT
    ▼
AgentCore Runtime (CUSTOM_JWT validates token)
    │
    ▼
MCP Server (FastMCP, Python)

Mode B: Gateway (recommended)

Claude Code / Kiro
    │ PKCE → Cognito Hosted UI → browser
    │ Bearer JWT
    ▼
AgentCore Gateway (CUSTOM_JWT validates token)
    │ SigV4 (gateway IAM role)
    ▼
AgentCore Runtime (AWS_IAM auth)
    │
    ▼
MCP Server (FastMCP, Python)

The Gateway mode provides:

  • Centralized authentication (gateway handles all JWT validation)
  • Tool discovery and semantic search across multiple targets
  • Protocol-level MCP routing
  • Separation of concerns (runtime doesn't need to know about user auth)

Project Structure

.
├── server/
│   ├── cognitopocmcp/              # Runtime deployed via agentcore CLI
│   │   ├── app/cognito_poc_mcp/
│   │   │   └── main.py            # FastMCP server with sample tools
│   │   └── agentcore/             # agentcore CLI config
│   ├── mcp_server.py              # MCP server source (standalone mode)
│   └── requirements.txt
├── src/
│   ├── config.mjs                 # Shared config (project name, region, helpers)
│   ├── auth.mjs                   # PKCE auth module (no secrets!)
│   ├── mcp-server.mjs             # Stdio MCP server (proxy mode)
│   └── test-auth.mjs              # Standalone auth flow test
├── scripts/
│   ├── setup-cognito.mjs          # Creates Cognito pool + public client + user
│   ├── deploy.sh                  # Deploys runtime (standalone mode, with JWT auth)
│   ├── deploy-infrastructure.mjs  # Creates gateway + IAM role + target (gateway mode)
│   ├── test-gateway.mjs           # Tests gateway end-to-end
│   ├── test-deployed.mjs          # Tests standalone runtime end-to-end
│   └── teardown-cognito.mjs       # Deletes all infrastructure
├── .env                           # Generated by setup (Cognito config)
├── .mcp.json                      # Generated by deploy-infra (gateway URL + OAuth)
├── claude-mcp-config.json         # Same as .mcp.json (for copying to Claude/Kiro)
└── package.json

Prerequisites

# AWS CLI + credentials configured
aws sts get-caller-identity

# Node.js 20+
node --version

# AgentCore CLI
npm install -g @aws/agentcore

# Python 3.10+ (for the MCP server)
python3 --version

Quick Start: Gateway Mode (recommended)

Step 1: Install dependencies

npm install

Step 2: Create Cognito infrastructure

npm run setup

Creates a Cognito User Pool with a public app client (no secret), a hosted UI domain, and a test user (testuser / TestPass123!). Config is saved to .env.

Step 3: Deploy the runtime

npm run deploy-runtime

Deploys the MCP server to AgentCore Runtime using the agentcore CLI. The runtime uses default IAM auth (the gateway will authenticate users).

Step 4: Deploy the gateway

npm run deploy-infra

Creates:

  • An IAM role for the gateway (with permission to invoke the runtime)
  • An AgentCore Gateway with CUSTOM_JWT inbound auth (Cognito PKCE)
  • A gateway target pointing at the runtime via GATEWAY_IAM_ROLE (SigV4)

Updates .mcp.json and claude-mcp-config.json with the gateway URL.

Step 5: Test

npm run test-gateway

Authenticates via Cognito (non-interactive using test user), then:

  • Verifies unauthenticated requests are rejected (401)
  • Initializes MCP session
  • Lists discovered tools
  • Calls tools (greet_user, add_numbers, get_server_info)

Step 6: Connect Claude Code / Kiro

Copy the generated config:

# For Kiro — .mcp.json is already in the project root
# For Claude Code
cp claude-mcp-config.json ~/.claude/mcp.json

The config looks like:

{
  "mcpServers": {
    "cognito-poc": {
      "type": "http",
      "url": "https://<gateway-id>.gateway.bedrock-agentcore.<region>.amazonaws.com/mcp",
      "oauth": {
        "clientId": "<public-client-id>",
        "callbackPort": 8976
      }
    }
  }
}

On first tool invocation, Claude/Kiro opens your browser for Cognito login. After that, tokens are cached and refreshed automatically.

Quick Start: Standalone Mode

If you don't need a gateway and want the runtime to handle JWT auth directly:

npm run setup         # Create Cognito pool
npm run deploy        # Deploy runtime with CUSTOM_JWT auth
npm run test-deployed # Test via PKCE (opens browser)

npm Scripts

Script Description
npm run setup Create Cognito User Pool + public client + test user
npm run deploy-runtime Deploy MCP runtime via agentcore CLI (IAM auth, for gateway)
npm run deploy-infra Create gateway + IAM role + target via Control Plane API
npm run deploy Deploy runtime with direct JWT auth (standalone, no gateway)
npm run test-gateway Test gateway end-to-end (non-interactive)
npm run test-gateway -- --pkce Test gateway with browser-based PKCE login
npm run test-deployed Test standalone runtime via PKCE
npm run test-auth Test PKCE auth flow only (opens browser)
npm run test-local Run MCP server locally for development
npm run teardown Delete all infrastructure (gateway, IAM role, Cognito pools)

MCP Tools Available

The sample MCP server exposes:

Tool Description
add_numbers Add two numbers together
multiply_numbers Multiply two numbers together
greet_user Greet a user by name
get_server_info Return deployment and version info
analyze_text Analyze text and return basic statistics

When accessed through the gateway, tool names are prefixed with the target name: mcp-runtime___add_numbers.

Cleanup

npm run teardown

This deletes:

  • AgentCore Gateway (targets + gateway)
  • Gateway IAM role
  • Cognito User Pool(s)
  • Local files (.env, .mcp.json, claude-mcp-config.json)

The AgentCore Runtime is NOT deleted (managed separately by agentcore CLI). To remove it:

cd server/cognitopocmcp && agentcore destroy

Key Concepts

Zero-secrets authentication

  • Cognito public client: GenerateSecret: false — no client secret exists
  • PKCE (code_challenge + code_verifier) proves the requester without a shared secret
  • Only the client_id is stored locally (a public identifier, not a credential)
  • Tokens are in-memory with 1-hour expiry + auto-refresh

Gateway outbound auth

The gateway authenticates to the runtime using its own IAM role (SigV4). This avoids the complexity of OAuth machine-to-machine flows between the gateway and runtime. The IAM role has bedrock-agentcore:* permission scoped to the runtime ARN.

Portability

All environment-specific values are derived at runtime:

  • AWS Account ID: resolved via STS.GetCallerIdentity
  • Gateway URL: read from .mcp.json (generated by deploy-infra)
  • Runtime ARN: read from agentcore deployed state
  • Project constants: centralized in src/config.mjs

To deploy in a different account/region, just configure AWS credentials and re-run the setup steps.

Security

See CONTRIBUTING for information on reporting security issues.

License

This library is licensed under the MIT-0 License. See the LICENSE file.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选