Skip to main content
Glama
pcolazurdo

blog-zero-secrets-mcp

by pcolazurdo

AgentCore + Cognito 공용 클라이언트 MCP PoC

AgentCore에서 MCP 서버의 두 가지 배포 모드를 보여주는 엔드투엔드 개념 증명:

  1. 독립형 — 게이트웨이 없이 Cognito JWT 인증을 직접 사용하는 런타임

  2. 게이트웨이 — Cognito PKCE 인바운드 인증 및 IAM 아웃바운드 인증을 사용하는 AgentCore 게이트웨이 뒤의 런타임

두 모드 모두 사용자 인증을 위해 PKCE와 함께 공용 Cognito 클라이언트(client_secret 없음)를 사용합니다.

아키텍처

모드 A: 독립형 (직접 JWT 인증을 사용하는 런타임)

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

모드 B: 게이트웨이 (권장)

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)

게이트웨이 모드는 다음을 제공합니다:

  • 중앙 집중식 인증 (게이트웨이가 모든 JWT 검증 처리)

  • 여러 대상에 걸친 도구 검색 및 의미 검색

  • 프로토콜 수준 MCP 라우팅

  • 관심사 분리 (런타임은 사용자 인증을 알 필요 없음)

Related MCP server: local-kms-mcp-server

프로젝트 구조

.
├── 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

사전 요구 사항

# 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

빠른 시작: 게이트웨이 모드 (권장)

1단계: 종속성 설치

npm install

2단계: Cognito 인프라 생성

npm run setup

공용 앱 클라이언트(비밀 없음), 호스팅 UI 도메인, 테스트 사용자(testuser / TestPass123!)가 있는 Cognito 사용자 풀을 생성합니다. 구성은 .env에 저장됩니다.

3단계: 런타임 배포

npm run deploy-runtime

agentcore CLI를 사용하여 MCP 서버를 AgentCore 런타임에 배포합니다. 런타임은 기본 IAM 인증을 사용합니다(게이트웨이가 사용자를 인증합니다).

4단계: 게이트웨이 배포

npm run deploy-infra

생성합니다:

  • 게이트웨이용 IAM 역할(런타임 호출 권한 포함)

  • CUSTOM_JWT 인바운드 인증(Cognito PKCE)을 사용하는 AgentCore 게이트웨이

  • GATEWAY_IAM_ROLE(SigV4)을 통해 런타임을 가리키는 게이트웨이 대상

.mcp.json 및 claude-mcp-config.json을 게이트웨이 URL로 업데이트합니다.

5단계: 테스트

npm run test-gateway

Cognito를 통해 인증하고(테스트 사용자를 사용한 비대화형), 그런 다음:

  • 인증되지 않은 요청이 거부되는지 확인(401)

  • MCP 세션 초기화

  • 발견된 도구 나열

  • 도구 호출(greet_user, add_numbers, get_server_info)

6단계: Claude Code / Kiro 연결

생성된 구성을 복사합니다:

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

구성은 다음과 같습니다:

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

첫 번째 도구 호출 시 Claude/Kiro가 Cognito 로그인을 위해 브라우저를 엽니다. 이후 토큰은 자동으로 캐시되고 새로 고쳐집니다.

빠른 시작: 독립형 모드

게이트웨이가 필요 없고 런타임이 JWT 인증을 직접 처리하려는 경우:

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 스크립트

스크립트

설명

npm run setup

Cognito 사용자 풀 + 공용 클라이언트 + 테스트 사용자 생성

npm run deploy-runtime

agentcore CLI를 통해 MCP 런타임 배포 (IAM 인증, 게이트웨이용)

npm run deploy-infra

Control Plane API를 통해 게이트웨이 + IAM 역할 + 대상 생성

npm run deploy

직접 JWT 인증으로 런타임 배포 (독립형, 게이트웨이 없음)

npm run test-gateway

게이트웨이 엔드투엔드 테스트 (비대화형)

npm run test-gateway -- --pkce

브라우저 기반 PKCE 로그인으로 게이트웨이 테스트

npm run test-deployed

PKCE를 통해 독립형 런타임 테스트

npm run test-auth

PKCE 인증 흐름만 테스트 (브라우저 열림)

npm run test-local

개발용 MCP 서버를 로컬에서 실행

npm run teardown

모든 인프라 삭제 (게이트웨이, IAM 역할, Cognito 풀)

사용 가능한 MCP 도구

샘플 MCP 서버는 다음을 노출합니다:

도구

설명

add_numbers

두 숫자를 더합니다

multiply_numbers

두 숫자를 곱합니다

greet_user

이름으로 사용자에게 인사합니다

get_server_info

배포 및 버전 정보를 반환합니다

analyze_text

텍스트를 분석하고 기본 통계를 반환합니다

게이트웨이를 통해 액세스하면 도구 이름 앞에 대상 이름이 붙습니다: mcp-runtime___add_numbers.

정리

npm run teardown

다음을 삭제합니다:

  • AgentCore 게이트웨이 (대상 + 게이트웨이)

  • 게이트웨이 IAM 역할

  • Cognito 사용자 풀

  • 로컬 파일 (.env, .mcp.json, claude-mcp-config.json)

AgentCore 런타임은 삭제되지 않습니다(agentcore CLI로 별도 관리). 제거하려면:

cd server/cognitopocmcp && agentcore destroy

주요 개념

제로 시크릿 인증

  • Cognito 공용 클라이언트: GenerateSecret: false — 클라이언트 시크릿이 없음

  • PKCE(code_challenge + code_verifier)는 공유 시크릿 없이 요청자를 증명

  • client_id만 로컬에 저장됨 (공개 식별자, 자격 증명 아님)

  • 토큰은 메모리에 저장되며 1시간 만료 + 자동 새로 고침

게이트웨이 아웃바운드 인증

게이트웨이는 자체 IAM 역할(SigV4)을 사용하여 런타임에 인증합니다. 이는 게이트웨이와 런타임 간의 OAuth 머신 간 흐름의 복잡성을 피합니다. IAM 역할에는 런타임 ARN으로 범위가 지정된 bedrock-agentcore:* 권한이 있습니다.

이식성

모든 환경별 값은 런타임에 파생됩니다:

  • AWS 계정 ID: STS.GetCallerIdentity를 통해 확인

  • 게이트웨이 URL: .mcp.json에서 읽음 (deploy-infra로 생성)

  • 런타임 ARN: agentcore 배포 상태에서 읽음

  • 프로젝트 상수: src/config.mjs에 중앙 집중화

다른 계정/리전에 배포하려면 AWS 자격 증명을 구성하고 설정 단계를 다시 실행하면 됩니다.

보안

보안 문제 신고에 대한 정보는 CONTRIBUTING을 참조하세요.

라이선스

이 라이브러리는 MIT-0 라이선스에 따라 라이선스가 부여됩니다. LICENSE 파일을 참조하세요.

Related MCP Connectors

Related MCP Servers