MSPbotsAIFramework

duo-mcp

Community MSPbotsAIFramework
Updated

duo-mcp

MCP server for the Cisco Duo Admin API — Duo's multi-factor authenticationand zero-trust access platform. Built to cover MFA synchronization, userpre-enrollment, and enrollment validation (the capabilities this taskspecifically requested), and — per an explicit follow-up scope decision — thefull Admin API beyond that.

MSPbots Connector

The MCP Gateway built for MSPs: visible, controlled, and your data stays where it belongs.

Get started at connect.mspbots.ai →

MSPbots Connector gives your AI clients one MCP URL to reach your entire MSP stack (RMM, PSA, documentation, security, finance), and gives you control over who can call which tool and a record of everything that was called.

Hosted service: connect.mspbots.ai · Free to use.

Why Connector

MSPbots Connector

Visible Every tool call is logged: who, which vendor, when. Usage dashboard, CSV export, SIEM streaming.
Controlled Role-based, per-tool allowlist. Deny by default.
Protected Credentials encrypted per record. AI clients never see your vendor passwords or tokens.
MSP-native Built for the MSP stack only: RMM, PSA, documentation, security, finance.

Quick start

  1. Sign up at connect.mspbots.ai.
  2. Connect your vendors. Pick from 150+ connectors and authorize each one on the vendor's own page, or bring your own API keys. No extra vendor accounts needed.
  3. Set access. Create roles and decide which tools each role may call. Nothing is allowed until you allow it.
  4. Add your MCP URL to your AI client. Copy the URL from your Connector dashboard into Claude, ChatGPT, Cursor, VS Code, Gemini, Codex, or any MCP-capable client.
  5. Ask your AI to do real work, and watch every call appear in the audit log.

Features

Unified gateway

  • One MCP URL for all your AI clients
  • 150+ connectors across the MSP stack
  • Custom MCP servers supported, free
  • Authorization happens on each vendor's own page; the AI never sees passwords or tokens
  • Bring your own credentials: use the vendor API keys you already have
  • Multiple accounts per app; connect once, reuse across AI clients
  • Tool search: finds the right action for the task
  • One sign-in; vendor credentials are injected behind the scenes and OAuth tokens refresh automatically

Visibility

  • Audit log for every tool call (who, which vendor, when)
  • Usage dashboard: call volume, top vendors, error rate, per-user activity
  • Export audit logs to CSV, or stream to Loki, Graylog, or LogScale (SIEM)
  • Optional recording of tool arguments and result summaries (off by default, enabled per organization)

Control

  • Per-role, per-tool allowlist, deny by default
  • owner / admin / member roles
  • SCIM provisioning with Entra ID, Okta, JumpCloud, and Google Workspace

Security

  • Credentials encrypted one record at a time (AES-256-GCM, per-record key)
  • AI clients authenticate with OAuth 2.1 + PKCE
  • Vendor responses are scanned for prompt-injection patterns and returned as structured data. This is one layer of defense, not a guarantee against every attack.
  • Static egress IP for customer firewall and API allowlisting

Pricing

Free.

Links: connect.mspbots.ai · mspbots.ai

Overview

  • Stateless HTTP service. No credentials are ever persisted — each requestsupplies its own integration key/secret key/API host via headers, used onlyfor the lifetime of that single request.
  • Supports concurrent requests; per-request credential isolation is done viaPython contextvars, not a global/shared client instance.
  • Entry points: POST /mcp (MCP protocol) and GET /health (health check).
  • Default port: 8080 (configurable via MCP_HTTP_PORT).

Scope

28 tools, trimmed down from an original 160-tool full-Admin-API build(2026-08-04). Duo has no existing MSPbots integration to anchor scopeagainst — it was never previously configured in MSPbots' platform — sounlike other trimmed vendors in this program, "actual usage" was taken fromthe original ClickUp task's own stated requirement instead of a live APIconfig: MFA synchronization, user pre-enrollment, and enrollmentvalidation. Those 3 capabilities map to the users category almostentirely, plus the resource types a user's MFA methods reference:

  • MFA synchronization: duo_users_retrieve_users,duo_users_retrieve_user_by_id, duo_users_synchronize_user_from_directory,plus per-user MFA-method listing (retrieve_phones_by_user_id,retrieve_hardware_tokens_by_user_id,retrieve_web_authn_credentials_by_user_id, retrieve_groups_by_user_id)
  • User pre-enrollment: duo_users_create_user, duo_users_enroll_user,duo_users_associate_phone_with_user (+ disassociate),duo_users_associate_hardware_token_with_user,duo_users_associate_group_with_user, plus phone provisioning(duo_phones_create_phone, duo_phones_create_activation_code_via_sms)
  • Enrollment validation: duo_users_send_verification_push +duo_users_retrieve_verification_push_response

