Skip to main content

Overview

The MCP Server with LangGraph provides automated setup scripts for configuring Keycloak, identity federation, and JWT management. These scripts streamline deployment and ensure consistent configuration across environments.
All setup scripts are located in the /scripts/setup/ directory and require appropriate environment variables to be configured.

setup_keycloak.py

Initializes Keycloak with realm, clients, users, and OpenFGA synchronization.

Purpose

Automates the initial Keycloak setup for the MCP Server with LangGraph, including:
  • Realm creation (langgraph-agent)
  • Client configuration with service accounts enabled
  • Default test users (alice, bob, admin)
  • Role mappings (admin, premium, user)
  • Optional OpenFGA tuple synchronization

Usage

python scripts/setup/setup_keycloak.py

Environment Variables

VariableDefaultDescription
KEYCLOAK_SERVER_URLhttp://localhost:8082Keycloak server URL
KEYCLOAK_ADMIN_USERNAMEadminKeycloak admin username
KEYCLOAK_ADMIN_PASSWORDadminKeycloak admin password
KEYCLOAK_REALMlanggraph-agentRealm name to create/configure
VariableDefaultDescription
KEYCLOAK_CLIENT_IDlanggraph-clientOAuth2/OIDC client ID
KEYCLOAK_CLIENT_SECRET(generated)Client secret (auto-generated if not provided)
SYNC_TO_OPENFGAfalseEnable automatic OpenFGA tuple creation
OPENFGA_API_URL-OpenFGA API endpoint (if syncing)

What It Creates

1

Realm Setup

Creates the langgraph-agent realm with:
  • Access token lifespan: 15 minutes (900s)
  • Refresh token lifespan: 30 minutes (1800s)
  • Service account refresh token: 30 days (2592000s)
  • Login and registration enabled
2

Client Configuration

Creates OAuth2/OIDC client with:
  • Client ID: langgraph-client
  • Service accounts enabled (for service principals)
  • Direct access grants enabled
  • Standard flow enabled
  • Client credentials flow enabled
3

Default Users

Creates test users:
  • alice (password: alice123) - Premium user
  • bob (password: bob123) - Standard user
  • admin (password: admin123) - Administrator
4

Role Definitions

Creates client roles:
  • admin - Full administrative access
  • premium - Premium tier features
  • user - Standard user access

Example

export KEYCLOAK_SERVER_URL=https://keycloak.example.com
export KEYCLOAK_ADMIN_USERNAME=admin
export KEYCLOAK_ADMIN_PASSWORD=secure_password
export SYNC_TO_OPENFGA=true
export OPENFGA_API_URL=http://openfga:8080

python scripts/setup/setup_keycloak.py

setup_ldap_federation.py

Configures Keycloak to federate users from LDAP or Active Directory.

Purpose

Enables enterprise LDAP/Active Directory integration where users authenticate against their existing directory service, and Keycloak issues JWTs. This allows centralized identity management without duplicating user databases.

Usage

python scripts/setup/setup_ldap_federation.py

Environment Variables

