Metadata-Version: 2.4
Name: bibliocommons-mcp-mosyle
Version: 1.3.5
Summary: MCP server for Mosyle Business MDM
Author-email: Cody Lusk <cody.lusk@bibliocommons.com>
License: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: fastmcp>=3.2.4
Requires-Dist: requests>=2.33.1
Requires-Dist: fastapi>=0.136.1
Requires-Dist: uvicorn>=0.46.0
Requires-Dist: python-multipart>=0.0.27
Provides-Extra: dev
Requires-Dist: pytest>=9.0.3; extra == "dev"
Requires-Dist: pytest-asyncio>=1.3.0; extra == "dev"
Requires-Dist: pytest-cov>=7.1.0; extra == "dev"
Requires-Dist: httpx>=0.28.1; extra == "dev"

# Mosyle MDM MCP Server

MCP server for interacting with Mosyle Business MDM instances. Provides 35 tools across device management, user/group management, custom attributes, lost mode, and log streaming. Supports JWT authentication and a `--read-only` mode for safe operation.

## Configuration

**Authentication**: Mosyle uses an API access token combined with email/password credentials to obtain a JWT bearer token. Create a dedicated API user in Mosyle Business rather than using a personal account.

### Option 1: config.json

```bash
cp config.json.example config.json
# Edit config.json with your API credentials
```

### Option 2: Environment Variables

```bash
export MOSYLE_HOST="businessapi.mosyle.com"
export MOSYLE_EMAIL="api-user@example.com"
export MOSYLE_PASSWORD="api-password"
export MOSYLE_ACCESS_TOKEN="your-access-token"
export MOSYLE_LOGS_HOST="businessapilogs.mosyle.com"
export MOSYLE_TIMEOUT="30"
```

## Installation

### Option 1: Using uvx (Recommended — no install needed)

```bash
uvx bibliocommons-mcp-mosyle
```