Plus core CRUD/list for the referenced resource types themselves —duo_users_modify_user, duo_users_delete_user,duo_users_create_bypass_codes_for_user, duo_phones_retrieve_phones,duo_phones_retrieve_phone_by_id, duo_tokens_retrieve_hardware_tokens,duo_tokens_retrieve_hardware_token_by_id,duo_webauthn_credentials_retrieve_web_authn_credentials (+ _by_key),duo_groups_retrieve_groups, duo_groups_get_group_info.

Everything else from the original 160-tool build — Desktop Authenticators, Bypass Codes (standalone category; the per-user variantunder users was kept), Integrations, Policies, Endpoints,Registered Devices, Passport, Administrators, Administrative Units,Logs, Trust Monitor, Settings, Custom Branding, Account Info,Bulk Operations (15 categories, ~132 tools) — was removed as unrelated tothe original task's 3 stated capabilities.

No official Duo MCP exists — searched GitHub (duo-mcp, "duosecurity" mcp) and both wyre-technology/MSPbotsAI orgs before building; the onlyexisting "Duo + MCP" material is Duo SSO for MCP,which is the reverse relationship (Duo as an identity provider protectingMCP servers), not a Duo Admin API MCP server.

Source data for the kept tools was originally extracted from Duo's ownofficial Postman collection(https://github.com/duosecurity/duo_postman_collection, duo-admin-apifolder), cross-referenced against the live duo.com/docs/adminapidocumentation. If a removed category is needed later, that same source canbe re-parsed the same way.

Authentication

Duo Admin API auth is not a simple bearer token — every request isindividually signed with HMAC-SHA512 (Duo's "sig_version 5") using anIntegration Key (ikey) and Secret Key (skey). This server implementsthat signing logic itself (ported line-for-line from Duo's ownreference Python clientand verified byte-for-byte identical against that referenceimplementation for both GET-style query-signed requests and POST-styleJSON-body-signed requests, including special-character percent-encoding) —callers only need to supply the raw ikey/skey/host per request; this servercomputes the canonical string, HMAC, and Authorization: Basic header onevery call.

Per Duo's own signing convention: GET/DELETE requests sign and sendparams as a url-encoded query string; POST/PUT/PATCH requests sign andsend params as a single JSON object request body. Tools in this server don'tneed to know which — the client picks the correct transport based on theHTTP method automatically, exactly matching the reference implementation'sbehavior.

HEADER authentication parameters

Header Type Required Default Allowed values Description Example
X-Duo-Ikey string Yes None None Integration Key of the Duo Admin API integration (used as the Basic Auth username part of the HMAC signature) X-Duo-Ikey: DIABCDEFGHIJ1234567K
X-Duo-Skey string Yes None None Secret Key of the Duo Admin API integration (HMAC-SHA512 signing key, used only to compute the signature for the current request, never stored on disk) X-Duo-Skey: 1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b
X-Duo-Api-Host string Yes None None The Admin API host of this Duo account (each account has its own subdomain, such as api-xxxxxxxx.duosecurity.com); no protocol prefix needed X-Duo-Api-Host: api-12345678.duosecurity.com

Missing any header returns 401:

{
  "error": "Missing credentials",
  "message": "This server requires the X-Duo-Ikey, X-Duo-Skey, and X-Duo-Api-Host headers",
  "required_headers": ["X-Duo-Ikey", "X-Duo-Skey", "X-Duo-Api-Host"],
  "optional_headers": []
}

Environment Variables

Variable Type Required Default Description
MCP_HTTP_PORT int No 8080 HTTP listen port
MCP_HTTP_HOST string No 0.0.0.0 HTTP listen address

MCP Endpoint

  • POST /mcp — MCP protocol (streamable HTTP transport)
  • GET /health — health check, returns {"status": "ok"} (local-only probe, does not call Duo)

Tool List

Tool names are duo_<category>_<operation>, derived from each operation'sname in Duo's official Postman collection. body parameters (for endpointswhose payload is a nested/complex JSON object rather than flat scalarfields, e.g. bulk operations, SSO integration config, policy sections) areaccepted as a generic dict — the docstring lists the top-level keys fromDuo's own example, and the full schema is in the linked API reference.