VariableDefaultDescription
KEYCLOAK_SERVER_URLhttp://localhost:8082Keycloak server URL
KEYCLOAK_ADMIN_USERNAMEadminAdmin username
KEYCLOAK_ADMIN_PASSWORDadminAdmin password
KEYCLOAK_REALMlanggraph-agentTarget realm
VariableRequiredDescription
LDAP_CONNECTION_URLLDAP server URL (e.g., ldap://ad.example.com:389)
LDAP_BIND_DNService account DN for binding
LDAP_BIND_PASSWORDService account password
LDAP_USERS_DNBase DN for user search
VariableDefault (AD)Default (LDAP)Description
LDAP_USERNAME_ATTRIBUTEsAMAccountNameuidUsername attribute
LDAP_USER_OBJECT_CLASSESperson,organizationalPerson,userinetOrgPerson,organizationalPersonUser object classes
LDAP_VENDORadotherLDAP vendor (ad/other)

What It Configures

User Federation

  • LDAP user provider configuration
  • Attribute mapping (email, name, phone, etc.)
  • Username and UUID mapping
  • Read-only federation (users managed in LDAP)

Group Synchronization

  • LDAP group mapper
  • Group hierarchy preservation
  • Automatic role assignment
  • Periodic sync (hourly changed, daily full)

Attribute Mappers

  • Standard attributes (email, firstName, lastName)
  • Extended attributes (department, title, phone)
  • Custom mappings from /config/ldap_mappers.yaml

Sync Schedule

  • Full sync: Every 24 hours
  • Changed sync: Every hour
  • Batch size: 1000 users
  • Connection pooling enabled

Active Directory Example

export KEYCLOAK_SERVER_URL=https://keycloak.example.com
export KEYCLOAK_ADMIN_USERNAME=admin
export KEYCLOAK_ADMIN_PASSWORD=admin_password

## Active Directory Configuration
export LDAP_CONNECTION_URL='ldap://ad.example.com:389'
export LDAP_BIND_DN='CN=svc_keycloak,OU=Service Accounts,DC=example,DC=com'
export LDAP_BIND_PASSWORD='service_account_password'
export LDAP_USERS_DN='OU=Users,DC=example,DC=com'
export LDAP_VENDOR=ad

python scripts/setup/setup_ldap_federation.py

Generic LDAP Example

export LDAP_CONNECTION_URL='ldap://ldap.example.com:389'
export LDAP_BIND_DN='cn=admin,dc=example,dc=com'
export LDAP_BIND_PASSWORD='ldap_password'
export LDAP_USERS_DN='ou=people,dc=example,dc=com'
export LDAP_USERNAME_ATTRIBUTE=uid
export LDAP_VENDOR=other

python scripts/setup/setup_ldap_federation.py

Configuration File

The script uses /config/ldap_mappers.yaml for attribute mapping configuration. See Configuration Files Reference for details.

setup_saml_idp.py

Configures SAML 2.0 identity provider integration (e.g., ADFS, Okta, Azure AD).

Purpose

Enables SAML-based Single Sign-On (SSO) from enterprise identity providers. Users authenticate via their corporate SSO portal, and Keycloak issues JWTs for MCP Server access.

Usage

python scripts/setup/setup_saml_idp.py

Environment Variables

VariableDefaultDescription
KEYCLOAK_SERVER_URLhttp://localhost:8082Keycloak server URL
KEYCLOAK_ADMIN_USERNAMEadminAdmin username
KEYCLOAK_ADMIN_PASSWORDadminAdmin password
KEYCLOAK_REALMlanggraph-agentTarget realm
VariableRequiredDescription
SAML_ALIASIdentity provider alias (e.g., adfs, okta)
SAML_SSO_URLSAML SSO endpoint URL
SAML_ENTITY_IDIdentity provider entity ID
SAML_CERTIFICATEX.509 certificate (PEM format)
VariableDefaultDescription
SAML_NAME_ID_FORMATurn:oasis:names:tc:SAML:1.1:nameid-format:emailAddressName ID format
SAML_WANT_ASSERTIONS_SIGNEDtrueRequire signed assertions
SAML_FORCE_AUTHNfalseForce re-authentication

Supported Providers

  • ADFS
  • Okta
  • Azure AD
export SAML_ALIAS=adfs
export SAML_SSO_URL='https://adfs.example.com/adfs/ls/'
export SAML_ENTITY_ID='https://adfs.example.com/adfs/services/trust'
export SAML_CERTIFICATE='-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAK...
-----END CERTIFICATE-----'

python scripts/setup/setup_saml_idp.py

What It Creates

  • SAML identity provider configuration in Keycloak
  • Attribute mappers (email, firstName, lastName, roles)
  • SP metadata for configuration in external IdP
  • Trust relationship between Keycloak and SAML IdP

Testing

After configuration, test SAML authentication:
## Get Keycloak SP metadata for configuring external IdP
curl https://keycloak.example.com/realms/langgraph-agent/protocol/saml/descriptor

setup_oidc_idp.py

Configures OpenID Connect identity provider integration (Google, GitHub, custom OIDC providers).

Purpose

Enables OAuth 2.0 / OpenID Connect based authentication from social providers (Google, GitHub) or enterprise OIDC providers (Auth0, Keycloak).

Usage

python scripts/setup/setup_oidc_idp.py --provider google
python scripts/setup/setup_oidc_idp.py --provider github
python scripts/setup/setup_oidc_idp.py --provider custom

Environment Variables

VariableDefaultDescription
KEYCLOAK_SERVER_URLhttp://localhost:8082Keycloak server URL
KEYCLOAK_ADMIN_USERNAMEadminAdmin username
KEYCLOAK_ADMIN_PASSWORDadminAdmin password
KEYCLOAK_REALMlanggraph-agentTarget realm
Google:
GOOGLE_CLIENT_ID=<oauth-client-id>
GOOGLE_CLIENT_SECRET=<oauth-client-secret>
GitHub:
GITHUB_CLIENT_ID=<oauth-app-id>
GITHUB_CLIENT_SECRET=<oauth-app-secret>
Custom OIDC:
OIDC_ALIAS=custom-idp
OIDC_AUTHORIZATION_URL=https://idp.example.com/oauth/authorize
OIDC_TOKEN_URL=https://idp.example.com/oauth/token
OIDC_USERINFO_URL=https://idp.example.com/userinfo
OIDC_JWKS_URL=https://idp.example.com/.well-known/jwks.json
OIDC_CLIENT_ID=<client-id>
OIDC_CLIENT_SECRET=<client-secret>

Provider Examples

Google

export GOOGLE_CLIENT_ID='123456.apps.googleusercontent.com'
export GOOGLE_CLIENT_SECRET='GOCSPX-...'

python scripts/setup/setup_oidc_idp.py --provider google

GitHub

export GITHUB_CLIENT_ID='Iv1.a1b2c3d4e5f6g7h8'
export GITHUB_CLIENT_SECRET='ghp_...'

python scripts/setup/setup_oidc_idp.py --provider github

Custom

export OIDC_ALIAS=auth0
export OIDC_AUTHORIZATION_URL='https://example.auth0.com/authorize'
export OIDC_TOKEN_URL='https://example.auth0.com/oauth/token'
export OIDC_CLIENT_ID='...'
export OIDC_CLIENT_SECRET='...'

python scripts/setup/setup_oidc_idp.py --provider custom

Configuration File

The script can use /config/oidc_providers.yaml for managing multiple OIDC providers. See Configuration Files Reference.

update_kong_jwks.py

Updates Kong Gateway with the latest Keycloak JWKS (JSON Web Key Set) for JWT validation.

Purpose

Synchronizes Keycloak’s public keys with Kong Gateway to enable JWT validation. This script is typically run as a Kubernetes CronJob to automatically rotate keys.

Usage

## Manual execution
python scripts/update_kong_jwks.py

## Kubernetes CronJob (recommended)
kubectl apply -f deployments/kubernetes/kong/kong-jwks-updater-cronjob.yaml

Environment Variables

VariableDefaultDescription
KEYCLOAK_SERVER_URLhttp://keycloak:8080Keycloak server URL
KEYCLOAK_REALMlanggraph-agentRealm name
KONG_ADMIN_URLhttp://kong-admin:8001Kong Admin API URL
KONG_CONSUMER_NAMEjwt-consumerKong consumer for JWT plugin

What It Does

1

Fetch JWKS

Retrieves the current JSON Web Key Set from Keycloak’s OIDC discovery endpoint:
GET /realms/{realm}/protocol/openid-connect/certs
2

Convert to PEM

Converts JWK format to PEM format required by Kong’s JWT plugin.
3

Update Kong Consumer

Updates the Kong consumer’s public key via Admin API:
PATCH /consumers/{consumer}/jwt
4

Verify

Tests JWT validation to ensure the update was successful.

Automated Updates

Deploy as a Kubernetes CronJob for automatic key rotation:
apiVersion: batch/v1
kind: CronJob
metadata:
  name: kong-jwks-updater
spec:
  schedule: "0 */6 * * *"  # Every 6 hours
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: jwks-updater
            image: mcp-server-langgraph:latest
            command: ["python", "scripts/update_kong_jwks.py"]
            env:
            - name: KEYCLOAK_SERVER_URL
              value: "http://keycloak:8080"
            - name: KONG_ADMIN_URL
              value: "http://kong-admin:8001"

Troubleshooting

Ensure Keycloak and Kong are accessible from the script’s execution environment. Check service names and ports in Kubernetes.
Verify Keycloak is returning valid JWKs:
curl http://keycloak:8080/realms/langgraph-agent/protocol/openid-connect/certs | jq
Create the Kong consumer first:
kubectl apply -f deployments/kubernetes/kong/kong-consumers.yaml

Common Patterns

Prerequisites Check

All scripts include health checks for dependencies:
## Wait for Keycloak to be ready (max 30 retries, 2s delay)
./scripts/setup/setup_keycloak.py
## ✓ Keycloak is ready!

Idempotent Execution

Scripts can be run multiple times safely:
  • Existing resources are updated, not duplicated
  • Configuration changes are applied incrementally
  • No data loss on re-runs

Error Handling

All scripts provide detailed error messages:
 Error: LDAP_CONNECTION_URL is required but not set
  Set the environment variable and try again.

Dry Run Mode

Some scripts support dry-run for validation:
## Preview changes without applying
DRY_RUN=true python scripts/setup/setup_keycloak.py

Best Practices

Use Environment Files

# .env.keycloak
KEYCLOAK_SERVER_URL=https://...
KEYCLOAK_ADMIN_USERNAME=admin
KEYCLOAK_ADMIN_PASSWORD=...

# Load and run
source .env.keycloak
python scripts/setup/setup_keycloak.py

Secrets Management

Never commit credentials to git. Use:
  • Kubernetes Secrets
  • External Secrets Operator
  • Infisical
  • Vault

Script Chaining

# Complete setup pipeline
python scripts/setup/setup_keycloak.py && \
python scripts/setup/setup_ldap_federation.py && \
python scripts/update_kong_jwks.py

Version Control

Track configuration files in git:
  • /config/ldap_mappers.yaml
  • /config/oidc_providers.yaml
  • /config/role_mappings.yaml

See Also