# Nomid MDM MCP server

> Instructions for AI agents that manage a company's Android and VR devices through Nomid MDM, including setting up kiosk mode on tablets. Human-readable documentation: https://www.nomidmdm.com/en/developers/mcp

## Connect

- Endpoint: `https://api.nomid.tech/emm/api/mcp` (MCP Streamable HTTP, stateless).
- A person creates the Nomid account and company (https://www.nomidmdm.com/en/signup). You cannot create accounts.
- Sign in with Nomid (OAuth 2.1): add the endpoint as a remote MCP server or connector and sign in. Works with claude.ai, ChatGPT and Claude Code. You act as the signed-in user, within their role, their policy scope and the scopes they granted: `mcp:read`, `mcp:devices:command`, `mcp:devices:destructive`, `mcp:provisioning`, `mcp:policies:write`. Clients that follow the server's sign-in challenge ask for `mcp:read`, `mcp:devices:command` and `mcp:provisioning`; a client that sends no scope gets `mcp:read` only; `mcp:devices:destructive` and `mcp:policies:write` must be requested explicitly. The user can untick scopes on the consent page, and Nomid drops what their role or the company's settings do not allow. Policy changes and provisioning also need the company to allow them for agents.
- API key: send `Authorization: Bearer <key>` or `X-API-Key: <key>`. The key's permissions decide which tools work. Never print a key.
- Each tool needs its own permission on the key or connection, and a refusal names it. Tell the user which permission is missing; do not work around it.
- Companies: an API key, or a connection made for one company, works only in that company. A connection made with "All companies I manage" reaches every company the user manages. `list_companies` lists what the connection reaches, and every other tool takes an optional `company` argument with a `company` value from that list; without it a tool runs in the connection's own company. Naming a company out of reach is a tool error.
- REST equivalents of most tools live under `https://api.nomid.tech/emm/api/v1`: https://www.nomidmdm.com/en/developers/api-reference

## Rules

1. Read before you act. Find devices with `search_devices` (use `query` for a name or serial number) and confirm you have the right one before any command. Answer fleet questions with `count_devices` or `get_fleet_summary`, not by paging devices.
2. Commands act on real, physical devices right away. Say what you will do to which devices, naming how many, and get the user's yes before calling `send_device_command`. For several devices make one call with `assetIds` (up to 50) or `devicesInPolicy`, never one call per device.
3. `send_destructive_command` (wipe, screen lock reset or change, relinquish ownership, uninstall apps, clear app data) cannot be undone and Nomid has no approval step for it: tell the user exactly what happens to which device and get an explicit yes first. Never pick a screen lock password yourself.
4. Policy changes are proposals. Read the policy, propose with `propose_policy_change`, `create_policy` or `rollback_policy`, show the user the change list from the proposal, get their approval, then call `apply_policy_proposal`. The proposal's `impact` decides the rest. `NORMAL`: the apply goes through. Nomid cannot verify that the user approved in the conversation, so never apply without asking: the rating only limits how far a change without a person's click can reach. `HIGH` (`requiresPortalApproval` is true; `requiresConfirmation` is a deprecated alias): do not call the apply, which is refused and changes nothing. Give the user the proposal's `approvalUrl` and ask them to approve it in the Nomid portal, after a sign-in at most 10 minutes old. Then read the outcome with `get_policy_proposal`. `confirmation` is ignored. A policy proposal expires after 24 hours; on `stale_proposal`, read the policy again and propose again. Rating: a policy with no devices is NORMAL, except a rollback that restores sections outside the settings catalogue (networks, certificates, kiosk), which is HIGH. Cosmetic changes (messages, display, sound) are NORMAL up to 49 devices. Ordinary changes (settings not flagged risky, adding an app or changing how it installs, unless that blocks it, a third-party app's managed configuration) are NORMAL up to 5 devices. Risky changes are HIGH from 1 device: unknown sources, Play Protect, factory reset, developer options, USB data, encryption, removing or blocking an app, the home screen, a rollback, any other policy edit, and the configuration of the Nomid Settings agent or a secure web app. With 50 or more devices all of these are HIGH. A policy's description, tags and group do not affect devices, so changing them is always NORMAL. Apply an `apps` proposal before proposing a `homeScreen` change that uses those apps.
5. A command answering `UNCONFIRMED` may still have run. Check `list_device_commands` before resending, and never resend without asking the user. On several devices, only the devices in `retryAssetIds` are safe to send again.
6. On a rate limit, wait before trying again: over REST, a 429 with `Retry-After`; over MCP, a tool error saying "Rate limit exceeded ... Retry after N second(s)". Wait that long, and do not loop. A command to several devices costs one unit of the write limit per started group of 5 devices (a call on 50 costs the whole minute) and is refused whole when it does not fit, so send fewer devices or wait. Destructive commands that need `DEVICES_COMMAND_DESTRUCTIVE` also have a limit of 5 per hour per key or connection.
7. When something does not work, call `diagnose` before guessing a cause. Give the user the `portalUrl` of devices and policies you mention, or a link from `get_portal_link`.
8. Create a provisioning QR code only when the user asks for one. Each call creates a live enrollment token valid for 24 hours, and the image can carry the Wi-Fi password: give it only to the user who asked, never repeat the token or password in text, and do not create extra codes "just in case".
9. Never invent secrets or identifiers: a kiosk maintenance password, a Wi-Fi password, a screen lock password, or a package name. Ask the user.
10. A result with `resultTrimmed` lists only the first items: say so and narrow the call.
11. Prices from `search_nomid_site` are public list prices. For the company's own plan use `get_company_plan`; for invoices point the user to Billing in the portal.

