
[](https://opensource.org/licenses/Apache-2.0)
[](https://python.org/)
[MCP (Model Context Protocol)](https://modelcontextprotocol.io/introduction) is an open protocol introduced by Anthropic that standardizes how large language models communicate with external tools, resources or remote services.
The Okta MCP Server integrates with LLMs and AI agents, allowing you to perform various Okta management operations using natural language. For instance, you could simply ask Claude Desktop to perform Okta management operations:
- > Create a new user and add them to the Engineering group
- > Show me all failed login attempts from the last 24 hours
- > List all applications that haven't been used in the past month
**Empower your LLM Agents to Manage your Okta Organization**
This server is an [Model Context Protocol](https://modelcontextprotocol.io/introduction) server that provides seamless integration with Okta's Admin Management APIs. It allows LLM agents to interact with Okta in a programmatic way, enabling automation and enhanced management capabilities.
## Key Features
* **LLM-Driven Okta Management:** Allows your LLM agents to perform administrative tasks within your Okta environment based on natural language instructions.
* **Secure Authentication:** Supports both Device Authorization Grant for interactive use and Private Key JWT for secure, automated server-to-server communication.
* **Interactive Confirmation via Elicitation:** Destructive operations (deletes, deactivations) prompt the user for confirmation through the [MCP Elicitation API](https://modelcontextprotocol.io/specification/2025-06-18/client/elicitation) before proceeding, with automatic fallback for clients that do not yet support the feature.
* **Integration with Okta Admin Management APIs:** Leverages the official Okta APIs to ensure secure and reliable interaction with your Okta org.
* **Extensible Architecture:** Designed to be easily extended with new functionalities and support for additional Okta API endpoints.
* **Comprehensive Tool Support:** Full CRUD operations for users, groups, applications, policies, and more.
This MCP server utilizes [Okta's Python SDK](https://github.com/okta/okta-sdk-python) to communicate with the Okta APIs, ensuring a robust and well-supported integration.
## 🚀 Getting Started
**Prerequisites:**
- [Python 3.8+](https://python.org/downloads) OR [Docker](https://docs.docker.com/get-docker/)
- [uv](https://docs.astral.sh/uv/getting-started/installation/) package manager (if not using Docker)
- [Claude Desktop](https://claude.ai/download) or any other [MCP Client](https://modelcontextprotocol.io/clients)
- [Okta](https://okta.com/) account with appropriate permissions
### Install the Okta MCP Server
Install Okta MCP Server and configure it to work with your preferred MCP Client.
Choose one of the following installation methods:
🐳 Option 1: Docker (Recommended)
Docker provides a consistent environment without needing to install Python or uv locally.
1. Clone the repository:
```bash
git clone https://github.com/okta/okta-mcp-server.git
cd okta-mcp-server
```
2. Create a `.env` file from the example:
```bash
cp .env.example .env
# Edit .env and add your Okta credentials
```
3. Build and run with Docker Compose:
```bash
docker-compose up -d
```
4. Configure your MCP Client to use the Docker container:
**Claude Desktop with Docker (Private Key JWT - Recommended for Docker):**
This method requires no browser interaction and is ideal for containerized environments.
```json
{
"mcpServers": {
"okta-mcp-server": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "OKTA_ORG_URL",
"-e", "OKTA_CLIENT_ID",
"-e", "OKTA_SCOPES",
"-e", "OKTA_PRIVATE_KEY",
"-e", "OKTA_KEY_ID",
"okta-mcp-server"
],
"env": {
"OKTA_ORG_URL": "https://your-org.okta.com",
"OKTA_CLIENT_ID": "your-client-id",
"OKTA_SCOPES": "okta.users.read okta.groups.read",
"OKTA_PRIVATE_KEY": "-----BEGIN RSA PRIVATE KEY-----
Your private key content here
-----END RSA PRIVATE KEY-----",
"OKTA_KEY_ID": "your-key-id"
}
}
}
}
```
**Claude Desktop with Docker (Device Authorization Grant):**
This method requires browser-based authentication. When the server starts, it will display an authentication URL in the logs. Copy and paste this URL into your browser to complete the authentication.
> **Note:** Docker containers cannot open a browser on the host automatically. You must manually copy the URL from `docker logs okta-mcp-server` and paste it into your browser.
```json
{
"mcpServers": {
"okta-mcp-server": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-v", "okta-keyring:/home/appuser/.local/share/python_keyring",
"-e", "OKTA_ORG_URL",
"-e", "OKTA_CLIENT_ID",
"-e", "OKTA_SCOPES",
"-e", "PYTHON_KEYRING_BACKEND=keyrings.alt.file.PlaintextKeyring",
"okta-mcp-server"
],
"env": {
"OKTA_ORG_URL": "https://your-org.okta.com",
"OKTA_CLIENT_ID": "your-client-id",
"OKTA_SCOPES": "okta.users.read okta.groups.read"
}
}
}
}
```
The `-v okta-keyring:/home/appuser/.local/share/python_keyring` volume persists tokens between container restarts.
**VS Code with Docker (Private Key JWT - Recommended for Docker):**
```json
{
"mcp": {
"inputs": [
{
"type": "promptString",
"description": "Okta Organization URL (e.g., https://dev-123456.okta.com)",
"id": "OKTA_ORG_URL"
},
{
"type": "promptString",
"description": "Okta Client ID",
"id": "OKTA_CLIENT_ID",
"password": true
},
{
"type": "promptString",
"description": "Okta Scopes (separated by whitespace)",
"id": "OKTA_SCOPES"
},
{
"type": "promptString",
"description": "Okta Private Key (for browserless auth)",
"id": "OKTA_PRIVATE_KEY",
"password": true
},
{
"type": "promptString",
"description": "Okta Key ID (for browserless auth)",
"id": "OKTA_KEY_ID",
"password": true
}
],
"servers": {
"okta-mcp-server": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "OKTA_ORG_URL=${input:OKTA_ORG_URL}",
"-e", "OKTA_CLIENT_ID=${input:OKTA_CLIENT_ID}",
"-e", "OKTA_SCOPES=${input:OKTA_SCOPES}",
"-e", "OKTA_PRIVATE_KEY=${input:OKTA_PRIVATE_KEY}",
"-e", "OKTA_KEY_ID=${input:OKTA_KEY_ID}",
"okta-mcp-server"
]
}
}
}
}
```
**VS Code with Docker (Device Authorization Grant):**
> **Note:** Device Authorization requires manual browser interaction. When the server starts, check the MCP output panel for the authentication URL, then copy and paste it into your browser.
```json
{
"mcp": {
"inputs": [
{
"type": "promptString",
"description": "Okta Organization URL (e.g., https://dev-123456.okta.com)",
"id": "OKTA_ORG_URL"
},
{
"type": "promptString",
"description": "Okta Client ID",
"id": "OKTA_CLIENT_ID",
"password": true
},
{
"type": "promptString",
"description": "Okta Scopes (separated by whitespace)",
"id": "OKTA_SCOPES"
}
],
"servers": {
"okta-mcp-server": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-v", "okta-keyring:/home/appuser/.local/share/python_keyring",
"-e", "OKTA_ORG_URL=${input:OKTA_ORG_URL}",
"-e", "OKTA_CLIENT_ID=${input:OKTA_CLIENT_ID}",
"-e", "OKTA_SCOPES=${input:OKTA_SCOPES}",
"-e", "PYTHON_KEYRING_BACKEND=keyrings.alt.file.PlaintextKeyring",
"okta-mcp-server"
]
}
}
}
}
```
**Alternatively, use docker-compose (requires .env file):**
```json
{
"mcp": {
"servers": {
"okta-mcp-server": {
"command": "docker-compose",
"args": [
"-f",
"/path/to/okta-mcp-server/docker-compose.yml",
"run",
"--rm",
"okta-mcp-server"
]
}
}
}
}
```
**Alternatively, build and run directly:**
```bash
# Build the image
docker build -t okta-mcp-server .
# Run the container
docker run -i --rm \
-e OKTA_ORG_URL="" \
-e OKTA_CLIENT_ID="" \
-e OKTA_SCOPES="" \
okta-mcp-server
```
📦 Option 2: uv (Python Package Manager)
1. Clone and install the server:
```bash
git clone https://github.com/okta/okta-mcp-server.git
cd okta-mcp-server
uv sync
```
2. Configure Claude Desktop by adding the following to your `claude_desktop_config.json`:
```json
{
"mcpServers": {
"okta-mcp-server": {
"command": "uv",
"args": [
"run",
"--directory",
"/path/to/okta-mcp-server",
"okta-mcp-server"
],
"env": {
"OKTA_ORG_URL": "",
"OKTA_CLIENT_ID": "",
"OKTA_SCOPES": "",
"OKTA_PRIVATE_KEY": "",
"OKTA_KEY_ID": ""
}
}
}
}
```
### Configure with Different MCP Clients
VS Code
Add the following to your VS Code `settings.json`:
```json
{
"mcp": {
"inputs": [
{
"type": "promptString",
---