The 3 capabilities this task specifically named map to these tools:

  • MFA synchronization: duo_users_retrieve_users, duo_users_synchronize_user_from_directory
  • User pre-enrollment: duo_users_create_user, duo_users_enroll_user
  • Enrollment validation: duo_users_send_verification_push + duo_users_retrieve_verification_push_response
Category Tool Description Method + Path Params
groups duo_groups_get_group_info Get Group Info. GET /admin/v2/groups/{group_id} group_id(required)
groups duo_groups_retrieve_groups Retrieve Groups. GET /admin/v1/groups limit(optional), offset(optional)
phones duo_phones_create_activation_code_via_sms Create Activation Code via SMS. POST /admin/v1/phones/{phone_id}/send_sms_activation phone_id(required), valid_secs(optional), install(optional), installation_msg(optional), activation_msg(optional)
phones duo_phones_create_phone Create Phone. POST /admin/v1/phones none
phones duo_phones_retrieve_phone_by_id Retrieve Phone by ID. GET /admin/v1/phones/{phone_id} phone_id(required)
phones duo_phones_retrieve_phones Retrieve Phones. GET /admin/v1/phones number(optional), extension(optional), limit(optional), offset(optional)
tokens duo_tokens_retrieve_hardware_token_by_id Retrieve Hardware Token by ID. GET /admin/v1/tokens/{token_id} token_id(required)
tokens duo_tokens_retrieve_hardware_tokens Retrieve Hardware Tokens. GET /admin/v1/tokens type(optional), serial(optional), limit(optional), offset(optional)
users duo_users_associate_group_with_user Associate Group with User. POST /admin/v1/users/{user_id}/groups user_id(required), group_id(required)
users duo_users_associate_hardware_token_with_user Associate Hardware Token with User. POST /admin/v1/users/{user_id}/tokens user_id(required), token_id(required)
users duo_users_associate_phone_with_user Associate Phone with User. POST /admin/v1/users/{user_id}/phones user_id(required), phone_id(required)
users duo_users_create_bypass_codes_for_user Create Bypass Codes for User. POST /admin/v1/users/{user_id}/bypass_codes user_id(required), count(optional), codes(optional), reuse_count(optional), valid_secs(optional)
users duo_users_create_user Create User. POST /admin/v1/users username(required), aliases(optional), realname(optional), email(optional), status(optional), notes(optional), firstname(optional), lastname(optional)
users duo_users_delete_user Delete User. DELETE /admin/v1/users/{user_id} user_id(required)
users duo_users_disassociate_phone_from_user Disassociate Phone from User. DELETE /admin/v1/users/{user_id}/phones/{phone_id} user_id(required), phone_id(required)
users duo_users_enroll_user Enroll User. POST /admin/v1/users/enroll username(required), email(required), valid_secs(optional)
users duo_users_modify_user Modify User. POST /admin/v1/users/{user_id} user_id(required), username(optional), aliases(optional), realname(optional), email(optional), status(optional), notes(optional), firstname(optional), lastname(optional)
users duo_users_retrieve_groups_by_user_id Retrieve Groups by User ID. GET /admin/v1/users/{user_id}/groups user_id(required), limit(optional), offset(optional)
users duo_users_retrieve_hardware_tokens_by_user_id Retrieve Hardware Tokens by User ID. GET /admin/v1/users/{user_id}/tokens user_id(required), limit(optional), offset(optional)
users duo_users_retrieve_phones_by_user_id Retrieve Phones by User ID. GET /admin/v1/users/{user_id}/phones user_id(required), limit(optional), offset(optional)
users duo_users_retrieve_user_by_id Retrieve User by ID. GET /admin/v1/users/{user_id} user_id(required)
users duo_users_retrieve_users Retrieve Users. GET /admin/v1/users username(optional), limit(optional), offset(optional)
users duo_users_retrieve_verification_push_response Retrieve Verification Push Response. GET /admin/v1/users/{user_id}/verification_push_response user_id(required), push_id(required)
users duo_users_retrieve_web_authn_credentials_by_user_id Retrieve WebAuthn Credentials by User ID. GET /admin/v1/users/{user_id}/webauthncredentials user_id(required)
users duo_users_send_verification_push Send Verification Push. POST /admin/v1/users/{user_id}/send_verification_push user_id(required), phone_id(required)
users duo_users_synchronize_user_from_directory Synchronize User from Directory. POST /admin/v1/users/directorysync/{directory_key}/syncuser directory_key(required), username(required)
webauthn_credentials duo_webauthn_credentials_retrieve_web_authn_credentials Retrieve WebAuthn Credentials. GET /admin/v1/webauthncredentials limit(optional), offset(optional)
webauthn_credentials duo_webauthn_credentials_retrieve_web_authn_credentials_by_key Retrieve WebAuthn Credentials by Key. GET /admin/v1/webauthncredentials/[webauthnkey] webauthnkey(required)

