Skip to main content

Okta CIAM/SSO MCP Server and Agent for Agentic AI!

Project description

Okta Agent

CLI or API | MCP | Agent

PyPI - Version MCP Server PyPI - Downloads GitHub Repo stars PyPI - License GitHub last commit (by committer) PyPI - Wheel

Version: 0.1.0

Documentation — Installation, deployment, usage across the API, CLI, and MCP server live on the docs site: https://knuckles-team.github.io/okta-agent/

Table of Contents

Overview

Enterprise CIAM/SSO connector for the agent fleet: a production-grade MCP server and Pydantic AI agent over the Okta Management API — users, groups, applications, policies, and the system log. Complements keycloak-agent (open-source IdP) with the commercial-IdP side of the house, mirroring its verb taxonomy so agents can switch IdPs with familiar verbs.

  • Raw httpx client — no Okta SDK; every method documents the endpoint it calls.
  • Two auth modes: SSWS API token and OAuth2 private-key-JWT (org authorization server, Okta API scopes).
  • Rate-limit aware: every response envelope carries the latest X-Rate-Limit-* snapshot; HTTP 429 triggers capped automatic backoff.
  • Cursor pagination via Link: rel="next" headers (Okta's after cursor), with hard item caps and resumable next_cursors.
  • Safety: destructive operations (deactivate / delete / clear sessions / password ops) are blocked unless explicitly allowed; credential material is redacted from logs and error envelopes.

Architecture

graph TD
    User([User/A2A]) --> Server[A2A Server / okta-agent]
    Server --> Agent[Pydantic AI Agent]
    Agent --> MCP[MCP Server / okta-mcp]
    MCP --> Client[Api facade / httpx]
    Client --> ExternalAPI([Okta Management API])

Installation

pip install okta-agent            # core API client
pip install okta-agent[mcp]       # + MCP server
pip install okta-agent[agent]     # + Pydantic AI agent server

Configure

export OKTA_ORG_URL="https://acme.okta.com"

# Mode 1 — SSWS API token (takes precedence)
export OKTA_API_TOKEN="<api token>"

# Mode 2 — OAuth2 private-key-JWT (service app, Okta API scopes)
export OKTA_CLIENT_ID="0oa..."
export OKTA_PRIVATE_KEY_FILE="/path/to/key.pem"   # or OKTA_PRIVATE_KEY inline
export OKTA_SCOPES="okta.users.read okta.groups.manage"

See .env.example for every knob (OKTA_SSL_VERIFY, OKTA_MAX_RETRIES, OKTA_BACKOFF_CAP_SECONDS, OKTA_ALLOW_DESTRUCTIVE, per-tool switches).

Environment Variables

Variable Default Purpose
OKTA_ORG_URL Okta org URL, no trailing slash (OKTA_AGENT_BASE_URL accepted as fallback)
OKTA_API_TOKEN SSWS API token (auth mode 1, takes precedence)
OKTA_CLIENT_ID Service-app client id (private-key-JWT)
OKTA_PRIVATE_KEY / OKTA_PRIVATE_KEY_FILE PEM private key inline or path
OKTA_KEY_ID Optional JWKS key id for the client assertion
OKTA_SCOPES read scopes Space-separated Okta API scopes
OKTA_SSL_VERIFY True TLS verification toward the org
OKTA_MAX_RETRIES 2 429 retry attempts
OKTA_BACKOFF_CAP_SECONDS 60 429 backoff cap
OKTA_ALLOW_DESTRUCTIVE False Org-wide default for destructive tool actions
HOST / PORT / TRANSPORT 0.0.0.0 / 8000 / stdio MCP server bind + transport
USERSTOOL / GROUPSTOOL / APPSTOOL / POLICIESTOOL / SYSTEMTOOL True Per-domain tool toggles
ENABLE_OTEL / OTEL_EXPORTER_OTLP_* Telemetry (OTEL / Langfuse)
EUNOMIA_TYPE / EUNOMIA_POLICY_FILE / EUNOMIA_REMOTE_URL none MCP authorization middleware
AUTH_TYPE none MCP server auth mode (Docker)
DEFAULT_AGENT_NAME / AGENT_DESCRIPTION / AGENT_SYSTEM_PROMPT identity files A2A agent identity overrides

Quick Start

from okta_agent import Api
from okta_agent.api.credentials import SswsToken
from okta_agent.okta_input_models import SearchInput, FilterCondition

api = Api(org_url="https://acme.okta.com", credential=SswsToken("<token>"))

active = api.search_users(
    conditions=[{"field": "status", "op": "eq", "value": "ACTIVE"}],
)
print(active["data"], active["rate_limit"])

# Or build typed tool params for the MCP surface:
params = SearchInput(
    conditions=[FilterCondition(field="status", op="eq", value="ACTIVE")]
).model_dump_json(exclude_none=True)

Run

okta-mcp                                  # stdio MCP server
okta-mcp --transport streamable-http --host 0.0.0.0 --port 8000
okta-agent                                # A2A agent server

MCP Tools

Five consolidated, action-routed tools. Each takes action, params_json, and (where applicable) allow_destructive.

Tool Actions Destructive (gated)
okta_users list, search, get, create, update, activate, deactivate, suspend, unsuspend, unlock, expire_password, reset_password, list_groups, list_apps, list_factors, clear_sessions deactivate, suspend, expire_password, reset_password, clear_sessions
okta_groups list, search, get, create, update, delete, list_members, add_member, remove_member, list_rules, create_rule, activate_rule, deactivate_rule delete, remove_member, deactivate_rule
okta_apps list, get, create (oidc/saml/bookmark templates), update, activate, deactivate, list_users, assign_user, unassign_user, list_groups, assign_group, unassign_group deactivate, unassign_user, unassign_group
okta_policies list (okta_sign_on/password/mfa_enroll/access_policy), get, list_rules, activate, deactivate, activate_rule, deactivate_rule — policy/rule create+update intentionally out of scope in this release deactivate, deactivate_rule
okta_system org, list_authorization_servers, logs (since/until/filter/q, capped at 1000 events, resumable cursor), list_authenticators, list_factors, list_zones

Examples

{"action": "search", "params_json": "{\"conditions\": [{\"field\": \"status\", \"op\": \"eq\", \"value\": \"ACTIVE\"}, {\"field\": \"profile.department\", \"op\": \"eq\", \"value\": \"Engineering\"}]}"}
{"action": "create", "params_json": "{\"template\": \"oidc\", \"label\": \"My App\", \"settings\": {\"redirect_uris\": [\"https://app.example.com/cb\"]}}"}
{"action": "deactivate", "params_json": "{\"user_id\": \"00u1\"}", "allow_destructive": true}

Every successful response is an envelope:

{"data": [...], "rate_limit": {"limit": 600, "remaining": 599, "reset": 1700000000}, "count": 5, "truncated": false, "next_cursor": null}

Errors map Okta's envelope: {"error": {"status", "error_code", "error_summary", "error_id", "error_causes", "rate_limit"}}.

Deployment

# MCP server only (port 8000, streamable-http, /health)
docker compose -f docker/mcp.compose.yml up -d

# MCP server + A2A agent server (agent on port 9021, AG-UI web interface)
docker compose -f docker/agent.compose.yml up -d

The A2A agent server (okta-agent console script, agent_server.py) reads MCP_URL, PROVIDER, and MODEL_ID from the environment. Prebuilt image: knucklessg1/okta-agent:latest. See docs/deployment.md for transports, reverse proxy, and DNS guidance.

Keycloak parity

Verbs intentionally mirror keycloak-agent where the concepts overlap, so an agent fluent in one IdP connector can drive the other:

Concept keycloak-agent okta-agent
Users CRUD keycloak_agent_users list/get/create/update okta_users list/get/create/update
Password reset reset_password reset_password (plus expire_password)
User's groups list_users_by_user_id_groups list_groups
Groups CRUD + members keycloak_agent_groups okta_groups (+ Okta group rules)
OAuth/SAML clients keycloak_agent_clients okta_apps (Keycloak "clients" = Okta "apps")
Auth policies/flows keycloak_agent_authentication okta_policies (read + lifecycle)
Server/org info & events keycloak_agent_info / attack detection okta_system (org + system log)

Okta-only surface: lifecycle states (suspend/unlock), group rules, app assignment profiles, network zones, Okta API scopes via private-key-JWT.

Development

pip install -e .[mcp,test]
pytest -v
pre-commit run --all-files

API references are cited in every client docstring (https://developer.okta.com/docs/api/).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

okta_agent-0.1.0.tar.gz (53.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

okta_agent-0.1.0-py3-none-any.whl (68.7 kB view details)

Uploaded Python 3

File details

Details for the file okta_agent-0.1.0.tar.gz.

File metadata

  • Download URL: okta_agent-0.1.0.tar.gz
  • Upload date:
  • Size: 53.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for okta_agent-0.1.0.tar.gz
Algorithm Hash digest
SHA256 5959bf8374fbf42e061f3384d2590c4ea0fee7887ce87755cfa7cabbfbe47d38
MD5 bc09950bdacd48c9d131aeadeba15ac6
BLAKE2b-256 a8086573e012ebc805aef541f648f08c01592188bfaa3feab39d8d0c0907b018

See more details on using hashes here.

File details

Details for the file okta_agent-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: okta_agent-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 68.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for okta_agent-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9b8618d4db436db2a414ab744219fbbe585fbc41207a7f467e203506568a849f
MD5 9d9e41dd1182f1e5cb83d59aaba17a32
BLAKE2b-256 a325919de69e06c090ef7115670196691de175521e4dc86efc595e8a09a54e55

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page