npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

soti-mcp

v0.1.0

Published

Model Context Protocol server for SOTI MobiControl — operate Android/iOS/Windows/rugged MDM fleets with AI agents (Claude Code, Cursor, Cline, Continue).

Readme

soti-mcp

Operate your SOTI MobiControl MDM fleet from any AI agent — Claude Code, Cursor, Cline, Continue. A Model Context Protocol (MCP) server that wraps the SOTI MobiControl REST API as a clean tool surface so an LLM can list, search, command, and reshape your Android / iOS / Windows / rugged device estate via natural language.

30-second demo

Note: A scripted GIF will be added in v0.2. In the meantime, here is the kind of dialogue this server enables:

You: "Show me devices in the field group with battery below 30% that haven't checked in for 6 hours."

Claude (calls soti_search_devices): Found 4 devices: device-a, device-b, …

You: "Lock down device-a in kiosk mode."

Claude (calls soti_lockdown_device): Dispatched EnableKioskMode to device-a.

Install

Per-project (recommended for MCP clients):

npm install --save-dev soti-mcp

Globally (for direct CLI use):

npm install -g soti-mcp

This package ships an executable soti-mcp binary that speaks MCP over stdio out of the box.

Configure your AI client

Claude Code

Add to your project's .mcp.json (or your user-level ~/.claude.json):

{
  "mcpServers": {
    "soti": {
      "command": "soti-mcp",
      "env": {
        "SOTI_MC_BASE_URL": "https://mc.example.com/MobiControl",
        "SOTI_MC_CLIENT_ID": "your-client-id",
        "SOTI_MC_CLIENT_SECRET": "your-client-secret"
      }
    }
  }
}

Cursor

~/.cursor/mcp.json (or workspace-level .cursor/mcp.json):

{
  "mcpServers": {
    "soti": {
      "command": "soti-mcp",
      "env": {
        "SOTI_MC_BASE_URL": "https://mc.example.com/MobiControl",
        "SOTI_MC_CLIENT_ID": "your-client-id",
        "SOTI_MC_CLIENT_SECRET": "your-client-secret"
      }
    }
  }
}

Cline

In your VS Code settings.json:

{
  "cline.mcpServers": {
    "soti": {
      "command": "soti-mcp",
      "env": {
        "SOTI_MC_BASE_URL": "https://mc.example.com/MobiControl",
        "SOTI_MC_CLIENT_ID": "your-client-id",
        "SOTI_MC_CLIENT_SECRET": "your-client-secret"
      }
    }
  }
}

Continue

~/.continue/config.json:

{
  "experimental": {
    "modelContextProtocolServers": [
      {
        "transport": {
          "type": "stdio",
          "command": "soti-mcp",
          "env": {
            "SOTI_MC_BASE_URL": "https://mc.example.com/MobiControl",
            "SOTI_MC_CLIENT_ID": "your-client-id",
            "SOTI_MC_CLIENT_SECRET": "your-client-secret"
          }
        }
      }
    ]
  }
}

HTTP / SSE transport (remote consumers)

Set SOTI_MCP_HTTP_HOST and SOTI_MCP_HTTP_PORT to expose the server over Streamable HTTP. Useful for hosting the MCP server in your platform stack.

SOTI_MCP_HTTP_HOST=0.0.0.0 SOTI_MCP_HTTP_PORT=8765 soti-mcp

Tool reference

| Tool | Kind | Purpose | |---|---|---| | soti_list_devices | Read | Paginated device list, optionally filtered by group path or property filter. | | soti_get_device | Read | Full details for a single device by ID, MAC, or IMEI. | | soti_search_devices | Read | Advanced filter search (CONTAINS, =, !=, >, <, AND, OR). | | soti_get_device_location | Read | Last known GPS / cellular fix for a device. | | soti_get_device_apps | Read | Installed application list, paginated and orderable. | | soti_list_groups | Read | Device group hierarchy. | | soti_get_group_devices | Read | Members of a device group, recursing into subgroups. | | soti_list_policies | Read | Configuration profiles (SOTI calls these profiles). | | soti_list_alerts | Read | Active compliance / alert policies. | | soti_get_compliance_report | Read | Compliance status for a device, group, or fleet. | | soti_send_command | Action | Generic device action (CheckIn, Lock, Locate, RemoteRing, …). | | soti_install_app | Action | Install a managed application on a device. | | soti_uninstall_app | Action | Uninstall a managed application from a device. | | soti_lockdown_device | Action | Enable kiosk lockdown. | | soti_release_device | Action | Release kiosk lockdown. | | soti_wipe_device | DESTRUCTIVE | Factory-reset / wipe. Requires confirm: true. | | soti_assign_policy | Action | Assign a profile to groups, devices, or a filter expression. | | soti_move_device | Action | Move a device to another group. |

Resources

| URI Template | Returns | |---|---| | soti://device/{id} | Full JSON snapshot of one device. | | soti://group/{path}/devices | Devices that belong to a group (recurses into subgroups). | | soti://compliance/report/{date} | Compliance roll-up snapshot. |

Tool result envelope

Every tool returns a JSON object in this shape:

{
  "ok": true,
  "data": [ … ],
  "nextCursor": "…optional opaque cursor…"
}

…or, on failure:

