Skip to main content
Glama
README.md
# vsa-x-mcp

MCP wrapper for VSA X API with centralized configuration and multiple endpoints for managing devices, assets, organizations, and rate limits.

## Quick Start

1. Copy `.env.sample` to `.env` and configure:
   ```env
   VSA_SERVER_NAME=your-vsa-server.example
   VSA_API_PATH=/api/v3
   PORT=3000
   READ_ONLY=true
   ```

2. Install dependencies:
   ```bash
   npm install
   ```

3. Start the server:
   ```bash
   npm start
   ```

## Configuration

### Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `VSA_SERVER_NAME` | Yes | VSA X server hostname (e.g., `vsa.example.com`) |
| `VSA_API_PATH` | Yes | API path prefix (default: `/api/v3`) |
| `VSA_BASE_URL` | No | Alternative: full base URL (legacy, for backwards compatibility) |
| `PORT` | No | Server port (default: `3000`) |
| `READ_ONLY` | No | Block destructive operations when `true` (default: `true`) |

**Note:** Use either `VSA_SERVER_NAME` + `VSA_API_PATH` (recommended) or `VSA_BASE_URL` (legacy).

## Authentication

Clients authenticate using HTTP Basic Auth:
```
Authorization: Basic base64(TOKEN_ID:TOKEN_SECRET)
```

Example:
```bash
curl -u "your-token-id:your-token-secret" http://localhost:3000/devices
```

## Endpoints

### Health
- `GET /health` — Health check

### Devices
- `GET /devices` — List all devices with optional pagination, filtering, and sorting
  - Query params: `$top`, `$skip`, `$filter`, `$orderby`, `$count`, `scopeId`
  - Example: `GET /devices?$top=50&$skip=0&$filter=contains(tolower(Name),'server')`
- `GET /devices/:id` — Get device details
- `GET /devices/:id/assets` — Get assets for a specific device

### Organizations
- `GET /organizations` — List organizations with optional pagination, filtering, and sorting
  - Query params: `$top`, `$skip`, `$filter`, `$orderby`, `$count`
  - Example: `GET /organizations?$top=20&$orderby=Name`

### Rate Limits
- `GET /ratelimits` — Get current rate limit status

## Query Parameters

The list endpoints (`/devices` and `/organizations`) support OData query parameters for powerful filtering and pagination:

| Parameter | Description | Example |
|-----------|-------------|---------|
| `$top` | Maximum items to return (pagination) | `$top=50` |
| `$skip` | Number of items to skip (pagination) | `$skip=100` |
| `$filter` | Filter results using OData syntax | `$filter=contains(tolower(Name),'prod')` |
| `$orderby` | Sort results by one or more fields | `$orderby=Name desc` |
| `$count` | Include total count in response metadata | `$count=true` |

### Devices Endpoint - Filterable Properties
Use these properties in `$filter` expressions: **Identifier**, **Name**, **GroupId**, **GroupName**, **IsAgentInstalled**, **IsMdmEnrolled**, **SiteId**, **SiteName**, **OrganizationId**, **OrganizationName**

Also supports: `scopeId` parameter for filtering by scope ID

### Devices Endpoint - Sortable Properties
Use these properties in `$orderby` expressions: **Identifier**, **Name**, **GroupId**, **GroupName**, **IsAgentInstalled**, **IsMdmEnrolled**, **SiteId**, **SiteName**, **OrganizationId**, **OrganizationName**

**Example requests:**
```bash
# Get first 50 devices sorted by name
curl -u TOKEN_ID:TOKEN_SECRET "http://localhost:3000/devices?$top=50&$orderby=Name"

# Find devices with agent installed and in a specific organization
curl -u TOKEN_ID:TOKEN_SECRET "http://localhost:3000/devices?$filter=IsAgentInstalled eq true and OrganizationName eq 'Acme Corp'&$top=50"

# Paginate through devices with specific group, sorted by name
curl -u TOKEN_ID:TOKEN_SECRET "http://localhost:3000/devices?$top=100&$skip=100&$filter=GroupName eq 'Production'&$orderby=Name"

# Find devices in a specific scope that are not MDM enrolled
curl -u TOKEN_ID:TOKEN_SECRET "http://localhost:3000/devices?scopeId=123&$filter=IsMdmEnrolled eq false&$top=50&$orderby=Name desc"

# Filter organizations by name with total count
curl -u TOKEN_ID:TOKEN_SECRET "http://localhost:3000/organizations?$filter=startswith(Name,'Production')&$count=true"
```
## Features

- ✅ Basic authentication forwarding per request
- ✅ Centralized API URL configuration
- ✅ Per-route write operation guards
- ✅ Error handling with upstream error details
- ✅ Rate limit headers forwarding
- ✅ OpenAPI documentation (`openapi.yaml`)

## Write Operations

Write operations are guarded by `READ_ONLY` environment variable:
- When `READ_ONLY=true` (default), destructive operations are blocked
- To enable writes, set `READ_ONLY=false` or include `confirm_destructive_action=true` in the request

## Testing

Run tests with:
```bash
npm test
```

## API Documentation

See `openapi.yaml` for complete API specification and schema details.