## Tools

The server offers one tool per kind of action. Device commands, policy changes and diagnosis are chosen by an argument of a shared tool (`command`, a policy part, `area`).

### Read

- `search_devices` (`DEVICES_READ`): Page through devices, filtered by status, policy, `lastSyncBefore` (the portal's Last sync: use it for devices not seen or offline since a date), `lastSeenBefore` or `missing` (no IMEI or serial number). To find a device the user names, pass only `query` (name, serial number, IMEI, model or tag). `fields: "names"` returns a compact table.
- `count_devices` (`DEVICES_READ`): Count devices with the same filters as search_devices; `groupBy` (`policy`, `model`, `status`) gives an exact breakdown.
- `get_device` (`DEVICES_READ`): Full detail of one device by its assetId: status, policy, battery, hardware, location, non-compliance reasons.
- `get_fleet_summary` (`DEVICES_READ`): Total devices, a status breakdown and the security posture. Never a device list.
- `list_device_commands` (`DEVICES_READ`): The latest commands sent to a device, their outcome and who sent them. Check it before resending a command whose outcome was unknown.
- `list_device_apps` (`DEVICES_READ`): The apps a device last reported: package name, name, version, state and who installed them. `query` matches package and name.
- `list_device_user_logins` (`DEVICES_READ`): Who logged in on which device, newest first: the device user (`PIN`, `SSO`, or `EXTERNAL` for a user the customer's own system signs in), the asset, `loginAt`/`logoutAt`/`expiresAt`, `open`, and who reported the login and the logout (`DEVICE`, `API`, `EXPIRY`). Filter by `assetId` or `serialNumber`, `deviceUserId` or `externalUserId`, `open`, and `from`/`to`; `limit` defaults to 50, at most 200. Use it for "who is using this device".
- `list_companies` (`DEVICES_READ` or `POLICIES_READ`): The companies this connection can work in, with device counts. Needed only when it reaches more than one; every other tool then takes an optional `company` argument (a value from this list).
- `list_policies` (`POLICIES_READ`): Every policy with its device count; `query` keeps policies whose name or path name contains it.
- `get_policy_settings` (`POLICIES_READ`): The editable settings of a policy with current and allowed values, its apps (package name, name, source, install type, and `managedByNomid` for apps you cannot change) and its current `homeScreen` mode. Read it before proposing a change.
- `get_policy_document` (`POLICIES_READ`): A policy's full configuration as JSON, or the part at `path`, a JSON Pointer (an app by package name: `/apps/com.example.app`; kiosk controls: `/kioskCustomization`). Secrets, and every value of an app's managed configuration, read as `{"redacted": true}`. Without a path, apps are summarized. `lockedFields` lists what edits refuse and why; a part over 30,000 characters returns `fieldSizes` instead: read a narrower path. Read it before proposing edits.
- `list_policy_revisions` (`POLICIES_READ`): A policy's saved revisions, newest first, for rollback_policy.
- `get_policy_proposal` (`POLICIES_READ`): The current state of a policy change proposal you made.
- `find_app` (`POLICIES_READ`): Where one app is: in a policy (`policyId`), the company's library, Google Play (by package name only) and a device (`assetId`). `query` is a package name, a Play Store link or part of an app name. The `answer` says whether the app can be added and how. Use it before adding an app to a policy.
- `search_library` (`POLICIES_READ`): The company's Nomid library: published private apps (`kind: "apps"`, the default) or the VR library's web links (`kind: "links"`). Not Google Play and not a policy's apps.
- `get_company_plan` (`DEVICES_READ`): The company's own plan, billable device count and device limit. No prices or invoices: point the user to Billing in the portal. With Sign in with Nomid, the user's role also needs to see billing.
- `diagnose` (`DEVICES_READ` or `POLICIES_READ`): Diagnose one problem in one call. `area: "remote_access"` or `"policy_sync"` with `assetId` explains why a device cannot be reached or is not applying its policy. `area: "enrollment"` with `policyId` and/or `serialNumber` explains why Android devices fail to enroll with a QR code (Wi-Fi first), and lists what only the person holding the device can check. Returns likely causes with evidence and next steps.
- `get_portal_link` (`DEVICES_READ` or `POLICIES_READ`): The Nomid portal URL of a device (`kind: "asset"`), policy, library app or portal page (for example `android_enterprise`, `enroll`, `billing`), to give the user a page to open.
- `search_nomid_site` (`DEVICES_READ` or `POLICIES_READ`): Public plans and list prices from www.nomidmdm.com. These are list prices, not the company's own contract.
- `read_flagged_chats` (`DEVICES_READ`): Nomid staff only (system administrators signed in with Sign in with Nomid). Customers never get it.

### Device commands

Also need the company's device commands setting (Sign in with Nomid).

- `send_device_command` (`DEVICES_COMMAND` + `DEVICES_READ`): Run a reversible command on a real device now. `command` is one of `lock_device`, `start_lost_mode`, `stop_lost_mode`, `send_device_message`, `request_status_report`, `force_location_update`, `sync_policy`, `reboot_device`, `shutdown_device`, `launch_app`, `change_device_policy`, plus that command's own arguments. Pass exactly one target: `assetId`, `assetIds` (up to 50) or `devicesInPolicy` (at most 50). A device that cannot take the command does not stop the others: the result lists each device's outcome (`SENT`, `NOT_SENT`, `UNCONFIRMED`, `FAILED`), and `retryAssetIds` lists the `NOT_SENT` devices, which are safe to send again. `lock_device` and lost mode need an Android Management device; `sync_policy`, `shutdown_device` and `launch_app` a Nomid agent (AOSP) device. `change_device_policy` also needs POLICIES_READ.

### Destructive device commands

Also needs the company's destructive commands setting (`clear_app_data`: with Sign in with Nomid, its device commands setting).

- `send_destructive_command` (`DEVICES_COMMAND_DESTRUCTIVE` + `DEVICES_READ`): Run a command that cannot be undone, on one device (`assetId`); these never go to several devices at once. `command` is `wipe_device` (factory reset a company-owned device, or remove the work profile from a personally owned one), `reset_screen_lock`, `change_screen_lock_password` (a password the user gave), `relinquish_ownership`, `uninstall_apps` or `clear_app_data` (up to 20 packages). Nomid has no approval step for these. `uninstall_apps` needs a Nomid agent (AOSP or PICO) device on agent 4.5.20 or later and runs when the device next checks in, even days later: follow it with list_device_commands; an app its policy installs comes back on the next sync. `clear_app_data` and the screen lock commands need an Android Management device. `clear_app_data` needs only DEVICES_COMMAND.

### Policy changes

Also need the company's policy changes setting.

- `propose_policy_change` (`POLICIES_WRITE` + `POLICIES_READ`): Propose one change to an existing policy: `policyId` plus exactly one part (`settings`, `apps`, `homeScreen`, `details`, `edits`); for several kinds of change, call it once per part. Nothing changes until the proposal is applied. `settings`: the settings get_policy_settings lists. `apps`: up to 20 changes: `ADD` a Google Play or Nomid Store app by `packageName` (a Play Store link works too), `ADD_WEB_APP` a Nomid secure web app for a `url` (optional `title`, at most 50 characters), `REMOVE`, or `SET_INSTALL_TYPE` (`FORCE_INSTALLED`, `AVAILABLE`, `BLOCKED`). Ask the user for a package name rather than guessing. Nomid's own apps cannot be changed here. `homeScreen`: kiosk mode and the home screen (see Kiosk mode below). `details`: description, tags and policy group. `edits`: up to 30 JSON Pointer edits (`{"op": "SET" | "REMOVE", "path", "value"}`) of the get_policy_document document: Wi-Fi networks, password rules, restrictions, system updates, launcher look, fences, kiosk controls at `/kioskCustomization`, an app's managed configuration. To add a Wi-Fi network use the password the user gave you; never invent one. Removing or blocking an app, or most edits and home screen changes on a policy with devices, are HIGH impact.
- `create_policy` (`POLICIES_WRITE` + `POLICIES_READ`): Propose a new policy. When the user names no policy to copy, create it from scratch; do not pick one for them. With `fromPolicyId` it copies that policy; without it the policy starts from Nomid defaults (the Nomid Settings agent, device reporting, Play Protect enforced, the standard Android home screen, no other apps). A new policy has no devices, so its changes are not high impact. Add apps and the kiosk home screen with propose_policy_change.
- `rollback_policy` (`POLICIES_WRITE` + `POLICIES_READ`): Propose restoring a policy to one of its revisions (from list_policy_revisions). HIGH impact on a policy with devices.
- `apply_policy_proposal` (`POLICIES_WRITE` + `POLICIES_READ`): Apply a proposal after the user approved its change list. A `NORMAL` proposal applies once the user approved. A `HIGH` one is refused with an `approvalUrl` for a person to approve in the Nomid portal; read the outcome with `get_policy_proposal`.

### Provisioning

With Sign in with Nomid, also needs the company's provisioning setting.

- `create_provisioning_qr_code` (`PROVISIONING` + `POLICIES_READ`): A QR code that enrolls a new or factory-reset Android device with a policy (`policyId`; optional `personalUsage`: `ALLOWED` work profile, `DISALLOWED` fully managed, `USERLESS` dedicated device, and Wi-Fi fields `wifiSsid`, `wifiPassword`, `wifiSecurity`, `wifiHidden`). Call it only when the user asks for a code (rule 8). Each call creates an enrollment token valid for 24 hours; the image goes to the user directly. VR-only policies cannot use it.

## Kiosk mode

Kiosk setup is supported end to end: https://www.nomidmdm.com/en/features/kiosk-mode. Use the `homeScreen` part of `propose_policy_change` with `policyId` and:

- `mode`: `STANDARD`, `NOMID_LAUNCHER`, `KIOSK_MULTI_APP`, `KIOSK_SINGLE_APP`. `STANDARD` is the device's own home screen, `NOMID_LAUNCHER` the Nomid launcher, `KIOSK_MULTI_APP` Nomid Kiosk locked to a launcher of the policy's apps, `KIOSK_SINGLE_APP` locked to one app.
- `kioskApp`: the package name, for `KIOSK_SINGLE_APP`. It must already be in the policy (add it first with the `apps` part and apply that). Nomid Settings cannot be the single app.
- `maintenancePassword`: required for `KIOSK_SINGLE_APP`, 6 to 64 characters. The user must give it; never invent or repeat it. It is not shown back.
- `dock`: up to 6 policy apps pinned to the launcher (launcher and multi-app only).
- `addSystemApps` / `removeSystemApps`: `PHONE`, `CONTACTS`, `CAMERA`, `MESSAGES`, `SETTINGS`, `BROWSER`; `NOMID_LAUNCHER` only, not Nomid Kiosk.

Switching changes the agent's install type, the home activity and the kiosk keys together, and is always HIGH impact on a policy with devices, so a person approves it in the Nomid portal. On a new policy with no devices it is NORMAL. Once in kiosk, the status bar, navigation buttons, power button and device settings are edited with the `edits` part at `/kioskCustomization`; read it with `get_policy_document` first. `get_policy_settings` and `get_policy_document` report the current mode as `homeScreen`.

Recipe: create or pick a policy, add apps (`find_app`, `apps` part, apply), `homeScreen` part (apply), `create_provisioning_qr_code` with `personalUsage: "USERLESS"` for dedicated tablets, then enroll: a new or factory-reset tablet, tap the welcome screen of the setup wizard six times, connect to Wi-Fi if asked, scan the code. Verify with `search_devices`, `get_device` and `diagnose`; undo with `rollback_policy`. The step-by-step version is the `nomid-kiosk-setup` skill: https://www.nomidmdm.com/.well-known/agent-skills/nomid-kiosk-setup/SKILL.md

## Not available

Starting remote access sessions, listing or revoking enrollment tokens, creating zero-touch or Knox Mobile Enrollment configurations, and changing Nomid's own apps (the Nomid Settings agent and the inventory, geolocation, store and remote access apps). Fields that `get_policy_document` lists in `lockedFields` (what Nomid sets itself, and VR settings other than the environment id) cannot be edited. Device User logins and logouts are reported by the customer's own system over REST (`POST /device-user-logins`, permission `DEVICES_COMMAND`); no tool reports them. Send the user to the portal for these (`get_portal_link`).

## More

- MCP setup and troubleshooting: https://www.nomidmdm.com/en/developers/mcp
- Capability summary for agents: https://www.nomidmdm.com/skill.md
- Agent skills index: https://www.nomidmdm.com/.well-known/agent-skills/index.json
- Whole-site text for agents: https://www.nomidmdm.com/llms-full.txt
- Permissions: https://www.nomidmdm.com/en/developers/api-reference/authentication
- Device commands: https://www.nomidmdm.com/en/developers/api-reference/commands
- Policy changes: https://www.nomidmdm.com/en/developers/api-reference/policy-changes
- Provisioning QR codes: https://www.nomidmdm.com/en/developers/api-reference/provisioning-qr-codes
- Android enrollment: https://www.nomidmdm.com/en/features/enrollment
- Device User sessions: https://www.nomidmdm.com/en/developers/api-reference/device-user-sessions
