MCP Servers

A collection of Model Context Protocol servers, templates, tools and more.

MCP server by OmadaIdentity

Created 6/4/2026
Updated about 5 hours ago
Repository documentation and setup instructions

Omada Identity MCP Server

Important: This MCP server is published as a reference project from our innovation initiative. It is made available free of charge for evaluation and exploration, but is not part of Omada's supported production toolset. Functionality and APIs may evolve, and it is not intended for mission-critical workloads. See LICENSE for terms of use. If you encounter issues or would like to share feedback, please reach out through our support channel on Freshdesk.

A Model Context Protocol server that connects Claude Desktop, GitHub Copilot, and other MCP clients directly to an Omada Identity Governance instance.

Authentication is fully automatic — OAuth 2.0 Authorization Code + PKCE opens the browser once, then silently refreshes in the background. No bearer tokens, no separate auth server, no manual copy-paste.

Features

  • Automatic authentication — Auth Code + PKCE, token encrypted at rest with Windows DPAPI
  • OData API — query identities, resources, roles, assignments with full filtering and pagination
  • GraphQL API — access requests, approvals, contexts, calculated assignments, compliance
  • Works in Claude Desktop and GitHub Copilot — stdio transport, no extra setup
  • Response caching — configurable TTL to reduce repeated API calls

Start here

New to this project? Follow these three steps for your first successful interaction:

  1. Azure AD setup — create a dedicated app registration (5 min, requires Azure admin for consent)
  2. Configuration — add three values to your MCP client config (no .env needed)
  3. MCP client config — point Claude Desktop or Copilot at the server

On first use the server opens a browser for login, then calls ping to confirm connectivity. After that, try:

"Show me the first 5 identities in Omada"

If you get stuck, reach out through the Omada support channel on Freshdesk.

Requirements

  • Python 3.10+
  • An Omada Identity Cloud instance with OpenID authentication configured
  • An Azure AD app registration (public client — no secret required)
  • The user account must exist in the Omada environment

Installation

git clone <your-repo-url>
cd omada-mcp-server
pip install -r requirements.txt

Configuration is provided via the MCP client config (Claude Desktop or VS Code) — no .env file needed for normal use. See Configuration for details.

Azure AD setup

There are two separate app registrations involved:

  • Omada app — the app that backs the Omada API. It already exists and is managed by your Omada/IT team. You do not create this one.
  • MCP client app — a new, dedicated app you create below. This is what the MCP server uses to authenticate users and obtain tokens to call the Omada API.

Prerequisite: verify the Omada app exposes its API

Before creating the client app, confirm that the Omada app registration (the one that backs your Omada instance) has Expose an API configured with a user_impersonation scope.

