Skip to main content
Glama
pcolazurdo

blog-zero-secrets-mcp

by pcolazurdo

AgentCore + Cognito Public Client MCP PoC

End-to-End-Proof-of-Concept, das zwei Bereitstellungsmodi für einen MCP-Server auf AgentCore demonstriert:

  1. Standalone – Runtime mit direkter Cognito-JWT-Authentifizierung (ohne Gateway)

  2. Gateway – Runtime hinter einem AgentCore-Gateway mit Cognito-PKCE-Inbound-Authentifizierung und IAM-Outbound-Authentifizierung

Beide Modi verwenden einen öffentlichen Cognito-Client (ohne Secret) mit PKCE für die Benutzerauthentifizierung.

Architektur

Modus A: Standalone (Runtime mit direkter JWT-Authentifizierung)

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

Modus B: Gateway (empfohlen)

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)

Der Gateway-Modus bietet:

  • Zentralisierte Authentifizierung (das Gateway übernimmt die gesamte JWT-Validierung)

  • Tool-Erkennung und semantische Suche über mehrere Targets hinweg

  • MCP-Routing auf Protokollebene

  • Trennung von Verantwortlichkeiten (die Runtime muss nichts über die Benutzerauthentifizierung wissen)

Related MCP server: local-kms-mcp-server

Projektstruktur

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

Voraussetzungen

# 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

Schnellstart: Gateway-Modus (empfohlen)

Schritt 1: Abhängigkeiten installieren

npm install

Schritt 2: Cognito-Infrastruktur erstellen

npm run setup

Erstellt einen Cognito-User-Pool mit einem öffentlichen App-Client (ohne Secret), einer gehosteten UI-Domain und einem Testbenutzer (testuser / TestPass123!). Die Konfiguration wird in .env gespeichert.

Schritt 3: Runtime bereitstellen

npm run deploy-runtime

Stellt den MCP-Server über die agentcore-CLI auf der AgentCore-Runtime bereit. Die Runtime verwendet die Standard-IAM-Authentifizierung (das Gateway übernimmt die Benutzerauthentifizierung).

Schritt 4: Gateway bereitstellen

npm run deploy-infra

Erstellt:

  • Eine IAM-Rolle für das Gateway (mit Berechtigung zum Aufrufen der Runtime)

  • Ein AgentCore-Gateway mit CUSTOM_JWT-Inbound-Authentifizierung (Cognito PKCE)

  • Ein Gateway-Target, das über GATEWAY_IAM_ROLE (SigV4) auf die Runtime verweist

Aktualisiert .mcp.json und claude-mcp-config.json mit der Gateway-URL.

Schritt 5: Testen

npm run test-gateway

Authentifiziert sich über Cognito (nicht-interaktiv mit dem Testbenutzer) und prüft dann:

  • Dass unauthentifizierte Anfragen abgewiesen werden (401)

  • Initialisiert eine MCP-Sitzung

  • Listet erkannte Tools auf

  • Ruft Tools auf (greet_user, add_numbers, get_server_info)

Schritt 6: Claude Code / Kiro verbinden

Kopieren Sie die generierte Konfiguration:

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

Die Konfiguration sieht wie folgt aus:

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

Beim ersten Toolaufruf öffnet Claude/Kiro Ihren Browser für die Cognito-Anmeldung. Danach werden die Tokens automatisch zwischengespeichert und aktualisiert.

Schnellstart: Standalone-Modus

Falls Sie kein Gateway benötigen und die Runtime die JWT-Authentifizierung direkt übernehmen soll:

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-Skripte

Script

Beschreibung

npm run setup

Erstellt Cognito-User-Pool + öffentlichen Client + Testbenutzer

npm run deploy-runtime

Stellt die MCP-Runtime über die agentcore-CLI bereit (IAM-Auth, für Gateway)

npm run deploy-infra

Erstellt Gateway + IAM-Rolle + Target über die Control-Plane-API

npm run deploy

Stellt die Runtime mit direkter JWT-Auth bereit (Standalone, ohne Gateway)

npm run test-gateway

Testet das Gateway End-to-End (nicht-interaktiv)

npm run test-gateway -- --pkce

Testet das Gateway mit browserbasiertem PKCE-Login

npm run test-deployed

Testet die Standalone-Runtime per PKCE

npm run test-auth

Testet nur den PKCE-Authflow (öffnet den Browser)

npm run test-local

Führt den MCP-Server lokal für die Entwicklung aus

npm run teardown

Löscht die gesamte Infrastruktur (Gateway, IAM-Rolle, Cognito-Pools)

Verfügbare MCP-Tools

Der Beispiel-MCP-Server stellt die folgenden Tools bereit:

Tool

Beschreibung

add_numbers

Addiert zwei Zahlen miteinander

multiply_numbers

Multipliziert zwei Zahlen miteinander

greet_user

Begrüßt einen Benutzer namentlich

get_server_info

Gibt Bereitstellungs- und Versionsinformationen zurück

analyze_text

Analysiert Text und gibt Basisstatistiken zurück

Beim Zugriff über das Gateway wird der Name des Targets den Tool-Namen vorangestellt: mcp-runtime___add_numbers.

Bereinigung

npm run teardown

Dies löscht:

  • AgentCore-Gateway (Targets + Gateway)

  • Gateway-IAM-Rolle

  • Cognito-User-Pool(s)

  • Lokale Dateien (.env, .mcp.json, claude-mcp-config.json)

Die AgentCore-Runtime wird NICHT gelöscht (sie wird separat über die agentcore-CLI verwaltet). Um sie zu entfernen:

cd server/cognitopocmcp && agentcore destroy

Wichtige Konzepte

Central-Secrets-Authentifizierung

  • Cognito Public Client: GenerateSecret: false – es existiert kein Client-Secret

  • PKCE (code_challenge + code_verifier) weist die Berechtigung des klapp nach ohne gemeinsames Secret

  • Nur client_id wird lokal gespeichert (ein öffentlicher Identifier, keine Anmeldedaten)

  • Tokens liegen im Arbeitsspeicher mit einer Ablaufzeit von 1 Stunde und Auto-Refresh

Gateway-Outbound-Authentifizierung

Das Gateway authentifiziert sich gegenüber der Runtime über eine eigene IAM-Rolle (SigV4). Das vermeidet die Komplexität von OAuth-Machine-to-Machine-Flows zwischen Gateway und Runtime. Die IAM-Rolle hat die Berechtigung bedrock-agentcore:*, auf die Runtime-ARN eingeschränkt.

Portabilität

Alle umgebungsspezifischen Werte werden zur Laufzeit abgeleitet:

  • AWS-Konto-ID: aufgelöst über sts.GetCallerIdentity

  • Gateway-URL: gelesen aus .mcp.json (erzeugt durch deploy-infra)

  • Runtime-ARN: gelesen aus dem AgentCore-Deploymentstand

  • Projektkonstanten: zentral in src/config.mjs

Um in einer anderen AWS-Kunden/Region zu deploien, einfach AWS-Zugangsdaten konfigurieren und die Einrichtungsschritte erneut ausführen.

Sicherheit

Siehe CONTRIBUTING für Informationen zur Meldung von Sicherheitsproblemen.

Lizenz

Diese Bibliothek ist unter der MIT-0-Lizenz lizenziert. Siehe LICENSE.

Related MCP Connectors

Related MCP Servers