[uvx](https://github.com/astral-sh/uv) runs the package directly from PyPI in an isolated environment. Install uv first if you don't have it:

```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```

### Option 2: Using pip

```bash
pip install bibliocommons-mcp-mosyle
```

## AI Client Setup

### VS Code (with MCP Extension)

1. Install an MCP-compatible extension in VS Code
2. Open VS Code Settings (JSON): `Cmd+Shift+P` → "Preferences: Open User Settings (JSON)"
3. Add the server configuration:

```json
{
  "mcp.servers": {
    "mosyle": {
      "command": "uvx",
      "args": ["bibliocommons-mcp-mosyle"]
    }
  }
}
```

**Alternative: Using python directly**

```json
{
  "mcp.servers": {
    "mosyle": {
      "command": "python",
      "args": ["-m", "bibliocommons_mcp_mosyle"]
    }
  }
}
```

### Claude Desktop

1. Open Claude Desktop configuration:
   - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
   - Windows: `%APPDATA%\Claude\claude_desktop_config.json`

2. Add the server configuration:

```json
{
  "mcpServers": {
    "mosyle": {
      "command": "uvx",
      "args": ["bibliocommons-mcp-mosyle"]
    }
  }
}
```

**Alternative: Using python directly**

```json
{
  "mcpServers": {
    "mosyle": {
      "command": "python",
      "args": ["-m", "bibliocommons_mcp_mosyle"]
    }
  }
}
```

### Kiro IDE

1. Open Kiro IDE settings
2. Navigate to MCP Servers configuration
3. Add the server:

```json
{
  "mcpServers": {
    "mosyle": {
      "command": "uvx",
      "args": ["bibliocommons-mcp-mosyle"]
    }
  }
}
```

**Alternative: Using python directly**

```json
{
  "mcpServers": {
    "mosyle": {
      "command": "python",
      "args": ["-m", "bibliocommons_mcp_mosyle"]
    }
  }
}
```

### Kiro CLI

1. Create or edit the MCP configuration file:
   - User level: `~/.kiro/settings/mcp.json`
   - Project level: `<project-root>/.kiro/settings/mcp.json`

2. Add the server configuration:

```json
{
  "mcpServers": {
    "mosyle": {
      "command": "uvx",
      "args": ["bibliocommons-mcp-mosyle"]
    }
  }
}
```

**Alternative: Using python directly**

```json
{
  "mcpServers": {
    "mosyle": {
      "command": "python",
      "args": ["-m", "bibliocommons_mcp_mosyle"]
    }
  }
}
```

### Configuration Notes

- **Using `uvx` (default)**: Automatically manages dependencies in isolated environments (like `npx` for Node.js)
- **Using `python` (alternative)**: Requires `pip install bibliocommons-mcp-mosyle` first
- Add `--config /path/to/config.json` to the args array to use a specific config file
- Add `--read-only` to the args array to disable destructive tools
- After adding the configuration, restart your AI client for changes to take effect

For other AI clients (Amazon Q, GitHub Copilot, Cline, Zed, Cursor), see [docs/ai-clients.md](docs/ai-clients.md).

## Docker

```bash
# Pull from Docker Hub (private)
docker pull bibliocommons/mcp-mosyle:latest

# Run in stdio mode
docker run -i --rm \
  -v /path/to/config.json:/config.json:ro \
  bibliocommons/mcp-mosyle:latest \
  --config /config.json

# Run in HTTP mode
docker run -d --rm \
  -v /path/to/config.json:/config.json:ro \
  -p 8000:8000 \
  bibliocommons/mcp-mosyle:latest \
  --config /config.json --transport http --port 8000

# Run in expanded mode
docker run -i --rm \
  -v /path/to/config.json:/config.json:ro \
  bibliocommons/mcp-mosyle:latest \
  --config /config.json --expanded
```

## Web UI with Swagger

A REST API with interactive Swagger documentation is available:

```bash
python -m bibliocommons_mcp_mosyle.webui
```

Access the Swagger UI at: [http://localhost:8000/docs]

The Web UI provides:

- Interactive API documentation
- Try-it-out functionality for all endpoints
- OpenAPI/Swagger specification
- REST API access to all MCP tools

## Standalone MCP Server

```bash
python -m bibliocommons_mcp_mosyle
```

### CLI Flags

| Flag | Env Var | Description |
|------|---------|-------------|
| `--config PATH` | `MOSYLE_CONFIG` | Path to config.json |
| `--read-only` | `MOSYLE_READ_ONLY` | Exclude destructive tools |
| `--expanded` | `MOSYLE_EXPANDED` | Register all tools individually instead of gateway mode |
| `--transport stdio\|http` | `MOSYLE_TRANSPORT` | Transport mode (default: stdio) |
| `--port PORT` | `MOSYLE_PORT` | HTTP port (default: 8000) |
| `--version` | — | Show version and exit |

## Gateway Mode (Default)

By default, the server exposes 2 tools instead of 35 individual tools:

| Tool | Purpose |
|------|---------|
| `mosyle_api` | Execute any Mosyle MDM action by name with a params dict |
| `mosyle_help` | Search available actions, parameters, and descriptions |

The AI assistant calls `mosyle_help` to discover available actions, then calls `mosyle_api(action="list_devices", params={})` to execute them.

To register all individual tools (previous behavior), use `--expanded`:

```bash
python -m bibliocommons_mcp_mosyle --expanded
```

## Available Tools

| Domain | Tools | Description |
|--------|-------|-------------|
| Devices | 9 | list_devices, update_device, shutdown_devices, restart_devices, wipe_devices, assign_device_user, unassign_device, enable_activation_lock, disable_activation_lock |
| Custom Attributes | 6 | list_custom_device_attributes, create_custom_device_attribute, assign_custom_device_attribute, update_custom_device_attribute, remove_custom_device_attribute, delete_custom_device_attribute |
| Variables | 3 | save_variable, delete_variable, lock_device |
| Users | 3 | list_users, create_user, update_user |
| User Groups | 5 | list_user_groups, create_user_group, update_user_group, add_users_to_group, remove_users_from_group |
| Device Groups | 3 | list_device_groups, get_device_group_info, update_device_group |
| Lost Mode | 4 | enable_lost_mode, disable_lost_mode, play_lost_mode_sound, request_device_location |
| Logs | 2 | list_action_logs, get_logs_stream |

See [docs/API-REFERENCE.md](docs/API-REFERENCE.md) for full parameter details.

## Read-Only Mode

Disable all destructive tools for safe, audit-only operation:

```bash
# CLI flag
python -m bibliocommons_mcp_mosyle --read-only

# Environment variable
export MOSYLE_READ_ONLY=true
```

In read-only mode, the following 26 tools are excluded:

- **Devices**: update_device, shutdown_devices, restart_devices, wipe_devices, assign_device_user, unassign_device, enable_activation_lock, disable_activation_lock
- **Custom Attributes**: create_custom_device_attribute, assign_custom_device_attribute, update_custom_device_attribute, remove_custom_device_attribute, delete_custom_device_attribute
- **Variables**: save_variable, delete_variable, lock_device
- **Users**: create_user, update_user
- **User Groups**: create_user_group, update_user_group, add_users_to_group, remove_users_from_group
- **Device Groups**: update_device_group
- **Lost Mode**: enable_lost_mode, disable_lost_mode, play_lost_mode_sound

The remaining 9 read-only tools are: list_devices, list_custom_device_attributes, list_users, list_user_groups, list_device_groups, get_device_group_info, request_device_location, list_action_logs, get_logs_stream.

## Security Notes

- Create a **dedicated API user** in Mosyle Business for MCP access rather than using a personal account
- The access token is a long-lived credential; store it securely and rotate periodically
- **Never commit `config.json`** with real credentials (it is excluded by `.gitignore`)
- Use `config.json.example` as a template
- Prefer environment variables for production and CI environments
- Use `--read-only` mode when write access is not needed