How to find the Omada app registration: go to Azure Portal → App registrations → All applications and look for an app whose name matches your Omada instance (e.g. https://your-instance.omada.cloud/logon.aspx). If you are unsure which one it is, ask your Omada platform administrator.

If user_impersonation scope does not exist, create it:

  1. Open the Omada app registration → Expose an API.
  2. If Application ID URI is empty, click Add. Azure proposes api://<client-id>replace it with your Omada base URL: https://your-instance.omada.cloud. This is required for authentication to work without extra configuration.
  3. Click + Add a scope and fill in:
    • Scope name: user_impersonation
    • Who can consent: Admins only
    • Admin consent display name: Access Omada Identity
    • Admin consent description: Allows the app to access Omada Identity on behalf of the signed-in user
    • State: Enabled
  4. Save.

Create the MCP client app

  1. Go to Azure Portal → App registrations → New registration.

    • Name: something descriptive, e.g. omada-mcp-client.
    • Supported account types: select Accounts in this organizational directory only (Single tenant).
    • Leave redirect URI blank for now → Register.
  2. Go to Authentication (the portal may show this as Authentication (Preview)).

    • Open the Redirect URI configuration tab → click Add Redirect URI.
    • Set platform type to Mobile and desktop applications and enter http://localhost:8765 → Save.
  3. Still in Authentication, open the Settings tab.

    • Toggle Allow public client flows to Enabled → Save.
  4. Go to API permissions → Add a permission → APIs my organization uses. Search for the Omada app by name. If it does not appear in the list, paste its Application (client) ID directly into the search box — this always works. Choose Delegated permissions and select user_impersonationAdd permissions.

  5. Click Grant admin consent for your tenant. This is required because the Omada scope is restricted to admins-only consent. Both permissions (user_impersonation and User.Read) should show Granted status after this step.

  6. (Optional but recommended) In the Omada app registration → Expose an API → Authorized client applications, click Add a client application, paste the Client ID of the MCP client app, and select the user_impersonation scope. This pre-authorizes the client and prevents users from seeing a consent popup on first login.

  7. Go to the Overview page of the MCP client app and copy the Application (client) ID and Directory (tenant) ID into your .env file.

Automate with Azure CLI

All of the above can be scripted with az cli. Example to create the app and add the redirect URI:

# Create the app registration
az ad app create --display-name "omada-mcp-client" --public-client-redirect-uris "http://localhost:8765"

# Enable public client flows (fetch the app's object ID first)
OBJECT_ID=$(az ad app show --id <client-id> --query id -o tsv)
az rest --method PATCH \
  --uri "https://graph.microsoft.com/v1.0/applications/$OBJECT_ID" \
  --body '{"isFallbackPublicClient": true}'

# Add delegated API permission (requires the Omada app's client ID)
az ad app permission add \
  --id <mcp-client-id> \
  --api <omada-app-client-id> \
  --api-permissions <user_impersonation-scope-id>=Scope

# Grant admin consent
az ad app permission admin-consent --id <mcp-client-id>

Configuration

There are two ways to provide configuration — use whichever fits your setup:

Option A — env block in the MCP client config (recommended) Pass the variables directly in claude_desktop_config.json or .vscode/mcp.json (see MCP client configuration). No .env file needed.

Option B — .env file Useful when running server.py directly from the terminal or when running tests. Copy .env.example to .env and fill in your values:

OMADA_BASE_URL=https://your-instance.omada.cloud
TENANT_ID=your-azure-ad-tenant-id
CLIENT_ID=your-mcp-client-app-registration-client-id  # the MCP client app, NOT the Omada app

Only three variables are required. Everything else has a sensible default — the callback port defaults to 8765, GraphQL version to 3.0, caching is on. See .env.example for the full list of optional overrides.

MCP client configuration

Claude Desktop

Add to %APPDATA%\Claude\claude_desktop_config.json:

{
  "mcpServers": {
    "omada": {
      "command": "python",
      "args": ["C:\\path\\to\\omada-mcp-server\\server.py"],
      "env": {
        "OMADA_BASE_URL": "https://your-instance.omada.cloud",
        "TENANT_ID": "your-azure-ad-tenant-id",
        "CLIENT_ID": "your-mcp-client-app-registration-client-id"
      }
    }
  }
}

GitHub Copilot (VS Code)

Add to .vscode/mcp.json or user-level MCP config:

{
  "servers": {
    "omada": {
      "type": "stdio",
      "command": "python",
      "args": ["C:\\path\\to\\omada-mcp-server\\server.py"],
      "env": {
        "OMADA_BASE_URL": "https://your-instance.omada.cloud",
        "TENANT_ID": "your-azure-ad-tenant-id",
        "CLIENT_ID": "your-mcp-client-app-registration-client-id"
      }
    }
  }
}

First run

The first time the server is called, a browser window opens for login. After authenticating, the token is saved encrypted to .token_cache.bin (Windows DPAPI — only your Windows user can read it). Subsequent starts use the refresh token silently — no browser needed.

To force re-authentication, call the logout tool (or delete .token_cache.bin manually).

Available tools

Identity & resource queries (OData)

| Tool | Description | |---|---| | query_omada_identity | Query identities with field filters | | query_omada_resources | Query resources by type and system | | query_omada_entities | Generic query for any Omada entity type | | query_omada_entity | Advanced OData query with full filter/select/expand support | | get_all_omada_identities | Retrieve all identities with pagination | | query_calculated_assignments | Query calculated assignments for an identity |

Access requests (GraphQL)

| Tool | Description | |---|---| | get_access_requests | List access requests with optional filters | | create_access_request | Submit a new access request | | get_resources_for_beneficiary | Resources available for a specific identity | | get_requestable_resources | Alias for get_resources_for_beneficiary | | get_identities_for_beneficiary | Identities available as beneficiaries | | get_identity_contexts | Contexts assigned to a specific identity |

Approvals (GraphQL)

| Tool | Description | |---|---| | get_pending_approvals | List pending approval items (summary view) | | get_approval_details | Full approval details including technical IDs | | make_approval_decision | Approve or reject a pending item |

Assignments & compliance (GraphQL)

| Tool | Description | |---|---| | get_calculated_assignments_detailed | Detailed assignments with compliance status | | get_compliance_workbench_survey_and_compliance_status | Compliance workbench data |

Admin

| Tool | Description | |---|---| | ping | Health check | | check_omada_config | Show current server configuration | | logout | Clear stored tokens and force re-authentication on next call | | get_cache_stats | Cache hit/miss statistics | | clear_cache | Clear response cache | | view_cache_contents | List cached entries | | view_cache_contents_detailed | Detailed cache inspection | | get_cache_efficiency | Cache efficiency metrics |

Project structure

omada-mcp-server/
├── server.py            # Entry point — registers tools and starts server
├── auth.py              # OAuth 2.0 Auth Code + PKCE, DPAPI token cache
├── mcp_instance.py      # Shared FastMCP instance
├── exceptions.py        # Custom exception classes
├── logging_config.py    # Logging setup and per-function log level decorator
├── helpers.py           # Response builders and validation utilities
├── cache.py             # SQLite response cache (OmadaCache class)
├── cache_instance.py    # Shared cache singleton (import cache/CACHE_ENABLED from here)
├── cache_config.py      # Per-operation TTL configuration
├── completions.py       # MCP autocomplete suggestions
├── prompts.py           # MCP workflow prompt templates
├── api/
│   ├── odata.py         # OData client (filters, pagination, entity queries)
│   └── graphql.py       # GraphQL client (request builder, cache integration)
└── tools/
    ├── query.py          # OData query tools
    ├── access_requests.py # Access request tools
    ├── approvals.py      # Approval workflow tools
    ├── assignments.py    # Assignment and compliance tools
    └── admin.py          # Admin and cache management tools

Security

  • No client secret — PKCE public client flow, nothing to leak
  • Token encrypted at rest — on Windows, DPAPI ties encryption to your Windows user session; on macOS/Linux, the token cache falls back to a plain JSON file (.token_cache.bin) — ensure the file permissions on your system restrict access appropriately
  • Token never in LLM context — authentication is invisible to the AI model
  • Token never in tool responses — Bearer token is stripped before results are returned to the model
  • .env and .token_cache.bin excluded from git via .gitignore

API endpoints

| API | Endpoint | |---|---| | OData (built-in) | {OMADA_BASE_URL}/OData/BuiltIn/{EntityType} | | OData (data objects) | {OMADA_BASE_URL}/OData/DataObjects/{EntityType} | | GraphQL | {OMADA_BASE_URL}/api/Domain/{version} |

Logging

Logs go to both console and omada_mcp_server.log. Override log level per tool via environment variables:

LOG_LEVEL_get_pending_approvals=DEBUG
LOG_LEVEL_create_access_request=DEBUG

Dependency licenses

All direct runtime dependencies use permissive licenses compatible with evaluation use:

| Package | License | |---|---| | httpx | BSD-3-Clause | | fastmcp | Apache-2.0 | | mcp | MIT | | python-dotenv | BSD-3-Clause | | pywin32 (optional, Windows only) | PSF |

For commercial use or redistribution, verify transitive dependency licenses independently.

Quick Setup
Installation guide for this server

Install Package (if required)

uvx omada-mcp-server

Cursor configuration (mcp.json)

{ "mcpServers": { "omadaidentity-omada-mcp-server": { "command": "uvx", "args": [ "omada-mcp-server" ] } } }