{
  "ok": false,
  "error": {
    "code": "DEVICE_NOT_FOUND",
    "message": "Device not found (GET /devices/abc)",
    "hint": "Verify the device ID, or use mac:/imei_meid_esn: prefix.",
    "upstreamStatus": 404
  }
}

Error codes form a stable taxonomy: AUTH_FAILED, DEVICE_NOT_FOUND, RATE_LIMITED, PERMISSION_DENIED, INVALID_PARAMS, UPSTREAM_ERROR, NETWORK_ERROR, NOT_SUPPORTED, MISSING_CONFIRM, TIMEOUT.

Example prompts

  • "Show me offline devices in the warehouse group."
  • "Lock down device A1B2 in kiosk mode."
  • "List the 5 most recent compliance violations on Android Plus devices."
  • "Move all devices in \\Stores\Old\Pilot into \\Stores\Production."
  • "Which devices are running the com.acme.pos app at version below 4.2?"
  • "Send a check-in command to every device that hasn't reported in 24 hours."

The LLM picks the right tools and chains them together; you stay in chat.

Security notes

  • Credentials — Store SOTI_MC_CLIENT_SECRET in your MCP client's secrets store, not in .mcp.json if you can avoid it. The client ID and secret should be created in the MobiControl console (Administration → API Clients) with the minimum group-scope permissions your workflows require.
  • Scope minimization — SOTI MC enforces permissions per device group. Create a dedicated API client for the LLM with read-only or limited-action rights, and grant write actions only on the groups you actually need to mutate.
  • Destructive operationssoti_wipe_device requires explicit confirm: true. The tool description marks it DESTRUCTIVE so MCP clients can highlight it. soti_send_command rejects Wipe / FactoryReset and forces callers through soti_wipe_device.
  • Audit logging — SOTI MC logs every API call against the API client identity. Use a dedicated client for the LLM so its activity is auditable separately from human operators.
  • Token storage — OAuth2 access tokens are held only in the running process memory; never written to disk. Logs redact Authorization headers and access tokens.
  • Rate limit — A token-bucket limiter (default 10 req/sec) prevents the LLM from accidentally hammering your MobiControl Server. Tune via SOTI_MC_RATE_LIMIT_RPS.
  • Network — All traffic to MobiControl is over HTTPS. Use a private network or reverse proxy if your MobiControl Server is exposed to the internet.

Compatibility matrix

| MobiControl version | Status | Notes | |---|---|---| | 16.x (cloud + on-prem) | ✅ tested | Full tool surface available. | | 15.x | ✅ expected | All endpoints used by this MCP exist since v14. | | 14.x | ⚠️ partial | soti_search_devices and soti_move_device require v14+. | | 13.x | ⚠️ legacy | Most read tools work; soti_search_devices falls back to soti_list_devices. | | ≤ 12.x | ❌ unsupported | API surface differs significantly. |

When an endpoint is missing on an older version the server returns NOT_SUPPORTED rather than a raw 404 — your LLM can adapt its plan.

Environment variables

| Variable | Required | Default | Notes | |---|---|---|---| | SOTI_MC_BASE_URL | yes | — | e.g. https://mc.example.com/MobiControl. Token endpoint resolves to {BASE_URL}/api/token. | | SOTI_MC_CLIENT_ID | yes | — | OAuth2 client ID. | | SOTI_MC_CLIENT_SECRET | yes | — | OAuth2 client secret. | | SOTI_MC_GRANT_TYPE | no | client_credentials | Or password. | | SOTI_MC_USERNAME | when password | — | Resource Owner Password grant only. | | SOTI_MC_PASSWORD | when password | — | Resource Owner Password grant only. | | SOTI_MC_RATE_LIMIT_RPS | no | 10 | Per-server-instance request budget. | | SOTI_MC_LOG_LEVEL | no | info | trace / debug / info / warn / error. Logs go to stderr only. | | SOTI_MCP_HTTP_HOST | no | — | If set with SOTI_MCP_HTTP_PORT, switches to Streamable HTTP transport. | | SOTI_MCP_HTTP_PORT | no | — | TCP port for HTTP transport. |

Local development

git clone https://github.com/tomer-bdbd/soti-mcp.git
cd soti-mcp
npm install
cp .env.example .env   # then edit with your sandbox credentials
npm run dev            # runs from src/ via tsx
npm test               # 40+ unit tests, no SOTI sandbox required
npm run test:coverage  # enforces ≥80% lines

A live smoke test against a real SOTI MobiControl deployment is gated behind SOTI_MC_INTEGRATION=1 and is not run in CI. To exercise it locally:

SOTI_MC_INTEGRATION=1 npm test

Roadmap

  • v0.2 — bulk operations (/devices/actions), webhook receiver for SOTI events, iOS APNS-aware command set, scripted demo GIF, OpenAPI-driven type generation.
  • v0.3 — multi-tenant config (multiple SOTI servers per process), retry budget surfaced as MCP progress events.

Contributing

Issues and PRs welcome. Please open an issue first for non-trivial changes so we can align on scope. Run npm run lint && npm run typecheck && npm test before opening the PR.

License

MIT — see LICENSE.


Trademark note. SOTI and MobiControl are trademarks of SOTI Inc. This project is not affiliated with or endorsed by SOTI Inc. The maintainer is an independent SOTI MobiControl operator who built this so AI agents could drive their fleet without re-implementing OAuth2 + REST glue.