Test Example

# Health check
curl -s http://localhost:8080/health

# Call a tool via the MCP protocol (streamable HTTP) — requires an
# initialize handshake first per the MCP spec; abbreviated example below
# shows the tool-call request body only:
curl -s -X POST http://localhost:8080/mcp \
  -H "X-Duo-Ikey: <your-integration-key>" \
  -H "X-Duo-Skey: <your-secret-key>" \
  -H "X-Duo-Api-Host: api-xxxxxxxx.duosecurity.com" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "mcp-session-id: <session-id-from-initialize>" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "duo_users_retrieve_users",
      "arguments": {"limit": "5"}
    }
  }'

Signing correctness verified independently of any live account: thisserver's HMAC-SHA512 request-signing implementation was directly compared,side-by-side in the same Python process, against Duo's own officialreference client (duo_client_python) — the canonical string, the fullAuthorization: Basic header, and percent-encoding of special characterswere all confirmed byte-for-byte identical for both a GET (query-signed) anda POST (JSON-body-signed) scenario. Structural checks were also completed:MCP handshake, tools/list returning all 160 registered tools, and 401credential-gating with placeholder header values.

Live self-test against a real Duo account: passed. Using a real Admin APIintegration created in a live Duo account, three calls were made through therunning MCP server end-to-end (real HTTP requests toapi-4d02a5dd.duosecurity.com, real HMAC-SHA512 signing, real responseparsing):

  • duo_administrators_retrieve_administrators → returned the real accountowner ([email protected], role Owner, an enrolled iPhone with pushcapability).
  • duo_integrations_retrieve_integrations → returned the Admin APIintegration itself, with integration_key matching the ikey used toauthenticate — direct proof the signature was accepted by Duo.
  • duo_users_retrieve_users → returned []. Cross-checked against the twocalls above (not assumed): since both other calls returned real,non-empty data through the identical auth/parsing path, the empty arrayreflects a genuinely fresh account with zero enrolled end users yet, nota masked auth failure.

API Reference

Known Gaps

  • Trimmed from 160 to 28 tools on 2026-08-04. The original buildcovered the full public Admin API per an earlier follow-up scopedecision (justified at the time by there being no MSPbots-existingintegration to anchor a narrower scope against). A later scope decisioncut this back to the original ClickUp task's actual 3 statedcapabilities (MFA sync / pre-enrollment / enrollment validation) plusminimal supporting CRUD — see the Scope section above for the exactmapping and the full list of the 15 removed categories (~132 tools). Ifa removed category is needed later, Duo's own Postman collection (linkedbelow) still documents its exact operations and they can be re-added thesame way the kept tools were generated.
  • Several kept tools still mutate real Duo account data(duo_users_create_user, duo_users_delete_user,duo_users_enroll_user, duo_phones_create_phone, etc.) — treat theseas state-changing and confirm with a human before invoking.
  • body parameters are untyped (dict) where a tool has a nested/complex JSON payload — each such tool's docstring lists the top-levelkeys from Duo's own example payload; the full schema is in the linkedAPI reference.
  • Live functional self-test passed (pre-trim) against a real Duoaccount — administrators and integrations endpoints returned real data;the users endpoint correctly returned an empty list for this account'scurrent (zero end-user) state. Not independently re-verified against thelive API after the trim, though the trim only removed tools/files andchanged no request-building logic for the ones kept.

MCP Server · Populars

MCP Server · New

    bex-co

    Beancount.io Backend

    💰 Double-entry bookkeeping made easy — plain-text accounting for humans and AI agents. Polished iOS & Android app built with React Native + Expo.

    Community bex-co
    nkapila6

    mcpsurfr

    Local web search MCP server, formerly mcp-local-rag. Multi-engine deep research with on-device re-ranking. ✨ no API keys ✨

    Community nkapila6
    convex

    mcp.ts

    The open-source reactive database for app developers

    Community convex
    convex

    convex-backend

    The open-source reactive database for app developers

    Community convex
    Tripo-Developer

    Tripo MCP Server

    Official MCP server for Tripo

    Community Tripo-Developer