mirror of
https://github.com/jmagar/unraid-mcp
synced 2026-04-21 13:37:53 +00:00
fix(ci): add missing .dockerignore entries, replace uv audit with uvx pip-audit, upgrade trivy-action
This commit is contained in:
parent
d30739789d
commit
c39b05277c
25 changed files with 27501 additions and 2998 deletions
|
|
@ -21,10 +21,11 @@
|
|||
.env.*
|
||||
!.env.example
|
||||
*.log
|
||||
logs/
|
||||
backups/
|
||||
docs/
|
||||
specs/
|
||||
logs
|
||||
backups
|
||||
docs
|
||||
scripts
|
||||
specs
|
||||
*.md
|
||||
!README.md
|
||||
__pycache__
|
||||
|
|
@ -45,5 +46,5 @@ biome.json
|
|||
.pre-commit-config.yaml
|
||||
.prettierrc
|
||||
.prettierignore
|
||||
tests/
|
||||
tests
|
||||
|
||||
|
|
|
|||
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
|
|
@ -95,8 +95,10 @@ jobs:
|
|||
- uses: astral-sh/setup-uv@v5
|
||||
with:
|
||||
version: "0.9.25"
|
||||
- name: Install dependencies
|
||||
run: uv sync
|
||||
- name: Dependency audit
|
||||
run: uv audit
|
||||
run: uvx pip-audit
|
||||
|
||||
docker-security:
|
||||
name: Docker Security
|
||||
|
|
|
|||
2
.github/workflows/docker-publish.yml
vendored
2
.github/workflows/docker-publish.yml
vendored
|
|
@ -66,7 +66,7 @@ jobs:
|
|||
|
||||
- name: Scan image for vulnerabilities
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: aquasecurity/trivy-action@915b19bbe73b92a6cf82a1bc12b087c9a19a5fe2 # v0.28.0
|
||||
uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0
|
||||
with:
|
||||
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
|
||||
format: 'sarif'
|
||||
|
|
|
|||
|
|
@ -202,8 +202,8 @@ uv run pytest -x # Fail fast on first error
|
|||
See `tests/mcporter/README.md` for transport differences and `docs/DESTRUCTIVE_ACTIONS.md` for exact destructive-action test commands.
|
||||
|
||||
### API Reference Docs
|
||||
- `docs/UNRAID_API_COMPLETE_REFERENCE.md` — Full GraphQL schema reference
|
||||
- `docs/UNRAID_API_OPERATIONS.md` — All supported operations with examples
|
||||
- `docs/unraid/UNRAID-API-SUMMARY.md` — Condensed schema overview
|
||||
- `docs/unraid/UNRAID-API-COMPLETE-REFERENCE.md` — Full GraphQL schema reference
|
||||
- `docs/MARKETPLACE.md` — Plugin marketplace listing and publishing guide
|
||||
- `docs/PUBLISHING.md` — Step-by-step instructions for publishing to Claude plugin registry
|
||||
|
||||
|
|
@ -298,4 +298,4 @@ Bump type is determined by the commit message prefix:
|
|||
- `CHANGELOG.md` — new entry under the bumped version
|
||||
|
||||
All files MUST have the same version. Never bump only one file.
|
||||
CHANGELOG.md must have an entry for every version bump.
|
||||
CHANGELOG.md must have an entry for every version bump.
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ Complete listing of all plugin components.
|
|||
| `scripts/check-no-baked-env.sh` | Verify no env vars baked into images |
|
||||
| `scripts/check-outdated-deps.sh` | Dependency freshness check |
|
||||
| `scripts/ensure-ignore-files.sh` | Gitignore/dockerignore alignment |
|
||||
| `scripts/generate_unraid_api_reference.py` | Generate API reference from GraphQL introspection |
|
||||
| `scripts/generate_unraid_api_reference.py` | Generate canonical API docs and schema change report from GraphQL introspection |
|
||||
| `scripts/lint-plugin.sh` | Plugin manifest validation |
|
||||
| `scripts/validate-marketplace.sh` | Marketplace JSON validation |
|
||||
|
||||
|
|
|
|||
|
|
@ -1,290 +0,0 @@
|
|||
# Unraid GraphQL API Operations
|
||||
|
||||
Generated via live introspection at `2026-02-15 23:45:50Z`.
|
||||
|
||||
## Schema Summary
|
||||
- Query root: `Query`
|
||||
- Mutation root: `Mutation`
|
||||
- Subscription root: `Subscription`
|
||||
- Total types: **164**
|
||||
- Total directives: **6**
|
||||
- Type kinds:
|
||||
- `ENUM`: 32
|
||||
- `INPUT_OBJECT`: 16
|
||||
- `INTERFACE`: 2
|
||||
- `OBJECT`: 103
|
||||
- `SCALAR`: 10
|
||||
- `UNION`: 1
|
||||
|
||||
## Queries
|
||||
Total: **46**
|
||||
|
||||
### `apiKey(id: PrefixedID!): ApiKey`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **API_KEY**
|
||||
|
||||
Arguments:
|
||||
- `id`: `PrefixedID!`
|
||||
|
||||
### `apiKeyPossiblePermissions(): [Permission!]!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **PERMISSION** #### Description: All possible permissions for API keys
|
||||
|
||||
### `apiKeyPossibleRoles(): [Role!]!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **PERMISSION** #### Description: All possible roles for API keys
|
||||
|
||||
### `apiKeys(): [ApiKey!]!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **API_KEY**
|
||||
|
||||
### `array(): UnraidArray!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **ARRAY**
|
||||
|
||||
### `config(): Config!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **CONFIG**
|
||||
|
||||
### `customization(): Customization`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **CUSTOMIZATIONS**
|
||||
|
||||
### `disk(id: PrefixedID!): Disk!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **DISK**
|
||||
|
||||
Arguments:
|
||||
- `id`: `PrefixedID!`
|
||||
|
||||
### `disks(): [Disk!]!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **DISK**
|
||||
|
||||
### `docker(): Docker!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **DOCKER**
|
||||
|
||||
### `flash(): Flash!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **FLASH**
|
||||
|
||||
### `getApiKeyCreationFormSchema(): ApiKeyFormSettings!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **API_KEY** #### Description: Get JSON Schema for API key creation form
|
||||
|
||||
### `getAvailableAuthActions(): [AuthAction!]!`
|
||||
Get all available authentication actions with possession
|
||||
|
||||
### `getPermissionsForRoles(roles: [Role!]!): [Permission!]!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **PERMISSION** #### Description: Get the actual permissions that would be granted by a set of roles
|
||||
|
||||
Arguments:
|
||||
- `roles`: `[Role!]!`
|
||||
|
||||
### `info(): Info!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **INFO**
|
||||
|
||||
### `isInitialSetup(): Boolean!`
|
||||
### `isSSOEnabled(): Boolean!`
|
||||
### `logFile(lines: Int, path: String!, startLine: Int): LogFileContent!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **LOGS**
|
||||
|
||||
Arguments:
|
||||
- `lines`: `Int`
|
||||
- `path`: `String!`
|
||||
- `startLine`: `Int`
|
||||
|
||||
### `logFiles(): [LogFile!]!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **LOGS**
|
||||
|
||||
### `me(): UserAccount!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **ME**
|
||||
|
||||
### `metrics(): Metrics!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **INFO**
|
||||
|
||||
### `notifications(): Notifications!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **NOTIFICATIONS** #### Description: Get all notifications
|
||||
|
||||
### `oidcConfiguration(): OidcConfiguration!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **CONFIG** #### Description: Get the full OIDC configuration (admin only)
|
||||
|
||||
### `oidcProvider(id: PrefixedID!): OidcProvider`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **CONFIG** #### Description: Get a specific OIDC provider by ID
|
||||
|
||||
Arguments:
|
||||
- `id`: `PrefixedID!`
|
||||
|
||||
### `oidcProviders(): [OidcProvider!]!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **CONFIG** #### Description: Get all configured OIDC providers (admin only)
|
||||
|
||||
### `online(): Boolean!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **ONLINE**
|
||||
|
||||
### `owner(): Owner!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **OWNER**
|
||||
|
||||
### `parityHistory(): [ParityCheck!]!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **ARRAY**
|
||||
|
||||
### `plugins(): [Plugin!]!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **CONFIG** #### Description: List all installed plugins with their metadata
|
||||
|
||||
### `previewEffectivePermissions(permissions: [AddPermissionInput!], roles: [Role!]): [Permission!]!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **PERMISSION** #### Description: Preview the effective permissions for a combination of roles and explicit permissions
|
||||
|
||||
Arguments:
|
||||
- `permissions`: `[AddPermissionInput!]`
|
||||
- `roles`: `[Role!]`
|
||||
|
||||
### `publicOidcProviders(): [PublicOidcProvider!]!`
|
||||
Get public OIDC provider information for login buttons
|
||||
|
||||
### `publicPartnerInfo(): PublicPartnerInfo`
|
||||
### `publicTheme(): Theme!`
|
||||
### `rclone(): RCloneBackupSettings!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **FLASH**
|
||||
|
||||
### `registration(): Registration`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **REGISTRATION**
|
||||
|
||||
### `server(): Server`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **SERVERS**
|
||||
|
||||
### `servers(): [Server!]!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **SERVERS**
|
||||
|
||||
### `services(): [Service!]!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **SERVICES**
|
||||
|
||||
### `settings(): Settings!`
|
||||
### `shares(): [Share!]!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **SHARE**
|
||||
|
||||
### `upsConfiguration(): UPSConfiguration!`
|
||||
### `upsDeviceById(id: String!): UPSDevice`
|
||||
Arguments:
|
||||
- `id`: `String!`
|
||||
|
||||
### `upsDevices(): [UPSDevice!]!`
|
||||
### `validateOidcSession(token: String!): OidcSessionValidation!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **CONFIG** #### Description: Validate an OIDC session token (internal use for CLI validation)
|
||||
|
||||
Arguments:
|
||||
- `token`: `String!`
|
||||
|
||||
### `vars(): Vars!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **VARS**
|
||||
|
||||
### `vms(): Vms!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **VMS** #### Description: Get information about all VMs on the system
|
||||
|
||||
## Mutations
|
||||
Total: **22**
|
||||
|
||||
### `addPlugin(input: PluginManagementInput!): Boolean!`
|
||||
#### Required Permissions: - Action: **UPDATE_ANY** - Resource: **CONFIG** #### Description: Add one or more plugins to the API. Returns false if restart was triggered automatically, true if manual restart is required.
|
||||
|
||||
Arguments:
|
||||
- `input`: `PluginManagementInput!`
|
||||
|
||||
### `apiKey(): ApiKeyMutations!`
|
||||
### `archiveAll(importance: NotificationImportance): NotificationOverview!`
|
||||
Arguments:
|
||||
- `importance`: `NotificationImportance`
|
||||
|
||||
### `archiveNotification(id: PrefixedID!): Notification!`
|
||||
Marks a notification as archived.
|
||||
|
||||
Arguments:
|
||||
- `id`: `PrefixedID!`
|
||||
|
||||
### `archiveNotifications(ids: [PrefixedID!]!): NotificationOverview!`
|
||||
Arguments:
|
||||
- `ids`: `[PrefixedID!]!`
|
||||
|
||||
### `array(): ArrayMutations!`
|
||||
### `configureUps(config: UPSConfigInput!): Boolean!`
|
||||
Arguments:
|
||||
- `config`: `UPSConfigInput!`
|
||||
|
||||
### `createNotification(input: NotificationData!): Notification!`
|
||||
Creates a new notification record
|
||||
|
||||
Arguments:
|
||||
- `input`: `NotificationData!`
|
||||
|
||||
### `customization(): CustomizationMutations!`
|
||||
### `deleteArchivedNotifications(): NotificationOverview!`
|
||||
Deletes all archived notifications on server.
|
||||
|
||||
### `deleteNotification(id: PrefixedID!, type: NotificationType!): NotificationOverview!`
|
||||
Arguments:
|
||||
- `id`: `PrefixedID!`
|
||||
- `type`: `NotificationType!`
|
||||
|
||||
### `docker(): DockerMutations!`
|
||||
### `initiateFlashBackup(input: InitiateFlashBackupInput!): FlashBackupStatus!`
|
||||
Initiates a flash drive backup using a configured remote.
|
||||
|
||||
Arguments:
|
||||
- `input`: `InitiateFlashBackupInput!`
|
||||
|
||||
### `parityCheck(): ParityCheckMutations!`
|
||||
### `rclone(): RCloneMutations!`
|
||||
### `recalculateOverview(): NotificationOverview!`
|
||||
Reads each notification to recompute & update the overview.
|
||||
|
||||
### `removePlugin(input: PluginManagementInput!): Boolean!`
|
||||
#### Required Permissions: - Action: **DELETE_ANY** - Resource: **CONFIG** #### Description: Remove one or more plugins from the API. Returns false if restart was triggered automatically, true if manual restart is required.
|
||||
|
||||
Arguments:
|
||||
- `input`: `PluginManagementInput!`
|
||||
|
||||
### `unarchiveAll(importance: NotificationImportance): NotificationOverview!`
|
||||
Arguments:
|
||||
- `importance`: `NotificationImportance`
|
||||
|
||||
### `unarchiveNotifications(ids: [PrefixedID!]!): NotificationOverview!`
|
||||
Arguments:
|
||||
- `ids`: `[PrefixedID!]!`
|
||||
|
||||
### `unreadNotification(id: PrefixedID!): Notification!`
|
||||
Marks a notification as unread.
|
||||
|
||||
Arguments:
|
||||
- `id`: `PrefixedID!`
|
||||
|
||||
### `updateSettings(input: JSON!): UpdateSettingsResponse!`
|
||||
#### Required Permissions: - Action: **UPDATE_ANY** - Resource: **CONFIG**
|
||||
|
||||
Arguments:
|
||||
- `input`: `JSON!`
|
||||
|
||||
### `vm(): VmMutations!`
|
||||
## Subscriptions
|
||||
Total: **11**
|
||||
|
||||
### `arraySubscription(): UnraidArray!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **ARRAY**
|
||||
|
||||
### `logFile(path: String!): LogFileContent!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **LOGS**
|
||||
|
||||
Arguments:
|
||||
- `path`: `String!`
|
||||
|
||||
### `notificationAdded(): Notification!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **NOTIFICATIONS**
|
||||
|
||||
### `notificationsOverview(): NotificationOverview!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **NOTIFICATIONS**
|
||||
|
||||
### `ownerSubscription(): Owner!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **OWNER**
|
||||
|
||||
### `parityHistorySubscription(): ParityCheck!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **ARRAY**
|
||||
|
||||
### `serversSubscription(): Server!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **SERVERS**
|
||||
|
||||
### `systemMetricsCpu(): CpuUtilization!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **INFO**
|
||||
|
||||
### `systemMetricsCpuTelemetry(): CpuPackages!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **INFO**
|
||||
|
||||
### `systemMetricsMemory(): MemoryUtilization!`
|
||||
#### Required Permissions: - Action: **READ_ANY** - Resource: **INFO**
|
||||
|
||||
### `upsUpdates(): UPSDevice!`
|
||||
|
|
@ -1,928 +0,0 @@
|
|||
# Unraid API v4.29.2 — Complete Reference
|
||||
|
||||
> **Source of truth.** Auto-generated from live GraphQL introspection against tootie (10.1.0.2:31337) on 2026-03-15.
|
||||
> Unraid 7.2.4 · API v4.29.2 · 46 queries · 22 mutations · 11 subscriptions · 156 types
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Authentication](#authentication)
|
||||
- [Scalars & ID Format](#scalars--id-format)
|
||||
- [Queries](#queries)
|
||||
- [System & Server Info](#system--server-info)
|
||||
- [Array & Storage](#array--storage)
|
||||
- [Docker](#docker)
|
||||
- [Virtual Machines](#virtual-machines)
|
||||
- [Notifications](#notifications)
|
||||
- [API Keys & Permissions](#api-keys--permissions)
|
||||
- [Users & Auth](#users--auth)
|
||||
- [RClone / Backup](#rclone--backup)
|
||||
- [UPS / Power](#ups--power)
|
||||
- [Settings & Configuration](#settings--configuration)
|
||||
- [Logs](#logs)
|
||||
- [OIDC / SSO](#oidc--sso)
|
||||
- [Plugins](#plugins)
|
||||
- [Mutations](#mutations)
|
||||
- [Notification Mutations](#notification-mutations)
|
||||
- [Array Mutations](#array-mutations)
|
||||
- [Docker Mutations](#docker-mutations)
|
||||
- [VM Mutations](#vm-mutations)
|
||||
- [Parity Check Mutations](#parity-check-mutations)
|
||||
- [API Key Mutations](#api-key-mutations)
|
||||
- [Customization Mutations](#customization-mutations)
|
||||
- [RClone Mutations](#rclone-mutations)
|
||||
- [Flash Backup](#flash-backup)
|
||||
- [Settings Mutations](#settings-mutations)
|
||||
- [Plugin Mutations](#plugin-mutations)
|
||||
- [Subscriptions](#subscriptions)
|
||||
- [Enums](#enums)
|
||||
- [Input Types](#input-types)
|
||||
- [Object Types (Full Field Reference)](#object-types-full-field-reference)
|
||||
|
||||
---
|
||||
|
||||
## Authentication
|
||||
|
||||
All requests require an API key passed via the `x-api-key` HTTP header:
|
||||
|
||||
```bash
|
||||
curl -k -X POST \
|
||||
-H "x-api-key: YOUR_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"query": "{ online }"}' \
|
||||
https://YOUR-SERVER/graphql
|
||||
```
|
||||
|
||||
**Rate limit:** 100 requests per 10 seconds.
|
||||
|
||||
---
|
||||
|
||||
## Scalars & ID Format
|
||||
|
||||
| Scalar | Description |
|
||||
|--------|-------------|
|
||||
| `PrefixedID` | Server-prefixed ID: `<serverHash>:<localId>`. Input accepts with or without prefix. Output always includes prefix. |
|
||||
| `BigInt` | Non-fractional signed whole numbers (for disk sizes in KB, memory in bytes, etc.) |
|
||||
| `DateTime` | ISO 8601 UTC string, e.g. `2026-03-15T09:54:33Z` |
|
||||
| `JSON` | Arbitrary JSON value (used for settings, labels, mount info) |
|
||||
| `Port` | Valid TCP port 0–65535 |
|
||||
|
||||
---
|
||||
|
||||
## Queries
|
||||
|
||||
### System & Server Info
|
||||
|
||||
#### `info` → `Info!`
|
||||
Full hardware and software information. Permission: `READ_ANY` on `INFO`.
|
||||
|
||||
```graphql
|
||||
query {
|
||||
info {
|
||||
time
|
||||
baseboard { manufacturer model version serial memMax memSlots }
|
||||
cpu { manufacturer brand cores threads speed speedmax socket topology packages { totalPower power temp } }
|
||||
devices {
|
||||
gpu { type vendorname productid blacklisted }
|
||||
network { iface model vendor mac speed dhcp }
|
||||
pci { type vendorname productname vendorid productid }
|
||||
usb { name bus device }
|
||||
}
|
||||
display { theme unit scale tabs resize wwn total usage text warning critical hot max locale
|
||||
case { url icon error base64 }
|
||||
}
|
||||
memory { layout { size bank type clockSpeed manufacturer formFactor partNum serialNum } }
|
||||
os { platform distro release kernel arch hostname fqdn uptime uefi }
|
||||
system { manufacturer model version serial uuid sku virtual }
|
||||
versions { core { unraid api kernel } packages { openssl node npm pm2 git nginx php docker } }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### `vars` → `Vars!`
|
||||
143 system variables including hostname, timezone, array config, share settings, registration state, CSRF token, disk sync parameters, and much more. Permission: `READ_ANY` on `VARS`.
|
||||
|
||||
```graphql
|
||||
query {
|
||||
vars {
|
||||
version name timeZone comment security workgroup
|
||||
port portssl portssh useSsl useSsh useTelnet
|
||||
startArray spindownDelay shutdownTimeout
|
||||
shareCount shareSmbCount shareNfsCount
|
||||
regTy regState regTo
|
||||
mdNumDisks mdNumDisabled mdState mdResync
|
||||
configValid configError safeMode csrfToken
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### `metrics` → `Metrics!`
|
||||
CPU and memory utilization. Permission: `READ_ANY` on `INFO`.
|
||||
|
||||
```graphql
|
||||
query {
|
||||
metrics {
|
||||
cpu { percentTotal cpus { percentTotal percentUser percentSystem percentIdle } }
|
||||
memory { total used free available active buffcache percentTotal swapTotal swapUsed swapFree percentSwapTotal }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### `server` → `Server`
|
||||
Local server info. Permission: `READ_ANY` on `SERVERS`.
|
||||
|
||||
```graphql
|
||||
query {
|
||||
server { id name status guid apikey wanip lanip localurl remoteurl owner { username url avatar } }
|
||||
}
|
||||
```
|
||||
|
||||
#### `servers` → `[Server!]!`
|
||||
All registered servers (usually just the local one). Permission: `READ_ANY` on `SERVERS`.
|
||||
|
||||
#### `online` → `Boolean!`
|
||||
Simple connectivity check. Permission: `READ_ANY` on `ONLINE`.
|
||||
|
||||
#### `owner` → `Owner!`
|
||||
Server owner info. Permission: `READ_ANY` on `OWNER`. Returns `username`, `url`, `avatar`.
|
||||
|
||||
#### `registration` → `Registration`
|
||||
License info. Permission: `READ_ANY` on `REGISTRATION`. Returns `type`, `state`, `keyFile { location contents }`, `expiration`, `updateExpiration`.
|
||||
|
||||
#### `config` → `Config!`
|
||||
Configuration validity. Permission: `READ_ANY` on `CONFIG`. Returns `valid`, `error`.
|
||||
|
||||
#### `services` → `[Service!]!`
|
||||
Running services. Permission: `READ_ANY` on `SERVICES`. Each: `name`, `online`, `uptime { timestamp }`, `version`.
|
||||
|
||||
#### `flash` → `Flash!`
|
||||
Flash drive info. Permission: `READ_ANY` on `FLASH`. Returns `guid`, `vendor`, `product`.
|
||||
|
||||
#### `customization` → `Customization`
|
||||
UI customization. Permission: `READ_ANY` on `CUSTOMIZATIONS`. Returns `activationCode { ... }`, `partnerInfo { ... }`, `theme { ... }`.
|
||||
|
||||
#### `settings` → `Settings!`
|
||||
All settings including unified form, SSO, and API config.
|
||||
|
||||
```graphql
|
||||
query {
|
||||
settings {
|
||||
unified { dataSchema uiSchema values }
|
||||
sso { oidcProviders { id name clientId issuer scopes } }
|
||||
api { version extraOrigins sandbox plugins }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### `isInitialSetup` → `Boolean!`
|
||||
Whether server is in initial setup mode (no permission required).
|
||||
|
||||
---
|
||||
|
||||
### Array & Storage
|
||||
|
||||
#### `array` → `UnraidArray!`
|
||||
Array state with all disks. Permission: `READ_ANY` on `ARRAY`.
|
||||
|
||||
```graphql
|
||||
query {
|
||||
array {
|
||||
state
|
||||
capacity { kilobytes { free used total } disks { free used total } }
|
||||
boot { id name device size status temp type }
|
||||
parities { id name device size status temp numReads numWrites numErrors }
|
||||
parityCheckStatus { status progress speed errors duration correcting paused running }
|
||||
disks { id idx name device size status temp fsSize fsFree fsUsed type fsType color isSpinning numReads numWrites numErrors }
|
||||
caches { id name device size status temp fsSize fsFree fsUsed type }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### `shares` → `[Share!]!`
|
||||
User shares. Permission: `READ_ANY` on `SHARE`.
|
||||
|
||||
```graphql
|
||||
query {
|
||||
shares { id name free used size include exclude cache nameOrig comment allocator splitLevel floor cow color luksStatus }
|
||||
}
|
||||
```
|
||||
|
||||
#### `disks` → `[Disk!]!`
|
||||
Physical disks (hardware-level). Permission: `READ_ANY` on `DISK`.
|
||||
|
||||
```graphql
|
||||
query {
|
||||
disks { id device type name vendor size serialNum firmwareRevision interfaceType smartStatus temperature isSpinning
|
||||
partitions { name fsType size } }
|
||||
}
|
||||
```
|
||||
|
||||
#### `disk(id: PrefixedID!)` → `Disk!`
|
||||
Single disk by ID. Permission: `READ_ANY` on `DISK`.
|
||||
|
||||
#### `parityHistory` → `[ParityCheck!]!`
|
||||
Parity check history. Permission: `READ_ANY` on `ARRAY`.
|
||||
|
||||
```graphql
|
||||
query {
|
||||
parityHistory { date duration speed status errors progress correcting paused running }
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Docker
|
||||
|
||||
#### `docker` → `Docker!`
|
||||
Container and network queries. Permission: `READ_ANY` on `DOCKER`.
|
||||
|
||||
**Available sub-fields on Docker type:**
|
||||
- `containers(skipCache: Boolean! = false)` → `[DockerContainer!]!`
|
||||
- `networks(skipCache: Boolean! = false)` → `[DockerNetwork!]!`
|
||||
|
||||
**That's it.** No `logs`, no `portConflicts`, no `containerUpdateStatuses`. Only `containers` and `networks`.
|
||||
|
||||
```graphql
|
||||
query {
|
||||
docker {
|
||||
containers(skipCache: false) {
|
||||
id names image imageId command created state status autoStart
|
||||
ports { ip privatePort publicPort type }
|
||||
sizeRootFs labels hostConfig { networkMode } networkSettings mounts
|
||||
}
|
||||
networks(skipCache: false) {
|
||||
id name created scope driver enableIPv6
|
||||
internal attachable ingress configOnly
|
||||
ipam containers options labels
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**DockerContainer fields:** `id`, `names`, `image`, `imageId`, `command`, `created`, `ports`, `sizeRootFs`, `labels`, `state` (RUNNING/EXITED), `status`, `hostConfig`, `networkSettings`, `mounts`, `autoStart`.
|
||||
|
||||
**DockerNetwork fields:** `id`, `name`, `created`, `scope`, `driver`, `enableIPv6`, `ipam`, `internal`, `attachable`, `ingress`, `configFrom`, `configOnly`, `containers`, `options`, `labels`.
|
||||
|
||||
---
|
||||
|
||||
### Virtual Machines
|
||||
|
||||
#### `vms` → `Vms!`
|
||||
All VMs. Permission: `READ_ANY` on `VMS`.
|
||||
|
||||
```graphql
|
||||
query {
|
||||
vms {
|
||||
domains { id name state uuid }
|
||||
domain { id name state }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**VmState enum:** `NOSTATE`, `RUNNING`, `IDLE`, `PAUSED`, `SHUTDOWN`, `SHUTOFF`, `CRASHED`, `PMSUSPENDED`.
|
||||
|
||||
---
|
||||
|
||||
### Notifications
|
||||
|
||||
#### `notifications` → `Notifications!`
|
||||
Overview and list. Permission: `READ_ANY` on `NOTIFICATIONS`.
|
||||
|
||||
```graphql
|
||||
# Overview (counts by severity)
|
||||
query {
|
||||
notifications {
|
||||
overview {
|
||||
unread { info warning alert total }
|
||||
archive { info warning alert total }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# List with filter
|
||||
query {
|
||||
notifications {
|
||||
list(filter: { type: UNREAD, offset: 0, limit: 20, importance: WARNING }) {
|
||||
id title subject description importance link type timestamp formattedTimestamp
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**NotificationFilter input:** `type` (UNREAD/ARCHIVE, required), `offset` (required), `limit` (required), `importance` (optional: INFO/WARNING/ALERT).
|
||||
|
||||
---
|
||||
|
||||
### API Keys & Permissions
|
||||
|
||||
#### `apiKeys` → `[ApiKey!]!`
|
||||
All API keys. Permission: `READ_ANY` on `API_KEY`.
|
||||
|
||||
```graphql
|
||||
query { apiKeys { id key name description roles createdAt permissions { resource actions } } }
|
||||
```
|
||||
|
||||
#### `apiKey(id: PrefixedID!)` → `ApiKey`
|
||||
Single API key by ID. Permission: `READ_ANY` on `API_KEY`.
|
||||
|
||||
#### `apiKeyPossibleRoles` → `[Role!]!`
|
||||
Available roles (ADMIN, CONNECT, GUEST, VIEWER). Permission: `READ_ANY` on `PERMISSION`.
|
||||
|
||||
#### `apiKeyPossiblePermissions` → `[Permission!]!`
|
||||
All possible permissions. Permission: `READ_ANY` on `PERMISSION`.
|
||||
|
||||
#### `getPermissionsForRoles(roles: [Role!]!)` → `[Permission!]!`
|
||||
Resolve roles to actual permissions. Permission: `READ_ANY` on `PERMISSION`.
|
||||
|
||||
#### `previewEffectivePermissions(roles: [Role!], permissions: [AddPermissionInput!])` → `[Permission!]!`
|
||||
Preview effective permissions for a role/permission combo. Permission: `READ_ANY` on `PERMISSION`.
|
||||
|
||||
#### `getAvailableAuthActions` → `[AuthAction!]!`
|
||||
All auth actions (CREATE_ANY, READ_OWN, etc.).
|
||||
|
||||
#### `getApiKeyCreationFormSchema` → `ApiKeyFormSettings!`
|
||||
JSON Schema for API key creation form. Permission: `READ_ANY` on `API_KEY`. Returns `dataSchema`, `uiSchema`, `values`.
|
||||
|
||||
---
|
||||
|
||||
### Users & Auth
|
||||
|
||||
#### `me` → `UserAccount!`
|
||||
Current authenticated user. Permission: `READ_ANY` on `ME`.
|
||||
|
||||
```graphql
|
||||
query { me { id name description roles permissions { resource actions } } }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### RClone / Backup
|
||||
|
||||
#### `rclone` → `RCloneBackupSettings!`
|
||||
RClone configuration. Permission: `READ_ANY` on `FLASH`.
|
||||
|
||||
```graphql
|
||||
query {
|
||||
rclone {
|
||||
remotes { name type parameters config }
|
||||
drives { name options }
|
||||
configForm(formOptions: { providerType: "drive", showAdvanced: false }) {
|
||||
id dataSchema uiSchema
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### UPS / Power
|
||||
|
||||
#### `upsDevices` → `[UPSDevice!]!`
|
||||
All UPS devices.
|
||||
|
||||
```graphql
|
||||
query {
|
||||
upsDevices {
|
||||
id name model status
|
||||
battery { chargeLevel estimatedRuntime health }
|
||||
power { inputVoltage outputVoltage loadPercentage }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### `upsDeviceById(id: String!)` → `UPSDevice`
|
||||
Single UPS by ID.
|
||||
|
||||
#### `upsConfiguration` → `UPSConfiguration!`
|
||||
UPS daemon configuration.
|
||||
|
||||
```graphql
|
||||
query {
|
||||
upsConfiguration {
|
||||
service upsCable customUpsCable upsType device
|
||||
overrideUpsCapacity batteryLevel minutes timeout killUps
|
||||
nisIp netServer upsName modelName
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Logs
|
||||
|
||||
#### `logFiles` → `[LogFile!]!`
|
||||
Available log files. Permission: `READ_ANY` on `LOGS`.
|
||||
|
||||
```graphql
|
||||
query { logFiles { name path size modifiedAt } }
|
||||
```
|
||||
|
||||
#### `logFile(path: String!, lines: Int, startLine: Int)` → `LogFileContent!`
|
||||
Read a log file. Permission: `READ_ANY` on `LOGS`.
|
||||
|
||||
```graphql
|
||||
query { logFile(path: "/var/log/syslog", lines: 100, startLine: 1) { path content totalLines startLine } }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### OIDC / SSO
|
||||
|
||||
#### `isSSOEnabled` → `Boolean!`
|
||||
Whether SSO is enabled.
|
||||
|
||||
#### `publicOidcProviders` → `[PublicOidcProvider!]!`
|
||||
Public OIDC provider info for login buttons. Returns `id`, `name`, `buttonText`, `buttonIcon`, `buttonVariant`, `buttonStyle`.
|
||||
|
||||
#### `oidcProviders` → `[OidcProvider!]!`
|
||||
All configured OIDC providers (admin only). Permission: `READ_ANY` on `CONFIG`.
|
||||
|
||||
#### `oidcProvider(id: PrefixedID!)` → `OidcProvider`
|
||||
Single OIDC provider by ID. Permission: `READ_ANY` on `CONFIG`.
|
||||
|
||||
#### `oidcConfiguration` → `OidcConfiguration!`
|
||||
Full OIDC configuration. Permission: `READ_ANY` on `CONFIG`. Returns `providers` list and `defaultAllowedOrigins`.
|
||||
|
||||
#### `validateOidcSession(token: String!)` → `OidcSessionValidation!`
|
||||
Validate an OIDC session token. Permission: `READ_ANY` on `CONFIG`. Returns `valid`, `username`.
|
||||
|
||||
---
|
||||
|
||||
### Plugins
|
||||
|
||||
#### `plugins` → `[Plugin!]!`
|
||||
Installed plugins. Permission: `READ_ANY` on `CONFIG`.
|
||||
|
||||
```graphql
|
||||
query { plugins { name version hasApiModule hasCliModule } }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Mutations
|
||||
|
||||
### Notification Mutations
|
||||
|
||||
All notification mutations are **root-level** on the Mutation type.
|
||||
|
||||
| Mutation | Args | Returns | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `createNotification` | `input: NotificationData!` | `Notification!` | Create a new notification |
|
||||
| `archiveNotification` | `id: PrefixedID!` | `Notification!` | Mark as archived |
|
||||
| `archiveNotifications` | `ids: [PrefixedID!]!` | `NotificationOverview!` | Archive multiple |
|
||||
| `archiveAll` | `importance: NotificationImportance` | `NotificationOverview!` | Archive all (optional filter) |
|
||||
| `unreadNotification` | `id: PrefixedID!` | `Notification!` | Mark as unread |
|
||||
| `unarchiveNotifications` | `ids: [PrefixedID!]!` | `NotificationOverview!` | Unarchive multiple |
|
||||
| `unarchiveAll` | `importance: NotificationImportance` | `NotificationOverview!` | Unarchive all (optional filter) |
|
||||
| `deleteNotification` | `id: PrefixedID!`, `type: NotificationType!` | `NotificationOverview!` | Delete one notification |
|
||||
| `deleteArchivedNotifications` | — | `NotificationOverview!` | Delete ALL archived |
|
||||
| `recalculateOverview` | — | `NotificationOverview!` | Recompute counts from disk |
|
||||
|
||||
---
|
||||
|
||||
### Array Mutations
|
||||
|
||||
Nested under `mutation { array { ... } }` → `ArrayMutations!`
|
||||
|
||||
| Mutation | Args | Returns | Permission | Description |
|
||||
|----------|------|---------|------------|-------------|
|
||||
| `setState` | `input: ArrayStateInput!` | `UnraidArray!` | `UPDATE_ANY` on `ARRAY` | Start/stop array (`desiredState: START/STOP`) |
|
||||
| `addDiskToArray` | `input: ArrayDiskInput!` | `UnraidArray!` | `UPDATE_ANY` on `ARRAY` | Add disk to array |
|
||||
| `removeDiskFromArray` | `input: ArrayDiskInput!` | `UnraidArray!` | `UPDATE_ANY` on `ARRAY` | Remove disk (array must be stopped) |
|
||||
| `mountArrayDisk` | `id: PrefixedID!` | `ArrayDisk!` | `UPDATE_ANY` on `ARRAY` | Mount a disk |
|
||||
| `unmountArrayDisk` | `id: PrefixedID!` | `ArrayDisk!` | `UPDATE_ANY` on `ARRAY` | Unmount a disk |
|
||||
| `clearArrayDiskStatistics` | `id: PrefixedID!` | `Boolean!` | `UPDATE_ANY` on `ARRAY` | Clear disk I/O stats |
|
||||
|
||||
---
|
||||
|
||||
### Docker Mutations
|
||||
|
||||
Nested under `mutation { docker { ... } }` → `DockerMutations!`
|
||||
|
||||
| Mutation | Args | Returns | Permission | Description |
|
||||
|----------|------|---------|------------|-------------|
|
||||
| `start` | `id: PrefixedID!` | `DockerContainer!` | `UPDATE_ANY` on `DOCKER` | Start a container |
|
||||
| `stop` | `id: PrefixedID!` | `DockerContainer!` | `UPDATE_ANY` on `DOCKER` | Stop a container |
|
||||
|
||||
**That's it.** No pause, unpause, remove, update, or organizer mutations exist.
|
||||
|
||||
---
|
||||
|
||||
### VM Mutations
|
||||
|
||||
Nested under `mutation { vm { ... } }` → `VmMutations!`
|
||||
|
||||
| Mutation | Args | Returns | Permission | Description |
|
||||
|----------|------|---------|------------|-------------|
|
||||
| `start` | `id: PrefixedID!` | `Boolean!` | `UPDATE_ANY` on `VMS` | Start VM |
|
||||
| `stop` | `id: PrefixedID!` | `Boolean!` | `UPDATE_ANY` on `VMS` | Graceful stop |
|
||||
| `pause` | `id: PrefixedID!` | `Boolean!` | `UPDATE_ANY` on `VMS` | Pause VM |
|
||||
| `resume` | `id: PrefixedID!` | `Boolean!` | `UPDATE_ANY` on `VMS` | Resume paused VM |
|
||||
| `forceStop` | `id: PrefixedID!` | `Boolean!` | `UPDATE_ANY` on `VMS` | Force stop (hard power off) |
|
||||
| `reboot` | `id: PrefixedID!` | `Boolean!` | `UPDATE_ANY` on `VMS` | Reboot VM |
|
||||
| `reset` | `id: PrefixedID!` | `Boolean!` | `UPDATE_ANY` on `VMS` | Reset VM (hard reboot) |
|
||||
|
||||
---
|
||||
|
||||
### Parity Check Mutations
|
||||
|
||||
Nested under `mutation { parityCheck { ... } }` → `ParityCheckMutations!`
|
||||
|
||||
| Mutation | Args | Returns | Permission | Description |
|
||||
|----------|------|---------|------------|-------------|
|
||||
| `start` | `correct: Boolean!` | `JSON!` | `UPDATE_ANY` on `ARRAY` | Start parity check (correct=true writes fixes) |
|
||||
| `pause` | — | `JSON!` | `UPDATE_ANY` on `ARRAY` | Pause running check |
|
||||
| `resume` | — | `JSON!` | `UPDATE_ANY` on `ARRAY` | Resume paused check |
|
||||
| `cancel` | — | `JSON!` | `UPDATE_ANY` on `ARRAY` | Cancel running check |
|
||||
|
||||
> **Note:** Response types are `JSON!` — this API is marked WIP and types will change.
|
||||
|
||||
---
|
||||
|
||||
### API Key Mutations
|
||||
|
||||
Nested under `mutation { apiKey { ... } }` → `ApiKeyMutations!`
|
||||
|
||||
| Mutation | Args | Returns | Permission | Description |
|
||||
|----------|------|---------|------------|-------------|
|
||||
| `create` | `input: CreateApiKeyInput!` | `ApiKey!` | `CREATE_ANY` on `API_KEY` | Create API key |
|
||||
| `update` | `input: UpdateApiKeyInput!` | `ApiKey!` | `UPDATE_ANY` on `API_KEY` | Update API key |
|
||||
| `delete` | `input: DeleteApiKeyInput!` | `Boolean!` | `DELETE_ANY` on `API_KEY` | Delete one or more keys |
|
||||
| `addRole` | `input: AddRoleForApiKeyInput!` | `Boolean!` | `UPDATE_ANY` on `API_KEY` | Add role to key |
|
||||
| `removeRole` | `input: RemoveRoleFromApiKeyInput!` | `Boolean!` | `UPDATE_ANY` on `API_KEY` | Remove role from key |
|
||||
|
||||
---
|
||||
|
||||
### Customization Mutations
|
||||
|
||||
Nested under `mutation { customization { ... } }` → `CustomizationMutations!`
|
||||
|
||||
| Mutation | Args | Returns | Permission | Description |
|
||||
|----------|------|---------|------------|-------------|
|
||||
| `setTheme` | `theme: ThemeName!` | `Theme!` | `UPDATE_ANY` on `CUSTOMIZATIONS` | Update UI theme (azure/black/gray/white) |
|
||||
|
||||
---
|
||||
|
||||
### RClone Mutations
|
||||
|
||||
Nested under `mutation { rclone { ... } }` → `RCloneMutations!`
|
||||
|
||||
| Mutation | Args | Returns | Permission | Description |
|
||||
|----------|------|---------|------------|-------------|
|
||||
| `createRCloneRemote` | `input: CreateRCloneRemoteInput!` | `RCloneRemote!` | `CREATE_ANY` on `FLASH` | Create remote |
|
||||
| `deleteRCloneRemote` | `input: DeleteRCloneRemoteInput!` | `Boolean!` | `DELETE_ANY` on `FLASH` | Delete remote |
|
||||
|
||||
---
|
||||
|
||||
### Flash Backup
|
||||
|
||||
Root-level mutation.
|
||||
|
||||
| Mutation | Args | Returns | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `initiateFlashBackup` | `input: InitiateFlashBackupInput!` | `FlashBackupStatus!` | Start flash backup to remote |
|
||||
|
||||
**InitiateFlashBackupInput:** `remoteName: String!`, `sourcePath: String!`, `destinationPath: String!`, `options: JSON`
|
||||
|
||||
Returns: `status: String!`, `jobId: String`
|
||||
|
||||
---
|
||||
|
||||
### Settings Mutations
|
||||
|
||||
Root-level mutations.
|
||||
|
||||
| Mutation | Args | Returns | Permission | Description |
|
||||
|----------|------|---------|------------|-------------|
|
||||
| `updateSettings` | `input: JSON!` | `UpdateSettingsResponse!` | `UPDATE_ANY` on `CONFIG` | Update server settings |
|
||||
| `configureUps` | `config: UPSConfigInput!` | `Boolean!` | — | Configure UPS daemon |
|
||||
|
||||
**UpdateSettingsResponse:** `restartRequired: Boolean!`, `values: JSON!`, `warnings: [String!]`
|
||||
|
||||
---
|
||||
|
||||
### Plugin Mutations
|
||||
|
||||
Root-level mutations.
|
||||
|
||||
| Mutation | Args | Returns | Permission | Description |
|
||||
|----------|------|---------|------------|-------------|
|
||||
| `addPlugin` | `input: PluginManagementInput!` | `Boolean!` | `UPDATE_ANY` on `CONFIG` | Install plugin(s). Returns false if auto-restart triggered. |
|
||||
| `removePlugin` | `input: PluginManagementInput!` | `Boolean!` | `DELETE_ANY` on `CONFIG` | Remove plugin(s). Returns false if auto-restart triggered. |
|
||||
|
||||
---
|
||||
|
||||
## Subscriptions
|
||||
|
||||
WebSocket-based real-time data (graphql-ws protocol).
|
||||
|
||||
| Subscription | Returns | Permission | Description |
|
||||
|-------------|---------|------------|-------------|
|
||||
| `notificationAdded` | `Notification!` | `READ_ANY` on `NOTIFICATIONS` | New notification created |
|
||||
| `notificationsOverview` | `NotificationOverview!` | `READ_ANY` on `NOTIFICATIONS` | Overview counts change |
|
||||
| `ownerSubscription` | `Owner!` | `READ_ANY` on `OWNER` | Owner info change |
|
||||
| `serversSubscription` | `Server!` | `READ_ANY` on `SERVERS` | Server state change |
|
||||
| `parityHistorySubscription` | `ParityCheck!` | `READ_ANY` on `ARRAY` | Parity check updates |
|
||||
| `arraySubscription` | `UnraidArray!` | `READ_ANY` on `ARRAY` | Array state changes |
|
||||
| `logFile(path: String!)` | `LogFileContent!` | `READ_ANY` on `LOGS` | Live log file tail |
|
||||
| `systemMetricsCpu` | `CpuUtilization!` | `READ_ANY` on `INFO` | CPU utilization stream |
|
||||
| `systemMetricsCpuTelemetry` | `CpuPackages!` | `READ_ANY` on `INFO` | CPU power/temp stream |
|
||||
| `systemMetricsMemory` | `MemoryUtilization!` | `READ_ANY` on `INFO` | Memory utilization stream |
|
||||
| `upsUpdates` | `UPSDevice!` | — | UPS state changes |
|
||||
|
||||
---
|
||||
|
||||
## Enums
|
||||
|
||||
### ArrayDiskFsColor
|
||||
`GREEN_ON` · `GREEN_BLINK` · `BLUE_ON` · `BLUE_BLINK` · `YELLOW_ON` · `YELLOW_BLINK` · `RED_ON` · `RED_OFF` · `GREY_OFF`
|
||||
|
||||
### ArrayDiskStatus
|
||||
`DISK_NP` · `DISK_OK` · `DISK_NP_MISSING` · `DISK_INVALID` · `DISK_WRONG` · `DISK_DSBL` · `DISK_NP_DSBL` · `DISK_DSBL_NEW` · `DISK_NEW`
|
||||
|
||||
### ArrayDiskType
|
||||
`DATA` · `PARITY` · `FLASH` · `CACHE`
|
||||
|
||||
### ArrayState
|
||||
`STARTED` · `STOPPED` · `NEW_ARRAY` · `RECON_DISK` · `DISABLE_DISK` · `SWAP_DSBL` · `INVALID_EXPANSION` · `PARITY_NOT_BIGGEST` · `TOO_MANY_MISSING_DISKS` · `NEW_DISK_TOO_SMALL` · `NO_DATA_DISKS`
|
||||
|
||||
### ArrayStateInputState
|
||||
`START` · `STOP`
|
||||
|
||||
### AuthAction
|
||||
`CREATE_ANY` · `CREATE_OWN` · `READ_ANY` · `READ_OWN` · `UPDATE_ANY` · `UPDATE_OWN` · `DELETE_ANY` · `DELETE_OWN`
|
||||
|
||||
### AuthorizationOperator
|
||||
`EQUALS` · `CONTAINS` · `ENDS_WITH` · `STARTS_WITH`
|
||||
|
||||
### AuthorizationRuleMode
|
||||
`OR` · `AND`
|
||||
|
||||
### ConfigErrorState
|
||||
`UNKNOWN_ERROR` · `INELIGIBLE` · `INVALID` · `NO_KEY_SERVER` · `WITHDRAWN`
|
||||
|
||||
### ContainerPortType
|
||||
`TCP` · `UDP`
|
||||
|
||||
### ContainerState
|
||||
`RUNNING` · `EXITED`
|
||||
|
||||
### DiskFsType
|
||||
`XFS` · `BTRFS` · `VFAT` · `ZFS` · `EXT4` · `NTFS`
|
||||
|
||||
### DiskInterfaceType
|
||||
`SAS` · `SATA` · `USB` · `PCIE` · `UNKNOWN`
|
||||
|
||||
### DiskSmartStatus
|
||||
`OK` · `UNKNOWN`
|
||||
|
||||
### NotificationImportance
|
||||
`ALERT` · `INFO` · `WARNING`
|
||||
|
||||
### NotificationType
|
||||
`UNREAD` · `ARCHIVE`
|
||||
|
||||
### ParityCheckStatus
|
||||
`NEVER_RUN` · `RUNNING` · `PAUSED` · `COMPLETED` · `CANCELLED` · `FAILED`
|
||||
|
||||
### RegistrationState
|
||||
`TRIAL` · `BASIC` · `PLUS` · `PRO` · `STARTER` · `UNLEASHED` · `LIFETIME` · `EEXPIRED` · `EGUID` · `EGUID1` · `ETRIAL` · `ENOKEYFILE` · `ENOKEYFILE1` · `ENOKEYFILE2` · `ENOFLASH` · `ENOFLASH1` · `ENOFLASH2` · `ENOFLASH3` · `ENOFLASH4` · `ENOFLASH5` · `ENOFLASH6` · `ENOFLASH7` · `EBLACKLISTED` · `EBLACKLISTED1` · `EBLACKLISTED2` · `ENOCONN`
|
||||
|
||||
### Resource
|
||||
`ACTIVATION_CODE` · `API_KEY` · `ARRAY` · `CLOUD` · `CONFIG` · `CONNECT` · `CONNECT__REMOTE_ACCESS` · `CUSTOMIZATIONS` · `DASHBOARD` · `DISK` · `DISPLAY` · `DOCKER` · `FLASH` · `INFO` · `LOGS` · `ME` · `NETWORK` · `NOTIFICATIONS` · `ONLINE` · `OS` · `OWNER` · `PERMISSION` · `REGISTRATION` · `SERVERS` · `SERVICES` · `SHARE` · `VARS` · `VMS` · `WELCOME`
|
||||
|
||||
### Role
|
||||
- `ADMIN` — Full administrative access
|
||||
- `CONNECT` — Internal role for Unraid Connect
|
||||
- `GUEST` — Basic read access (user profile only)
|
||||
- `VIEWER` — Read-only access to all resources
|
||||
|
||||
### ServerStatus
|
||||
`ONLINE` · `OFFLINE` · `NEVER_CONNECTED`
|
||||
|
||||
### Temperature
|
||||
`CELSIUS` · `FAHRENHEIT`
|
||||
|
||||
### ThemeName
|
||||
`azure` · `black` · `gray` · `white`
|
||||
|
||||
### UPSCableType
|
||||
`USB` · `SIMPLE` · `SMART` · `ETHER` · `CUSTOM`
|
||||
|
||||
### UPSKillPower
|
||||
`YES` · `NO`
|
||||
|
||||
### UPSServiceState
|
||||
`ENABLE` · `DISABLE`
|
||||
|
||||
### UPSType
|
||||
`USB` · `APCSMART` · `NET` · `SNMP` · `DUMB` · `PCNET` · `MODBUS`
|
||||
|
||||
### UpdateStatus
|
||||
`UP_TO_DATE` · `UPDATE_AVAILABLE` · `REBUILD_READY` · `UNKNOWN`
|
||||
|
||||
### VmState
|
||||
`NOSTATE` · `RUNNING` · `IDLE` · `PAUSED` · `SHUTDOWN` · `SHUTOFF` · `CRASHED` · `PMSUSPENDED`
|
||||
|
||||
### registrationType
|
||||
`BASIC` · `PLUS` · `PRO` · `STARTER` · `UNLEASHED` · `LIFETIME` · `INVALID` · `TRIAL`
|
||||
|
||||
---
|
||||
|
||||
## Input Types
|
||||
|
||||
### NotificationData
|
||||
```graphql
|
||||
input NotificationData {
|
||||
title: String!
|
||||
subject: String!
|
||||
description: String!
|
||||
importance: NotificationImportance!
|
||||
link: String
|
||||
}
|
||||
```
|
||||
|
||||
### NotificationFilter
|
||||
```graphql
|
||||
input NotificationFilter {
|
||||
importance: NotificationImportance # optional filter
|
||||
type: NotificationType! # UNREAD or ARCHIVE
|
||||
offset: Int!
|
||||
limit: Int!
|
||||
}
|
||||
```
|
||||
|
||||
### ArrayStateInput
|
||||
```graphql
|
||||
input ArrayStateInput {
|
||||
desiredState: ArrayStateInputState! # START or STOP
|
||||
}
|
||||
```
|
||||
|
||||
### ArrayDiskInput
|
||||
```graphql
|
||||
input ArrayDiskInput {
|
||||
id: PrefixedID!
|
||||
slot: Int # optional slot number
|
||||
}
|
||||
```
|
||||
|
||||
### CreateApiKeyInput
|
||||
```graphql
|
||||
input CreateApiKeyInput {
|
||||
name: String!
|
||||
description: String
|
||||
roles: [Role!]
|
||||
permissions: [AddPermissionInput!]
|
||||
overwrite: Boolean # replace existing key with same name
|
||||
}
|
||||
```
|
||||
|
||||
### UpdateApiKeyInput
|
||||
```graphql
|
||||
input UpdateApiKeyInput {
|
||||
id: PrefixedID!
|
||||
name: String
|
||||
description: String
|
||||
roles: [Role!]
|
||||
permissions: [AddPermissionInput!]
|
||||
}
|
||||
```
|
||||
|
||||
### DeleteApiKeyInput
|
||||
```graphql
|
||||
input DeleteApiKeyInput {
|
||||
ids: [PrefixedID!]!
|
||||
}
|
||||
```
|
||||
|
||||
### AddPermissionInput
|
||||
```graphql
|
||||
input AddPermissionInput {
|
||||
resource: Resource!
|
||||
actions: [AuthAction!]!
|
||||
}
|
||||
```
|
||||
|
||||
### AddRoleForApiKeyInput / RemoveRoleFromApiKeyInput
|
||||
```graphql
|
||||
input AddRoleForApiKeyInput {
|
||||
apiKeyId: PrefixedID!
|
||||
role: Role!
|
||||
}
|
||||
input RemoveRoleFromApiKeyInput {
|
||||
apiKeyId: PrefixedID!
|
||||
role: Role!
|
||||
}
|
||||
```
|
||||
|
||||
### CreateRCloneRemoteInput
|
||||
```graphql
|
||||
input CreateRCloneRemoteInput {
|
||||
name: String!
|
||||
type: String! # e.g. "drive", "s3", "sftp"
|
||||
parameters: JSON! # provider-specific config
|
||||
}
|
||||
```
|
||||
|
||||
### DeleteRCloneRemoteInput
|
||||
```graphql
|
||||
input DeleteRCloneRemoteInput {
|
||||
name: String!
|
||||
}
|
||||
```
|
||||
|
||||
### RCloneConfigFormInput
|
||||
```graphql
|
||||
input RCloneConfigFormInput {
|
||||
providerType: String
|
||||
showAdvanced: Boolean = false
|
||||
parameters: JSON
|
||||
}
|
||||
```
|
||||
|
||||
### InitiateFlashBackupInput
|
||||
```graphql
|
||||
input InitiateFlashBackupInput {
|
||||
remoteName: String! # configured remote name
|
||||
sourcePath: String! # e.g. "/boot"
|
||||
destinationPath: String! # remote destination path
|
||||
options: JSON # e.g. {"--dry-run": true}
|
||||
}
|
||||
```
|
||||
|
||||
### UPSConfigInput
|
||||
```graphql
|
||||
input UPSConfigInput {
|
||||
service: UPSServiceState # ENABLE or DISABLE
|
||||
upsCable: UPSCableType # USB, SIMPLE, SMART, ETHER, CUSTOM
|
||||
customUpsCable: String # only when upsCable=CUSTOM
|
||||
upsType: UPSType # USB, APCSMART, NET, SNMP, DUMB, PCNET, MODBUS
|
||||
device: String # /dev/ttyUSB0 or IP:port
|
||||
overrideUpsCapacity: Int # watts
|
||||
batteryLevel: Int # 0-100 percent shutdown threshold
|
||||
minutes: Int # runtime minutes shutdown threshold
|
||||
timeout: Int # seconds, 0=disable
|
||||
killUps: UPSKillPower # YES or NO
|
||||
}
|
||||
```
|
||||
|
||||
### PluginManagementInput
|
||||
```graphql
|
||||
input PluginManagementInput {
|
||||
names: [String!]!
|
||||
bundled: Boolean! = false # treat as bundled plugins
|
||||
restart: Boolean! = true # auto-restart API after operation
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Object Types (Full Field Reference)
|
||||
|
||||
### Key Types Quick Reference
|
||||
|
||||
| Type | Key Fields |
|
||||
|------|-----------|
|
||||
| `UnraidArray` | `state`, `capacity`, `boot`, `parities[]`, `parityCheckStatus`, `disks[]`, `caches[]` |
|
||||
| `ArrayDisk` | `id`, `idx`, `name`, `device`, `size`, `status`, `temp`, `numReads/Writes/Errors`, `fsSize/Free/Used`, `type`, `color`, `isSpinning` |
|
||||
| `Disk` | `id`, `device`, `type`, `name`, `vendor`, `size`, `serialNum`, `interfaceType`, `smartStatus`, `temperature`, `partitions[]`, `isSpinning` |
|
||||
| `DockerContainer` | `id`, `names[]`, `image`, `state`, `status`, `ports[]`, `autoStart`, `labels`, `mounts[]` |
|
||||
| `DockerNetwork` | `id`, `name`, `driver`, `scope`, `internal`, `attachable`, `containers`, `ipam` |
|
||||
| `VmDomain` | `id`, `name`, `state`, `uuid` (deprecated) |
|
||||
| `Notification` | `id`, `title`, `subject`, `description`, `importance`, `type`, `timestamp` |
|
||||
| `Info` | `time`, `baseboard`, `cpu`, `devices`, `display`, `memory`, `os`, `system`, `versions` |
|
||||
| `Metrics` | `cpu { percentTotal, cpus[] }`, `memory { total, used, free, percentTotal }` |
|
||||
| `Share` | `id`, `name`, `free`, `used`, `size`, `include[]`, `exclude[]`, `cache`, `comment` |
|
||||
| `ApiKey` | `id`, `key`, `name`, `description`, `roles[]`, `permissions[]`, `createdAt` |
|
||||
| `UserAccount` | `id`, `name`, `description`, `roles[]`, `permissions[]` |
|
||||
| `Server` | `id`, `name`, `status`, `guid`, `wanip`, `lanip`, `localurl`, `remoteurl`, `owner` |
|
||||
| `Service` | `id`, `name`, `online`, `uptime`, `version` |
|
||||
| `Owner` | `username`, `url`, `avatar` |
|
||||
| `Registration` | `type`, `state`, `keyFile`, `expiration`, `updateExpiration` |
|
||||
| `Vars` | 143 fields — hostname, timezone, array state, share config, registration, tuning params |
|
||||
| `UPSDevice` | `id`, `name`, `model`, `status`, `battery { chargeLevel, estimatedRuntime, health }`, `power { inputVoltage, outputVoltage, loadPercentage }` |
|
||||
| `UPSConfiguration` | `service`, `upsCable`, `upsType`, `device`, `batteryLevel`, `minutes`, `timeout`, `killUps`, + 4 more |
|
||||
| `RCloneRemote` | `name`, `type`, `parameters`, `config` |
|
||||
| `Settings` | `unified { dataSchema, uiSchema, values }`, `sso { oidcProviders[] }`, `api { version, extraOrigins }` |
|
||||
| `Flash` | `guid`, `vendor`, `product` |
|
||||
| `ParityCheck` | `date`, `duration`, `speed`, `status`, `errors`, `progress`, `correcting`, `paused`, `running` |
|
||||
| `Plugin` | `name`, `version`, `hasApiModule`, `hasCliModule` |
|
||||
|
||||
---
|
||||
|
||||
## Schema Statistics
|
||||
|
||||
| Category | Count |
|
||||
|----------|-------|
|
||||
| Query fields | 46 |
|
||||
| Mutation fields | 22 |
|
||||
| Subscription fields | 11 |
|
||||
| Object types | 94 |
|
||||
| Input types | 16 |
|
||||
| Enum types | 30 |
|
||||
| Scalar types | 10 |
|
||||
| Union types | 1 |
|
||||
| Interface types | 2 |
|
||||
| **Total types** | **156** |
|
||||
|
|
@ -116,9 +116,11 @@ unraid-mcp/
|
|||
| +-- DESTRUCTIVE_ACTIONS.md # Destructive action reference
|
||||
| +-- MARKETPLACE.md # Marketplace guide
|
||||
| +-- PUBLISHING.md # Publishing guide
|
||||
| +-- UNRAID_API_*.md # Unraid API documentation
|
||||
| +-- unraid-schema.graphql # Full GraphQL schema
|
||||
| +-- unraid-api-introspection.json # Schema introspection data
|
||||
| +-- UNRAID-API-SUMMARY.md # Condensed Unraid API overview
|
||||
| +-- UNRAID-API-CHANGES.md # Schema diff vs previous snapshot
|
||||
| +-- UNRAID-API-COMPLETE-REFERENCE.md # Full Unraid API reference
|
||||
| +-- UNRAID-SCHEMA.graphql # Full GraphQL schema
|
||||
| +-- UNRAID-API-INTROSPECTION.json # Schema introspection data
|
||||
|
|
||||
+-- .github/
|
||||
| +-- workflows/
|
||||
|
|
|
|||
|
|
@ -72,13 +72,18 @@ bash scripts/validate-marketplace.sh
|
|||
|
||||
### generate_unraid_api_reference.py
|
||||
|
||||
Generates API reference documentation from GraphQL schema introspection:
|
||||
Generates the canonical Unraid API docs from GraphQL schema introspection:
|
||||
|
||||
```bash
|
||||
python scripts/generate_unraid_api_reference.py
|
||||
```
|
||||
|
||||
Produces the docs in `docs/UNRAID_API_COMPLETE_REFERENCE.md`.
|
||||
Produces:
|
||||
- `docs/unraid/UNRAID-API-SUMMARY.md`
|
||||
- `docs/unraid/UNRAID-API-COMPLETE-REFERENCE.md`
|
||||
- `docs/unraid/UNRAID-API-INTROSPECTION.json`
|
||||
- `docs/unraid/UNRAID-SCHEMA.graphql`
|
||||
- `docs/unraid/UNRAID-API-CHANGES.md`
|
||||
|
||||
## Hook scripts (`hooks/scripts/`)
|
||||
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1,723 +0,0 @@
|
|||
# Unraid API v4.29.2 — Introspection Summary
|
||||
|
||||
> Auto-generated from live API introspection on 2026-03-15
|
||||
> Source: tootie (10.1.0.2:31337)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Query Fields](#query-fields)
|
||||
- [Mutation Fields](#mutation-fields)
|
||||
- [Subscription Fields](#subscription-fields)
|
||||
- [Enum Types](#enum-types)
|
||||
- [Input Types](#input-types)
|
||||
- [Object Types](#object-types)
|
||||
|
||||
## Query Fields
|
||||
|
||||
**46 fields**
|
||||
|
||||
| Field | Return Type | Arguments |
|
||||
|-------|-------------|-----------|
|
||||
| `apiKey` | `ApiKey` | `id: PrefixedID!` |
|
||||
| `apiKeyPossiblePermissions` | `[Permission!]!` | — |
|
||||
| `apiKeyPossibleRoles` | `[Role!]!` | — |
|
||||
| `apiKeys` | `[ApiKey!]!` | — |
|
||||
| `array` | `UnraidArray!` | — |
|
||||
| `config` | `Config!` | — |
|
||||
| `customization` | `Customization` | — |
|
||||
| `disk` | `Disk!` | `id: PrefixedID!` |
|
||||
| `disks` | `[Disk!]!` | — |
|
||||
| `docker` | `Docker!` | — |
|
||||
| `flash` | `Flash!` | — |
|
||||
| `getApiKeyCreationFormSchema` | `ApiKeyFormSettings!` | — |
|
||||
| `getAvailableAuthActions` | `[AuthAction!]!` | — |
|
||||
| `getPermissionsForRoles` | `[Permission!]!` | `roles: [Role!]!` |
|
||||
| `info` | `Info!` | — |
|
||||
| `isInitialSetup` | `Boolean!` | — |
|
||||
| `isSSOEnabled` | `Boolean!` | — |
|
||||
| `logFile` | `LogFileContent!` | `path: String!`, `lines: Int`, `startLine: Int` |
|
||||
| `logFiles` | `[LogFile!]!` | — |
|
||||
| `me` | `UserAccount!` | — |
|
||||
| `metrics` | `Metrics!` | — |
|
||||
| `notifications` | `Notifications!` | — |
|
||||
| `oidcConfiguration` | `OidcConfiguration!` | — |
|
||||
| `oidcProvider` | `OidcProvider` | `id: PrefixedID!` |
|
||||
| `oidcProviders` | `[OidcProvider!]!` | — |
|
||||
| `online` | `Boolean!` | — |
|
||||
| `owner` | `Owner!` | — |
|
||||
| `parityHistory` | `[ParityCheck!]!` | — |
|
||||
| `plugins` | `[Plugin!]!` | — |
|
||||
| `previewEffectivePermissions` | `[Permission!]!` | `roles: [Role!]`, `permissions: [AddPermissionInput!]` |
|
||||
| `publicOidcProviders` | `[PublicOidcProvider!]!` | — |
|
||||
| `publicPartnerInfo` | `PublicPartnerInfo` | — |
|
||||
| `publicTheme` | `Theme!` | — |
|
||||
| `rclone` | `RCloneBackupSettings!` | — |
|
||||
| `registration` | `Registration` | — |
|
||||
| `server` | `Server` | — |
|
||||
| `servers` | `[Server!]!` | — |
|
||||
| `services` | `[Service!]!` | — |
|
||||
| `settings` | `Settings!` | — |
|
||||
| `shares` | `[Share!]!` | — |
|
||||
| `upsConfiguration` | `UPSConfiguration!` | — |
|
||||
| `upsDeviceById` | `UPSDevice` | `id: String!` |
|
||||
| `upsDevices` | `[UPSDevice!]!` | — |
|
||||
| `validateOidcSession` | `OidcSessionValidation!` | `token: String!` |
|
||||
| `vars` | `Vars!` | — |
|
||||
| `vms` | `Vms!` | — |
|
||||
|
||||
## Mutation Fields
|
||||
|
||||
**22 fields**
|
||||
|
||||
| Field | Return Type | Arguments |
|
||||
|-------|-------------|-----------|
|
||||
| `addPlugin` | `Boolean!` | `input: PluginManagementInput!` |
|
||||
| `apiKey` | `ApiKeyMutations!` | — |
|
||||
| `archiveAll` | `NotificationOverview!` | `importance: NotificationImportance` |
|
||||
| `archiveNotification` | `Notification!` | `id: PrefixedID!` |
|
||||
| `archiveNotifications` | `NotificationOverview!` | `ids: [PrefixedID!]!` |
|
||||
| `array` | `ArrayMutations!` | — |
|
||||
| `configureUps` | `Boolean!` | `config: UPSConfigInput!` |
|
||||
| `createNotification` | `Notification!` | `input: NotificationData!` |
|
||||
| `customization` | `CustomizationMutations!` | — |
|
||||
| `deleteArchivedNotifications` | `NotificationOverview!` | — |
|
||||
| `deleteNotification` | `NotificationOverview!` | `id: PrefixedID!`, `type: NotificationType!` |
|
||||
| `docker` | `DockerMutations!` | — |
|
||||
| `initiateFlashBackup` | `FlashBackupStatus!` | `input: InitiateFlashBackupInput!` |
|
||||
| `parityCheck` | `ParityCheckMutations!` | — |
|
||||
| `rclone` | `RCloneMutations!` | — |
|
||||
| `recalculateOverview` | `NotificationOverview!` | — |
|
||||
| `removePlugin` | `Boolean!` | `input: PluginManagementInput!` |
|
||||
| `unarchiveAll` | `NotificationOverview!` | `importance: NotificationImportance` |
|
||||
| `unarchiveNotifications` | `NotificationOverview!` | `ids: [PrefixedID!]!` |
|
||||
| `unreadNotification` | `Notification!` | `id: PrefixedID!` |
|
||||
| `updateSettings` | `UpdateSettingsResponse!` | `input: JSON!` |
|
||||
| `vm` | `VmMutations!` | — |
|
||||
|
||||
## Subscription Fields
|
||||
|
||||
**11 fields**
|
||||
|
||||
| Field | Return Type | Arguments |
|
||||
|-------|-------------|-----------|
|
||||
| `arraySubscription` | `UnraidArray!` | — |
|
||||
| `logFile` | `LogFileContent!` | `path: String!` |
|
||||
| `notificationAdded` | `Notification!` | — |
|
||||
| `notificationsOverview` | `NotificationOverview!` | — |
|
||||
| `ownerSubscription` | `Owner!` | — |
|
||||
| `parityHistorySubscription` | `ParityCheck!` | — |
|
||||
| `serversSubscription` | `Server!` | — |
|
||||
| `systemMetricsCpu` | `CpuUtilization!` | — |
|
||||
| `systemMetricsCpuTelemetry` | `CpuPackages!` | — |
|
||||
| `systemMetricsMemory` | `MemoryUtilization!` | — |
|
||||
| `upsUpdates` | `UPSDevice!` | — |
|
||||
|
||||
## Enum Types
|
||||
|
||||
**30 enums**
|
||||
|
||||
### `ArrayDiskFsColor`
|
||||
|
||||
```
|
||||
GREEN_ON
|
||||
GREEN_BLINK
|
||||
BLUE_ON
|
||||
BLUE_BLINK
|
||||
YELLOW_ON
|
||||
YELLOW_BLINK
|
||||
RED_ON
|
||||
RED_OFF
|
||||
GREY_OFF
|
||||
```
|
||||
|
||||
### `ArrayDiskStatus`
|
||||
|
||||
```
|
||||
DISK_NP
|
||||
DISK_OK
|
||||
DISK_NP_MISSING
|
||||
DISK_INVALID
|
||||
DISK_WRONG
|
||||
DISK_DSBL
|
||||
DISK_NP_DSBL
|
||||
DISK_DSBL_NEW
|
||||
DISK_NEW
|
||||
```
|
||||
|
||||
### `ArrayDiskType`
|
||||
|
||||
```
|
||||
DATA
|
||||
PARITY
|
||||
FLASH
|
||||
CACHE
|
||||
```
|
||||
|
||||
### `ArrayState`
|
||||
|
||||
```
|
||||
STARTED
|
||||
STOPPED
|
||||
NEW_ARRAY
|
||||
RECON_DISK
|
||||
DISABLE_DISK
|
||||
SWAP_DSBL
|
||||
INVALID_EXPANSION
|
||||
PARITY_NOT_BIGGEST
|
||||
TOO_MANY_MISSING_DISKS
|
||||
NEW_DISK_TOO_SMALL
|
||||
NO_DATA_DISKS
|
||||
```
|
||||
|
||||
### `ArrayStateInputState`
|
||||
|
||||
```
|
||||
START
|
||||
STOP
|
||||
```
|
||||
|
||||
### `AuthAction`
|
||||
> Authentication actions with possession (e.g., create:any, read:own)
|
||||
|
||||
```
|
||||
CREATE_ANY
|
||||
CREATE_OWN
|
||||
READ_ANY
|
||||
READ_OWN
|
||||
UPDATE_ANY
|
||||
UPDATE_OWN
|
||||
DELETE_ANY
|
||||
DELETE_OWN
|
||||
```
|
||||
|
||||
### `AuthorizationOperator`
|
||||
> Operators for authorization rule matching
|
||||
|
||||
```
|
||||
EQUALS
|
||||
CONTAINS
|
||||
ENDS_WITH
|
||||
STARTS_WITH
|
||||
```
|
||||
|
||||
### `AuthorizationRuleMode`
|
||||
> Mode for evaluating authorization rules - OR (any rule passes) or AND (all rules must pass)
|
||||
|
||||
```
|
||||
OR
|
||||
AND
|
||||
```
|
||||
|
||||
### `ConfigErrorState`
|
||||
> Possible error states for configuration
|
||||
|
||||
```
|
||||
UNKNOWN_ERROR
|
||||
INELIGIBLE
|
||||
INVALID
|
||||
NO_KEY_SERVER
|
||||
WITHDRAWN
|
||||
```
|
||||
|
||||
### `ContainerPortType`
|
||||
|
||||
```
|
||||
TCP
|
||||
UDP
|
||||
```
|
||||
|
||||
### `ContainerState`
|
||||
|
||||
```
|
||||
RUNNING
|
||||
EXITED
|
||||
```
|
||||
|
||||
### `DiskFsType`
|
||||
> The type of filesystem on the disk partition
|
||||
|
||||
```
|
||||
XFS
|
||||
BTRFS
|
||||
VFAT
|
||||
ZFS
|
||||
EXT4
|
||||
NTFS
|
||||
```
|
||||
|
||||
### `DiskInterfaceType`
|
||||
> The type of interface the disk uses to connect to the system
|
||||
|
||||
```
|
||||
SAS
|
||||
SATA
|
||||
USB
|
||||
PCIE
|
||||
UNKNOWN
|
||||
```
|
||||
|
||||
### `DiskSmartStatus`
|
||||
> The SMART (Self-Monitoring, Analysis and Reporting Technology) status of the disk
|
||||
|
||||
```
|
||||
OK
|
||||
UNKNOWN
|
||||
```
|
||||
|
||||
### `NotificationImportance`
|
||||
|
||||
```
|
||||
ALERT
|
||||
INFO
|
||||
WARNING
|
||||
```
|
||||
|
||||
### `NotificationType`
|
||||
|
||||
```
|
||||
UNREAD
|
||||
ARCHIVE
|
||||
```
|
||||
|
||||
### `ParityCheckStatus`
|
||||
|
||||
```
|
||||
NEVER_RUN
|
||||
RUNNING
|
||||
PAUSED
|
||||
COMPLETED
|
||||
CANCELLED
|
||||
FAILED
|
||||
```
|
||||
|
||||
### `RegistrationState`
|
||||
|
||||
```
|
||||
TRIAL
|
||||
BASIC
|
||||
PLUS
|
||||
PRO
|
||||
STARTER
|
||||
UNLEASHED
|
||||
LIFETIME
|
||||
EEXPIRED
|
||||
EGUID
|
||||
EGUID1
|
||||
ETRIAL
|
||||
ENOKEYFILE
|
||||
ENOKEYFILE1
|
||||
ENOKEYFILE2
|
||||
ENOFLASH
|
||||
ENOFLASH1
|
||||
ENOFLASH2
|
||||
ENOFLASH3
|
||||
ENOFLASH4
|
||||
ENOFLASH5
|
||||
ENOFLASH6
|
||||
ENOFLASH7
|
||||
EBLACKLISTED
|
||||
EBLACKLISTED1
|
||||
EBLACKLISTED2
|
||||
ENOCONN
|
||||
```
|
||||
|
||||
### `Resource`
|
||||
> Available resources for permissions
|
||||
|
||||
```
|
||||
ACTIVATION_CODE
|
||||
API_KEY
|
||||
ARRAY
|
||||
CLOUD
|
||||
CONFIG
|
||||
CONNECT
|
||||
CONNECT__REMOTE_ACCESS
|
||||
CUSTOMIZATIONS
|
||||
DASHBOARD
|
||||
DISK
|
||||
DISPLAY
|
||||
DOCKER
|
||||
FLASH
|
||||
INFO
|
||||
LOGS
|
||||
ME
|
||||
NETWORK
|
||||
NOTIFICATIONS
|
||||
ONLINE
|
||||
OS
|
||||
OWNER
|
||||
PERMISSION
|
||||
REGISTRATION
|
||||
SERVERS
|
||||
SERVICES
|
||||
SHARE
|
||||
VARS
|
||||
VMS
|
||||
WELCOME
|
||||
```
|
||||
|
||||
### `Role`
|
||||
> Available roles for API keys and users
|
||||
|
||||
```
|
||||
ADMIN
|
||||
CONNECT
|
||||
GUEST
|
||||
VIEWER
|
||||
```
|
||||
|
||||
### `ServerStatus`
|
||||
|
||||
```
|
||||
ONLINE
|
||||
OFFLINE
|
||||
NEVER_CONNECTED
|
||||
```
|
||||
|
||||
### `Temperature`
|
||||
> Temperature unit
|
||||
|
||||
```
|
||||
CELSIUS
|
||||
FAHRENHEIT
|
||||
```
|
||||
|
||||
### `ThemeName`
|
||||
> The theme name
|
||||
|
||||
```
|
||||
azure
|
||||
black
|
||||
gray
|
||||
white
|
||||
```
|
||||
|
||||
### `UPSCableType`
|
||||
> UPS cable connection types
|
||||
|
||||
```
|
||||
USB
|
||||
SIMPLE
|
||||
SMART
|
||||
ETHER
|
||||
CUSTOM
|
||||
```
|
||||
|
||||
### `UPSKillPower`
|
||||
> Kill UPS power after shutdown option
|
||||
|
||||
```
|
||||
YES
|
||||
NO
|
||||
```
|
||||
|
||||
### `UPSServiceState`
|
||||
> Service state for UPS daemon
|
||||
|
||||
```
|
||||
ENABLE
|
||||
DISABLE
|
||||
```
|
||||
|
||||
### `UPSType`
|
||||
> UPS communication protocols
|
||||
|
||||
```
|
||||
USB
|
||||
APCSMART
|
||||
NET
|
||||
SNMP
|
||||
DUMB
|
||||
PCNET
|
||||
MODBUS
|
||||
```
|
||||
|
||||
### `UpdateStatus`
|
||||
> Update status of a container.
|
||||
|
||||
```
|
||||
UP_TO_DATE
|
||||
UPDATE_AVAILABLE
|
||||
REBUILD_READY
|
||||
UNKNOWN
|
||||
```
|
||||
|
||||
### `VmState`
|
||||
> The state of a virtual machine
|
||||
|
||||
```
|
||||
NOSTATE
|
||||
RUNNING
|
||||
IDLE
|
||||
PAUSED
|
||||
SHUTDOWN
|
||||
SHUTOFF
|
||||
CRASHED
|
||||
PMSUSPENDED
|
||||
```
|
||||
|
||||
### `registrationType`
|
||||
|
||||
```
|
||||
BASIC
|
||||
PLUS
|
||||
PRO
|
||||
STARTER
|
||||
UNLEASHED
|
||||
LIFETIME
|
||||
INVALID
|
||||
TRIAL
|
||||
```
|
||||
|
||||
## Input Types
|
||||
|
||||
**16 input types**
|
||||
|
||||
### `AddPermissionInput`
|
||||
|
||||
| Field | Type | Default |
|
||||
|-------|------|---------|
|
||||
| `resource` | `Resource!` | — |
|
||||
| `actions` | `[AuthAction!]!` | — |
|
||||
|
||||
### `AddRoleForApiKeyInput`
|
||||
|
||||
| Field | Type | Default |
|
||||
|-------|------|---------|
|
||||
| `apiKeyId` | `PrefixedID!` | — |
|
||||
| `role` | `Role!` | — |
|
||||
|
||||
### `ArrayDiskInput`
|
||||
|
||||
| Field | Type | Default |
|
||||
|-------|------|---------|
|
||||
| `id` | `PrefixedID!` | — |
|
||||
| `slot` | `Int` | — |
|
||||
|
||||
### `ArrayStateInput`
|
||||
|
||||
| Field | Type | Default |
|
||||
|-------|------|---------|
|
||||
| `desiredState` | `ArrayStateInputState!` | — |
|
||||
|
||||
### `CreateApiKeyInput`
|
||||
|
||||
| Field | Type | Default |
|
||||
|-------|------|---------|
|
||||
| `name` | `String!` | — |
|
||||
| `description` | `String` | — |
|
||||
| `roles` | `[Role!]` | — |
|
||||
| `permissions` | `[AddPermissionInput!]` | — |
|
||||
| `overwrite` | `Boolean` | — |
|
||||
|
||||
### `CreateRCloneRemoteInput`
|
||||
|
||||
| Field | Type | Default |
|
||||
|-------|------|---------|
|
||||
| `name` | `String!` | — |
|
||||
| `type` | `String!` | — |
|
||||
| `parameters` | `JSON!` | — |
|
||||
|
||||
### `DeleteApiKeyInput`
|
||||
|
||||
| Field | Type | Default |
|
||||
|-------|------|---------|
|
||||
| `ids` | `[PrefixedID!]!` | — |
|
||||
|
||||
### `DeleteRCloneRemoteInput`
|
||||
|
||||
| Field | Type | Default |
|
||||
|-------|------|---------|
|
||||
| `name` | `String!` | — |
|
||||
|
||||
### `InitiateFlashBackupInput`
|
||||
|
||||
| Field | Type | Default |
|
||||
|-------|------|---------|
|
||||
| `remoteName` | `String!` | — |
|
||||
| `sourcePath` | `String!` | — |
|
||||
| `destinationPath` | `String!` | — |
|
||||
| `options` | `JSON` | — |
|
||||
|
||||
### `NotificationData`
|
||||
|
||||
| Field | Type | Default |
|
||||
|-------|------|---------|
|
||||
| `title` | `String!` | — |
|
||||
| `subject` | `String!` | — |
|
||||
| `description` | `String!` | — |
|
||||
| `importance` | `NotificationImportance!` | — |
|
||||
| `link` | `String` | — |
|
||||
|
||||
### `NotificationFilter`
|
||||
|
||||
| Field | Type | Default |
|
||||
|-------|------|---------|
|
||||
| `importance` | `NotificationImportance` | — |
|
||||
| `type` | `NotificationType!` | — |
|
||||
| `offset` | `Int!` | — |
|
||||
| `limit` | `Int!` | — |
|
||||
|
||||
### `PluginManagementInput`
|
||||
|
||||
| Field | Type | Default |
|
||||
|-------|------|---------|
|
||||
| `names` | `[String!]!` | — |
|
||||
| `bundled` | `Boolean!` | false |
|
||||
| `restart` | `Boolean!` | true |
|
||||
|
||||
### `RCloneConfigFormInput`
|
||||
|
||||
| Field | Type | Default |
|
||||
|-------|------|---------|
|
||||
| `providerType` | `String` | — |
|
||||
| `showAdvanced` | `Boolean` | false |
|
||||
| `parameters` | `JSON` | — |
|
||||
|
||||
### `RemoveRoleFromApiKeyInput`
|
||||
|
||||
| Field | Type | Default |
|
||||
|-------|------|---------|
|
||||
| `apiKeyId` | `PrefixedID!` | — |
|
||||
| `role` | `Role!` | — |
|
||||
|
||||
### `UPSConfigInput`
|
||||
|
||||
| Field | Type | Default |
|
||||
|-------|------|---------|
|
||||
| `service` | `UPSServiceState` | — |
|
||||
| `upsCable` | `UPSCableType` | — |
|
||||
| `customUpsCable` | `String` | — |
|
||||
| `upsType` | `UPSType` | — |
|
||||
| `device` | `String` | — |
|
||||
| `overrideUpsCapacity` | `Int` | — |
|
||||
| `batteryLevel` | `Int` | — |
|
||||
| `minutes` | `Int` | — |
|
||||
| `timeout` | `Int` | — |
|
||||
| `killUps` | `UPSKillPower` | — |
|
||||
|
||||
### `UpdateApiKeyInput`
|
||||
|
||||
| Field | Type | Default |
|
||||
|-------|------|---------|
|
||||
| `id` | `PrefixedID!` | — |
|
||||
| `name` | `String` | — |
|
||||
| `description` | `String` | — |
|
||||
| `roles` | `[Role!]` | — |
|
||||
| `permissions` | `[AddPermissionInput!]` | — |
|
||||
|
||||
## Object Types
|
||||
|
||||
**94 object types**
|
||||
|
||||
| Type | Fields | Description |
|
||||
|------|--------|-------------|
|
||||
| `ActivationCode` | 11 | — |
|
||||
| `ApiConfig` | 5 | — |
|
||||
| `ApiKey` | 7 | — |
|
||||
| `ApiKeyFormSettings` | 4 | — |
|
||||
| `ApiKeyMutations` | 5 | API Key related mutations |
|
||||
| `ArrayCapacity` | 2 | — |
|
||||
| `ArrayDisk` | 24 | — |
|
||||
| `ArrayMutations` | 6 | — |
|
||||
| `Capacity` | 3 | — |
|
||||
| `Config` | 3 | — |
|
||||
| `ContainerHostConfig` | 1 | — |
|
||||
| `ContainerPort` | 4 | — |
|
||||
| `CoreVersions` | 3 | — |
|
||||
| `CpuLoad` | 8 | CPU load for a single core |
|
||||
| `CpuPackages` | 4 | — |
|
||||
| `CpuUtilization` | 3 | — |
|
||||
| `Customization` | 3 | — |
|
||||
| `CustomizationMutations` | 1 | Customization related mutations |
|
||||
| `Disk` | 20 | — |
|
||||
| `DiskPartition` | 3 | — |
|
||||
| `Docker` | 3 | — |
|
||||
| `DockerContainer` | 15 | — |
|
||||
| `DockerMutations` | 2 | — |
|
||||
| `DockerNetwork` | 15 | — |
|
||||
| `ExplicitStatusItem` | 2 | — |
|
||||
| `Flash` | 4 | — |
|
||||
| `FlashBackupStatus` | 2 | — |
|
||||
| `Info` | 11 | — |
|
||||
| `InfoBaseboard` | 8 | — |
|
||||
| `InfoCpu` | 20 | — |
|
||||
| `InfoDevices` | 5 | — |
|
||||
| `InfoDisplay` | 16 | — |
|
||||
| `InfoDisplayCase` | 5 | — |
|
||||
| `InfoGpu` | 7 | — |
|
||||
| `InfoMemory` | 2 | — |
|
||||
| `InfoNetwork` | 8 | — |
|
||||
| `InfoOs` | 15 | — |
|
||||
| `InfoPci` | 9 | — |
|
||||
| `InfoSystem` | 8 | — |
|
||||
| `InfoUsb` | 4 | — |
|
||||
| `InfoVersions` | 3 | — |
|
||||
| `KeyFile` | 2 | — |
|
||||
| `LogFile` | 4 | — |
|
||||
| `LogFileContent` | 4 | — |
|
||||
| `MemoryLayout` | 12 | — |
|
||||
| `MemoryUtilization` | 12 | — |
|
||||
| `Metrics` | 3 | System metrics including CPU and memory utilization |
|
||||
| `Notification` | 9 | — |
|
||||
| `NotificationCounts` | 4 | — |
|
||||
| `NotificationOverview` | 2 | — |
|
||||
| `Notifications` | 3 | — |
|
||||
| `OidcAuthorizationRule` | 3 | — |
|
||||
| `OidcConfiguration` | 2 | — |
|
||||
| `OidcProvider` | 15 | — |
|
||||
| `OidcSessionValidation` | 2 | — |
|
||||
| `OrganizerContainerResource` | 4 | — |
|
||||
| `OrganizerResource` | 4 | — |
|
||||
| `Owner` | 3 | — |
|
||||
| `PackageVersions` | 8 | — |
|
||||
| `ParityCheck` | 9 | — |
|
||||
| `ParityCheckMutations` | 4 | Parity check related mutations, WIP, response types and functionaliy will change |
|
||||
| `Permission` | 2 | — |
|
||||
| `Plugin` | 4 | — |
|
||||
| `ProfileModel` | 4 | — |
|
||||
| `PublicOidcProvider` | 6 | — |
|
||||
| `PublicPartnerInfo` | 4 | — |
|
||||
| `RCloneBackupConfigForm` | 3 | — |
|
||||
| `RCloneBackupSettings` | 3 | — |
|
||||
| `RCloneDrive` | 2 | — |
|
||||
| `RCloneMutations` | 2 | RClone related mutations |
|
||||
| `RCloneRemote` | 4 | — |
|
||||
| `Registration` | 6 | — |
|
||||
| `ResolvedOrganizerFolder` | 4 | — |
|
||||
| `ResolvedOrganizerV1` | 2 | — |
|
||||
| `ResolvedOrganizerView` | 4 | — |
|
||||
| `Server` | 10 | — |
|
||||
| `Service` | 5 | — |
|
||||
| `Settings` | 4 | — |
|
||||
| `Share` | 16 | — |
|
||||
| `SsoSettings` | 2 | — |
|
||||
| `Theme` | 7 | — |
|
||||
| `UPSBattery` | 3 | — |
|
||||
| `UPSConfiguration` | 14 | — |
|
||||
| `UPSDevice` | 6 | — |
|
||||
| `UPSPower` | 3 | — |
|
||||
| `UnifiedSettings` | 4 | — |
|
||||
| `UnraidArray` | 8 | — |
|
||||
| `UpdateSettingsResponse` | 3 | — |
|
||||
| `Uptime` | 1 | — |
|
||||
| `UserAccount` | 5 | — |
|
||||
| `Vars` | 143 | — |
|
||||
| `VmDomain` | 4 | — |
|
||||
| `VmMutations` | 7 | — |
|
||||
| `Vms` | 3 | — |
|
||||
|
||||
## Schema Statistics
|
||||
|
||||
| Category | Count |
|
||||
|----------|-------|
|
||||
| Query fields | 46 |
|
||||
| Mutation fields | 22 |
|
||||
| Subscription fields | 11 |
|
||||
| Object types | 94 |
|
||||
| Input types | 16 |
|
||||
| Enum types | 30 |
|
||||
| Scalar types | 10 |
|
||||
| Union types | 1 |
|
||||
| Interface types | 2 |
|
||||
| **Total types** | **156** |
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
server {
|
||||
listen 443 ssl;
|
||||
server_name unraid.*;
|
||||
include /config/nginx/ssl.conf;
|
||||
location / {
|
||||
include /config/nginx/proxy.conf;
|
||||
proxy_pass http://unraid-mcp:6970;
|
||||
}
|
||||
}
|
||||
399
docs/unraid/UNRAID-API-CHANGES.md
Normal file
399
docs/unraid/UNRAID-API-CHANGES.md
Normal file
|
|
@ -0,0 +1,399 @@
|
|||
# Unraid API Schema Changes
|
||||
|
||||
> Generated on 2026-04-05T12:02:01+00:00
|
||||
> Source: https://10-1-0-2.95d289568cc4a4bdc8e0d50284d6f455ec0eae5f.myunraid.net:31337/graphql
|
||||
|
||||
## Query fields
|
||||
|
||||
- Added: 13
|
||||
- `assignableDisks`
|
||||
- `cloud`
|
||||
- `connect`
|
||||
- `display`
|
||||
- `installedUnraidPlugins`
|
||||
- `internalBootContext`
|
||||
- `isFreshInstall`
|
||||
- `network`
|
||||
- `pluginInstallOperation`
|
||||
- `pluginInstallOperations`
|
||||
- `remoteAccess`
|
||||
- `systemTime`
|
||||
- `timeZoneOptions`
|
||||
- Removed: 2
|
||||
- `isInitialSetup`
|
||||
- `publicPartnerInfo`
|
||||
|
||||
## Mutation fields
|
||||
|
||||
- Added: 23
|
||||
- `connectSignIn`
|
||||
- `connectSignOut`
|
||||
- `createDockerFolder`
|
||||
- `createDockerFolderWithItems`
|
||||
- `deleteDockerEntries`
|
||||
- `enableDynamicRemoteAccess`
|
||||
- `moveDockerEntriesToFolder`
|
||||
- `moveDockerItemsToPosition`
|
||||
- `notifyIfUnique`
|
||||
- `onboarding`
|
||||
- `refreshDockerDigests`
|
||||
- `renameDockerFolder`
|
||||
- `resetDockerTemplateMappings`
|
||||
- `setDockerFolderChildren`
|
||||
- `setupRemoteAccess`
|
||||
- `syncDockerTemplatePaths`
|
||||
- `unraidPlugins`
|
||||
- `updateApiSettings`
|
||||
- `updateDockerViewPreferences`
|
||||
- `updateServerIdentity`
|
||||
- `updateSshSettings`
|
||||
- `updateSystemTime`
|
||||
- `updateTemperatureConfig`
|
||||
- Removed: 0
|
||||
|
||||
## Subscription fields
|
||||
|
||||
- Added: 5
|
||||
- `displaySubscription`
|
||||
- `dockerContainerStats`
|
||||
- `notificationsWarningsAndAlerts`
|
||||
- `pluginInstallUpdates`
|
||||
- `systemMetricsTemperature`
|
||||
- Removed: 0
|
||||
|
||||
## Type Changes
|
||||
|
||||
### ENUM
|
||||
|
||||
- Added: 10
|
||||
- `DynamicRemoteAccessType`
|
||||
- `MinigraphStatus`
|
||||
- `OnboardingStatus`
|
||||
- `PluginInstallStatus`
|
||||
- `SensorType`
|
||||
- `TemperatureStatus`
|
||||
- `TemperatureUnit`
|
||||
- `URL_TYPE`
|
||||
- `WAN_ACCESS_TYPE`
|
||||
- `WAN_FORWARD_TYPE`
|
||||
- Removed: 0
|
||||
|
||||
### INPUT_OBJECT
|
||||
|
||||
- Added: 27
|
||||
- `AccessUrlInput`
|
||||
- `AccessUrlObjectInput`
|
||||
- `ActivationCodeOverrideInput`
|
||||
- `BrandingConfigInput`
|
||||
- `ConnectSettingsInput`
|
||||
- `ConnectSignInInput`
|
||||
- `ConnectUserInfoInput`
|
||||
- `CreateInternalBootPoolInput`
|
||||
- `DockerAutostartEntryInput`
|
||||
- `EnableDynamicRemoteAccessInput`
|
||||
- `InstallPluginInput`
|
||||
- `IpmiConfigInput`
|
||||
- `LmSensorsConfigInput`
|
||||
- `OnboardingOverrideCompletionInput`
|
||||
- `OnboardingOverrideInput`
|
||||
- `PartnerConfigInput`
|
||||
- `PartnerInfoOverrideInput`
|
||||
- `PartnerLinkInput`
|
||||
- `SensorConfigInput`
|
||||
- `SetupRemoteAccessInput`
|
||||
- `SystemConfigInput`
|
||||
- `TemperatureConfigInput`
|
||||
- `TemperatureHistoryConfigInput`
|
||||
- `TemperatureSensorsConfigInput`
|
||||
- `TemperatureThresholdsConfigInput`
|
||||
- `UpdateSshInput`
|
||||
- `UpdateSystemTimeInput`
|
||||
- Removed: 0
|
||||
|
||||
### OBJECT
|
||||
|
||||
- Added: 50
|
||||
- `AccessUrl`
|
||||
- `AccessUrlObject`
|
||||
- `ApiKeyResponse`
|
||||
- `BrandingConfig`
|
||||
- `Cloud`
|
||||
- `CloudResponse`
|
||||
- `Connect`
|
||||
- `ConnectSettings`
|
||||
- `ConnectSettingsValues`
|
||||
- `DockerContainerLogLine`
|
||||
- `DockerContainerLogs`
|
||||
- `DockerContainerPortConflict`
|
||||
- `DockerContainerStats`
|
||||
- `DockerLanPortConflict`
|
||||
- `DockerPortConflictContainer`
|
||||
- `DockerPortConflicts`
|
||||
- `DockerTemplateSyncResult`
|
||||
- `DynamicRemoteAccessStatus`
|
||||
- `FlatOrganizerEntry`
|
||||
- `InfoNetworkInterface`
|
||||
- `IpmiConfig`
|
||||
- `Language`
|
||||
- `LmSensorsConfig`
|
||||
- `MinigraphqlResponse`
|
||||
- `Network`
|
||||
- `Onboarding`
|
||||
- `OnboardingInternalBootContext`
|
||||
- `OnboardingInternalBootResult`
|
||||
- `OnboardingMutations`
|
||||
- `OnboardingState`
|
||||
- `PartnerConfig`
|
||||
- `PartnerLink`
|
||||
- `PluginInstallEvent`
|
||||
- `PluginInstallOperation`
|
||||
- `RelayResponse`
|
||||
- `RemoteAccess`
|
||||
- `SensorConfig`
|
||||
- `SystemConfig`
|
||||
- `SystemTime`
|
||||
- `TailscaleExitNodeStatus`
|
||||
- `TailscaleStatus`
|
||||
- `TemperatureHistoryConfig`
|
||||
- `TemperatureMetrics`
|
||||
- `TemperatureReading`
|
||||
- `TemperatureSensor`
|
||||
- `TemperatureSensorsConfig`
|
||||
- `TemperatureSummary`
|
||||
- `TemperatureThresholdsConfig`
|
||||
- `TimeZoneOption`
|
||||
- `UnraidPluginsMutations`
|
||||
- Removed: 4
|
||||
- `OrganizerContainerResource`
|
||||
- `OrganizerResource`
|
||||
- `PublicPartnerInfo`
|
||||
- `ResolvedOrganizerFolder`
|
||||
|
||||
### SCALAR
|
||||
|
||||
- Added: 1
|
||||
- `URL`
|
||||
- Removed: 0
|
||||
|
||||
### UNION
|
||||
|
||||
- Added: 0
|
||||
- Removed: 1
|
||||
- `ResolvedOrganizerEntry`
|
||||
|
||||
## Type Signature Changes
|
||||
|
||||
### `ActivationCode` (OBJECT)
|
||||
|
||||
- Added members: 3
|
||||
- `branding(): BrandingConfig`
|
||||
- `partner(): PartnerConfig`
|
||||
- `system(): SystemConfig`
|
||||
- Removed members: 10
|
||||
- `background(): String`
|
||||
- `comment(): String`
|
||||
- `header(): String`
|
||||
- `headermetacolor(): String`
|
||||
- `partnerName(): String`
|
||||
- `partnerUrl(): String`
|
||||
- `serverName(): String`
|
||||
- `showBannerGradient(): Boolean`
|
||||
- `sysModel(): String`
|
||||
- `theme(): String`
|
||||
|
||||
### `ArrayDiskType` (ENUM)
|
||||
|
||||
- Added members: 1
|
||||
- `BOOT`
|
||||
- Removed members: 0
|
||||
|
||||
### `ArrayStateInput` (INPUT_OBJECT)
|
||||
|
||||
- Added members: 2
|
||||
- `decryptionKeyfile: String`
|
||||
- `decryptionPassword: String`
|
||||
- Removed members: 0
|
||||
|
||||
### `ContainerState` (ENUM)
|
||||
|
||||
- Added members: 1
|
||||
- `PAUSED`
|
||||
- Removed members: 0
|
||||
|
||||
### `Customization` (OBJECT)
|
||||
|
||||
- Added members: 2
|
||||
- `availableLanguages(): [Language!]`
|
||||
- `onboarding(): Onboarding!`
|
||||
- Removed members: 2
|
||||
- `partnerInfo(): PublicPartnerInfo`
|
||||
- `theme(): Theme!`
|
||||
|
||||
### `CustomizationMutations` (OBJECT)
|
||||
|
||||
- Added members: 1
|
||||
- `setLocale(locale: String!): String!`
|
||||
- Removed members: 0
|
||||
|
||||
### `Docker` (OBJECT)
|
||||
|
||||
- Added members: 7
|
||||
- `container(id: PrefixedID!): DockerContainer`
|
||||
- `containerUpdateStatuses(): [ExplicitStatusItem!]!`
|
||||
- `containers(): [DockerContainer!]!`
|
||||
- `logs(id: PrefixedID!, since: DateTime, tail: Int): DockerContainerLogs!`
|
||||
- `networks(): [DockerNetwork!]!`
|
||||
- `organizer(): ResolvedOrganizerV1!`
|
||||
- `portConflicts(): DockerPortConflicts!`
|
||||
- Removed members: 2
|
||||
- `containers(skipCache: Boolean! = false): [DockerContainer!]!`
|
||||
- `networks(skipCache: Boolean! = false): [DockerNetwork!]!`
|
||||
|
||||
### `DockerContainer` (OBJECT)
|
||||
|
||||
- Added members: 18
|
||||
- `autoStartOrder(): Int`
|
||||
- `autoStartWait(): Int`
|
||||
- `iconUrl(): String`
|
||||
- `isOrphaned(): Boolean!`
|
||||
- `isRebuildReady(): Boolean`
|
||||
- `isUpdateAvailable(): Boolean`
|
||||
- `lanIpPorts(): [String!]`
|
||||
- `projectUrl(): String`
|
||||
- `registryUrl(): String`
|
||||
- `shell(): String`
|
||||
- `sizeLog(): BigInt`
|
||||
- `sizeRw(): BigInt`
|
||||
- `supportUrl(): String`
|
||||
- `tailscaleEnabled(): Boolean!`
|
||||
- `tailscaleStatus(forceRefresh: Boolean = false): TailscaleStatus`
|
||||
- `templatePath(): String`
|
||||
- `templatePorts(): [ContainerPort!]`
|
||||
- `webUiUrl(): String`
|
||||
- Removed members: 0
|
||||
|
||||
### `DockerMutations` (OBJECT)
|
||||
|
||||
- Added members: 7
|
||||
- `pause(id: PrefixedID!): DockerContainer!`
|
||||
- `removeContainer(id: PrefixedID!, withImage: Boolean): Boolean!`
|
||||
- `unpause(id: PrefixedID!): DockerContainer!`
|
||||
- `updateAllContainers(): [DockerContainer!]!`
|
||||
- `updateAutostartConfiguration(entries: [DockerAutostartEntryInput!]!, persistUserPreferences: Boolean): Boolean!`
|
||||
- `updateContainer(id: PrefixedID!): DockerContainer!`
|
||||
- `updateContainers(ids: [PrefixedID!]!): [DockerContainer!]!`
|
||||
- Removed members: 0
|
||||
|
||||
### `Info` (OBJECT)
|
||||
|
||||
- Added members: 2
|
||||
- `networkInterfaces(): [InfoNetworkInterface!]!`
|
||||
- `primaryNetwork(): InfoNetworkInterface`
|
||||
- Removed members: 0
|
||||
|
||||
### `Metrics` (OBJECT)
|
||||
|
||||
- Added members: 1
|
||||
- `temperature(): TemperatureMetrics`
|
||||
- Removed members: 0
|
||||
|
||||
### `Mutation` (OBJECT)
|
||||
|
||||
- Added members: 23
|
||||
- `connectSignIn(input: ConnectSignInInput!): Boolean!`
|
||||
- `connectSignOut(): Boolean!`
|
||||
- `createDockerFolder(childrenIds: [String!], name: String!, parentId: String): ResolvedOrganizerV1!`
|
||||
- `createDockerFolderWithItems(name: String!, parentId: String, position: Float, sourceEntryIds: [String!]): ResolvedOrganizerV1!`
|
||||
- `deleteDockerEntries(entryIds: [String!]!): ResolvedOrganizerV1!`
|
||||
- `enableDynamicRemoteAccess(input: EnableDynamicRemoteAccessInput!): Boolean!`
|
||||
- `moveDockerEntriesToFolder(destinationFolderId: String!, sourceEntryIds: [String!]!): ResolvedOrganizerV1!`
|
||||
- `moveDockerItemsToPosition(destinationFolderId: String!, position: Float!, sourceEntryIds: [String!]!): ResolvedOrganizerV1!`
|
||||
- `notifyIfUnique(input: NotificationData!): Notification`
|
||||
- `onboarding(): OnboardingMutations!`
|
||||
- `refreshDockerDigests(): Boolean!`
|
||||
- `renameDockerFolder(folderId: String!, newName: String!): ResolvedOrganizerV1!`
|
||||
- `resetDockerTemplateMappings(): Boolean!`
|
||||
- `setDockerFolderChildren(childrenIds: [String!]!, folderId: String): ResolvedOrganizerV1!`
|
||||
- `setupRemoteAccess(input: SetupRemoteAccessInput!): Boolean!`
|
||||
- `syncDockerTemplatePaths(): DockerTemplateSyncResult!`
|
||||
- `unraidPlugins(): UnraidPluginsMutations!`
|
||||
- `updateApiSettings(input: ConnectSettingsInput!): ConnectSettingsValues!`
|
||||
- `updateDockerViewPreferences(prefs: JSON!, viewId: String = "default"): ResolvedOrganizerV1!`
|
||||
- `updateServerIdentity(comment: String, name: String!, sysModel: String): Server!`
|
||||
- `updateSshSettings(input: UpdateSshInput!): Vars!`
|
||||
- `updateSystemTime(input: UpdateSystemTimeInput!): SystemTime!`
|
||||
- `updateTemperatureConfig(input: TemperatureConfigInput!): Boolean!`
|
||||
- Removed members: 0
|
||||
|
||||
### `Notifications` (OBJECT)
|
||||
|
||||
- Added members: 1
|
||||
- `warningsAndAlerts(): [Notification!]!`
|
||||
- Removed members: 0
|
||||
|
||||
### `Query` (OBJECT)
|
||||
|
||||
- Added members: 13
|
||||
- `assignableDisks(): [Disk!]!`
|
||||
- `cloud(): Cloud!`
|
||||
- `connect(): Connect!`
|
||||
- `display(): InfoDisplay!`
|
||||
- `installedUnraidPlugins(): [String!]!`
|
||||
- `internalBootContext(): OnboardingInternalBootContext!`
|
||||
- `isFreshInstall(): Boolean!`
|
||||
- `network(): Network!`
|
||||
- `pluginInstallOperation(operationId: ID!): PluginInstallOperation`
|
||||
- `pluginInstallOperations(): [PluginInstallOperation!]!`
|
||||
- `remoteAccess(): RemoteAccess!`
|
||||
- `systemTime(): SystemTime!`
|
||||
- `timeZoneOptions(): [TimeZoneOption!]!`
|
||||
- Removed members: 2
|
||||
- `isInitialSetup(): Boolean!`
|
||||
- `publicPartnerInfo(): PublicPartnerInfo`
|
||||
|
||||
### `ResolvedOrganizerView` (OBJECT)
|
||||
|
||||
- Added members: 2
|
||||
- `flatEntries(): [FlatOrganizerEntry!]!`
|
||||
- `rootId(): String!`
|
||||
- Removed members: 1
|
||||
- `root(): ResolvedOrganizerEntry!`
|
||||
|
||||
### `Server` (OBJECT)
|
||||
|
||||
- Added members: 1
|
||||
- `comment(): String`
|
||||
- Removed members: 0
|
||||
|
||||
### `Subscription` (OBJECT)
|
||||
|
||||
- Added members: 5
|
||||
- `displaySubscription(): InfoDisplay!`
|
||||
- `dockerContainerStats(): DockerContainerStats!`
|
||||
- `notificationsWarningsAndAlerts(): [Notification!]!`
|
||||
- `pluginInstallUpdates(operationId: ID!): PluginInstallEvent!`
|
||||
- `systemMetricsTemperature(): TemperatureMetrics`
|
||||
- Removed members: 0
|
||||
|
||||
### `UPSPower` (OBJECT)
|
||||
|
||||
- Added members: 2
|
||||
- `currentPower(): Float`
|
||||
- `nominalPower(): Int`
|
||||
- Removed members: 0
|
||||
|
||||
### `UnraidArray` (OBJECT)
|
||||
|
||||
- Added members: 1
|
||||
- `bootDevices(): [ArrayDisk!]!`
|
||||
- Removed members: 0
|
||||
|
||||
### `Vars` (OBJECT)
|
||||
|
||||
- Added members: 5
|
||||
- `bootEligible(): Boolean`
|
||||
- `bootedFromFlashWithInternalBootSetup(): Boolean`
|
||||
- `enableBootTransfer(): String`
|
||||
- `reservedNames(): String`
|
||||
- `tpmGuid(): String`
|
||||
- Removed members: 0
|
||||
File diff suppressed because it is too large
Load diff
24899
docs/unraid/UNRAID-API-INTROSPECTION.json
Normal file
24899
docs/unraid/UNRAID-API-INTROSPECTION.json
Normal file
File diff suppressed because it is too large
Load diff
165
docs/unraid/UNRAID-API-SUMMARY.md
Normal file
165
docs/unraid/UNRAID-API-SUMMARY.md
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
# Unraid API Introspection Summary
|
||||
|
||||
> Auto-generated from live API introspection on 2026-04-05T12:02:01+00:00
|
||||
> Source: https://10-1-0-2.95d289568cc4a4bdc8e0d50284d6f455ec0eae5f.myunraid.net:31337/graphql
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Schema Summary](#schema-summary)
|
||||
- [Query Fields](#query-fields)
|
||||
- [Mutation Fields](#mutation-fields)
|
||||
- [Subscription Fields](#subscription-fields)
|
||||
- [Type Kinds](#type-kinds)
|
||||
|
||||
## Schema Summary
|
||||
- Query root: `Query`
|
||||
- Mutation root: `Mutation`
|
||||
- Subscription root: `Subscription`
|
||||
- Total types: **239**
|
||||
- Total directives: **6**
|
||||
|
||||
## Query Fields
|
||||
|
||||
| Field | Return Type | Arguments |
|
||||
|-------|-------------|-----------|
|
||||
| `apiKey` | `ApiKey` | id: PrefixedID! |
|
||||
| `apiKeyPossiblePermissions` | `[Permission!]!` | — |
|
||||
| `apiKeyPossibleRoles` | `[Role!]!` | — |
|
||||
| `apiKeys` | `[ApiKey!]!` | — |
|
||||
| `array` | `UnraidArray!` | — |
|
||||
| `assignableDisks` | `[Disk!]!` | — |
|
||||
| `cloud` | `Cloud!` | — |
|
||||
| `config` | `Config!` | — |
|
||||
| `connect` | `Connect!` | — |
|
||||
| `customization` | `Customization` | — |
|
||||
| `disk` | `Disk!` | id: PrefixedID! |
|
||||
| `disks` | `[Disk!]!` | — |
|
||||
| `display` | `InfoDisplay!` | — |
|
||||
| `docker` | `Docker!` | — |
|
||||
| `flash` | `Flash!` | — |
|
||||
| `getApiKeyCreationFormSchema` | `ApiKeyFormSettings!` | — |
|
||||
| `getAvailableAuthActions` | `[AuthAction!]!` | — |
|
||||
| `getPermissionsForRoles` | `[Permission!]!` | roles: [Role!]! |
|
||||
| `info` | `Info!` | — |
|
||||
| `installedUnraidPlugins` | `[String!]!` | — |
|
||||
| `internalBootContext` | `OnboardingInternalBootContext!` | — |
|
||||
| `isFreshInstall` | `Boolean!` | — |
|
||||
| `isSSOEnabled` | `Boolean!` | — |
|
||||
| `logFile` | `LogFileContent!` | lines: Int, path: String!, startLine: Int |
|
||||
| `logFiles` | `[LogFile!]!` | — |
|
||||
| `me` | `UserAccount!` | — |
|
||||
| `metrics` | `Metrics!` | — |
|
||||
| `network` | `Network!` | — |
|
||||
| `notifications` | `Notifications!` | — |
|
||||
| `oidcConfiguration` | `OidcConfiguration!` | — |
|
||||
| `oidcProvider` | `OidcProvider` | id: PrefixedID! |
|
||||
| `oidcProviders` | `[OidcProvider!]!` | — |
|
||||
| `online` | `Boolean!` | — |
|
||||
| `owner` | `Owner!` | — |
|
||||
| `parityHistory` | `[ParityCheck!]!` | — |
|
||||
| `pluginInstallOperation` | `PluginInstallOperation` | operationId: ID! |
|
||||
| `pluginInstallOperations` | `[PluginInstallOperation!]!` | — |
|
||||
| `plugins` | `[Plugin!]!` | — |
|
||||
| `previewEffectivePermissions` | `[Permission!]!` | permissions: [AddPermissionInput!], roles: [Role!] |
|
||||
| `publicOidcProviders` | `[PublicOidcProvider!]!` | — |
|
||||
| `publicTheme` | `Theme!` | — |
|
||||
| `rclone` | `RCloneBackupSettings!` | — |
|
||||
| `registration` | `Registration` | — |
|
||||
| `remoteAccess` | `RemoteAccess!` | — |
|
||||
| `server` | `Server` | — |
|
||||
| `servers` | `[Server!]!` | — |
|
||||
| `services` | `[Service!]!` | — |
|
||||
| `settings` | `Settings!` | — |
|
||||
| `shares` | `[Share!]!` | — |
|
||||
| `systemTime` | `SystemTime!` | — |
|
||||
| `timeZoneOptions` | `[TimeZoneOption!]!` | — |
|
||||
| `upsConfiguration` | `UPSConfiguration!` | — |
|
||||
| `upsDeviceById` | `UPSDevice` | id: String! |
|
||||
| `upsDevices` | `[UPSDevice!]!` | — |
|
||||
| `validateOidcSession` | `OidcSessionValidation!` | token: String! |
|
||||
| `vars` | `Vars!` | — |
|
||||
| `vms` | `Vms!` | — |
|
||||
|
||||
## Mutation Fields
|
||||
|
||||
| Field | Return Type | Arguments |
|
||||
|-------|-------------|-----------|
|
||||
| `addPlugin` | `Boolean!` | input: PluginManagementInput! |
|
||||
| `apiKey` | `ApiKeyMutations!` | — |
|
||||
| `archiveAll` | `NotificationOverview!` | importance: NotificationImportance |
|
||||
| `archiveNotification` | `Notification!` | id: PrefixedID! |
|
||||
| `archiveNotifications` | `NotificationOverview!` | ids: [PrefixedID!]! |
|
||||
| `array` | `ArrayMutations!` | — |
|
||||
| `configureUps` | `Boolean!` | config: UPSConfigInput! |
|
||||
| `connectSignIn` | `Boolean!` | input: ConnectSignInInput! |
|
||||
| `connectSignOut` | `Boolean!` | — |
|
||||
| `createDockerFolder` | `ResolvedOrganizerV1!` | childrenIds: [String!], name: String!, parentId: String |
|
||||
| `createDockerFolderWithItems` | `ResolvedOrganizerV1!` | name: String!, parentId: String, position: Float, sourceEntryIds: [String!] |
|
||||
| `createNotification` | `Notification!` | input: NotificationData! |
|
||||
| `customization` | `CustomizationMutations!` | — |
|
||||
| `deleteArchivedNotifications` | `NotificationOverview!` | — |
|
||||
| `deleteDockerEntries` | `ResolvedOrganizerV1!` | entryIds: [String!]! |
|
||||
| `deleteNotification` | `NotificationOverview!` | id: PrefixedID!, type: NotificationType! |
|
||||
| `docker` | `DockerMutations!` | — |
|
||||
| `enableDynamicRemoteAccess` | `Boolean!` | input: EnableDynamicRemoteAccessInput! |
|
||||
| `initiateFlashBackup` | `FlashBackupStatus!` | input: InitiateFlashBackupInput! |
|
||||
| `moveDockerEntriesToFolder` | `ResolvedOrganizerV1!` | destinationFolderId: String!, sourceEntryIds: [String!]! |
|
||||
| `moveDockerItemsToPosition` | `ResolvedOrganizerV1!` | destinationFolderId: String!, position: Float!, sourceEntryIds: [String!]! |
|
||||
| `notifyIfUnique` | `Notification` | input: NotificationData! |
|
||||
| `onboarding` | `OnboardingMutations!` | — |
|
||||
| `parityCheck` | `ParityCheckMutations!` | — |
|
||||
| `rclone` | `RCloneMutations!` | — |
|
||||
| `recalculateOverview` | `NotificationOverview!` | — |
|
||||
| `refreshDockerDigests` | `Boolean!` | — |
|
||||
| `removePlugin` | `Boolean!` | input: PluginManagementInput! |
|
||||
| `renameDockerFolder` | `ResolvedOrganizerV1!` | folderId: String!, newName: String! |
|
||||
| `resetDockerTemplateMappings` | `Boolean!` | — |
|
||||
| `setDockerFolderChildren` | `ResolvedOrganizerV1!` | childrenIds: [String!]!, folderId: String |
|
||||
| `setupRemoteAccess` | `Boolean!` | input: SetupRemoteAccessInput! |
|
||||
| `syncDockerTemplatePaths` | `DockerTemplateSyncResult!` | — |
|
||||
| `unarchiveAll` | `NotificationOverview!` | importance: NotificationImportance |
|
||||
| `unarchiveNotifications` | `NotificationOverview!` | ids: [PrefixedID!]! |
|
||||
| `unraidPlugins` | `UnraidPluginsMutations!` | — |
|
||||
| `unreadNotification` | `Notification!` | id: PrefixedID! |
|
||||
| `updateApiSettings` | `ConnectSettingsValues!` | input: ConnectSettingsInput! |
|
||||
| `updateDockerViewPreferences` | `ResolvedOrganizerV1!` | prefs: JSON!, viewId: String (default: "default") |
|
||||
| `updateServerIdentity` | `Server!` | comment: String, name: String!, sysModel: String |
|
||||
| `updateSettings` | `UpdateSettingsResponse!` | input: JSON! |
|
||||
| `updateSshSettings` | `Vars!` | input: UpdateSshInput! |
|
||||
| `updateSystemTime` | `SystemTime!` | input: UpdateSystemTimeInput! |
|
||||
| `updateTemperatureConfig` | `Boolean!` | input: TemperatureConfigInput! |
|
||||
| `vm` | `VmMutations!` | — |
|
||||
|
||||
## Subscription Fields
|
||||
|
||||
| Field | Return Type | Arguments |
|
||||
|-------|-------------|-----------|
|
||||
| `arraySubscription` | `UnraidArray!` | — |
|
||||
| `displaySubscription` | `InfoDisplay!` | — |
|
||||
| `dockerContainerStats` | `DockerContainerStats!` | — |
|
||||
| `logFile` | `LogFileContent!` | path: String! |
|
||||
| `notificationAdded` | `Notification!` | — |
|
||||
| `notificationsOverview` | `NotificationOverview!` | — |
|
||||
| `notificationsWarningsAndAlerts` | `[Notification!]!` | — |
|
||||
| `ownerSubscription` | `Owner!` | — |
|
||||
| `parityHistorySubscription` | `ParityCheck!` | — |
|
||||
| `pluginInstallUpdates` | `PluginInstallEvent!` | operationId: ID! |
|
||||
| `serversSubscription` | `Server!` | — |
|
||||
| `systemMetricsCpu` | `CpuUtilization!` | — |
|
||||
| `systemMetricsCpuTelemetry` | `CpuPackages!` | — |
|
||||
| `systemMetricsMemory` | `MemoryUtilization!` | — |
|
||||
| `systemMetricsTemperature` | `TemperatureMetrics` | — |
|
||||
| `upsUpdates` | `UPSDevice!` | — |
|
||||
|
||||
## Type Kinds
|
||||
|
||||
- `ENUM`: 40
|
||||
- `INPUT_OBJECT`: 43
|
||||
- `INTERFACE`: 2
|
||||
- `OBJECT`: 143
|
||||
- `SCALAR`: 11
|
||||
|
||||
## Notes
|
||||
|
||||
- This summary is intentionally condensed; the full schema reference lives in `UNRAID-API-COMPLETE-REFERENCE.md`.
|
||||
- Raw schema exports live in `UNRAID-API-INTROSPECTION.json` and `UNRAID-SCHEMA.graphql`.
|
||||
|
|
@ -346,11 +346,6 @@ type Disk implements Node {
|
|||
"""The serial number of the disk"""
|
||||
serialNum: String!
|
||||
|
||||
"""
|
||||
Device identifier from emhttp devs.ini used by disk assignment commands
|
||||
"""
|
||||
emhttpDeviceId: String
|
||||
|
||||
"""The interface type of the disk"""
|
||||
interfaceType: DiskInterfaceType!
|
||||
|
||||
|
|
@ -552,6 +547,7 @@ type Vars implements Node {
|
|||
flashGuid: String
|
||||
flashProduct: String
|
||||
flashVendor: String
|
||||
tpmGuid: String
|
||||
regCheck: String
|
||||
regFile: String
|
||||
regGuid: String
|
||||
|
|
@ -595,6 +591,7 @@ type Vars implements Node {
|
|||
fsState: String
|
||||
bootEligible: Boolean
|
||||
enableBootTransfer: String
|
||||
bootedFromFlashWithInternalBootSetup: Boolean
|
||||
reservedNames: String
|
||||
|
||||
"""Human friendly string of array events happening"""
|
||||
|
|
@ -632,6 +629,14 @@ enum ConfigErrorState {
|
|||
WITHDRAWN
|
||||
}
|
||||
|
||||
type ApiConfig {
|
||||
version: String!
|
||||
extraOrigins: [String!]!
|
||||
sandbox: Boolean
|
||||
ssoSubIds: [String!]!
|
||||
plugins: [String!]!
|
||||
}
|
||||
|
||||
type Permission {
|
||||
resource: Resource!
|
||||
|
||||
|
|
@ -724,6 +729,65 @@ enum Role {
|
|||
VIEWER
|
||||
}
|
||||
|
||||
type NotificationCounts {
|
||||
info: Int!
|
||||
warning: Int!
|
||||
alert: Int!
|
||||
total: Int!
|
||||
}
|
||||
|
||||
type NotificationOverview {
|
||||
unread: NotificationCounts!
|
||||
archive: NotificationCounts!
|
||||
}
|
||||
|
||||
type Notification implements Node {
|
||||
id: PrefixedID!
|
||||
|
||||
"""Also known as 'event'"""
|
||||
title: String!
|
||||
subject: String!
|
||||
description: String!
|
||||
importance: NotificationImportance!
|
||||
link: String
|
||||
type: NotificationType!
|
||||
|
||||
"""ISO Timestamp for when the notification occurred"""
|
||||
timestamp: String
|
||||
formattedTimestamp: String
|
||||
}
|
||||
|
||||
enum NotificationImportance {
|
||||
ALERT
|
||||
INFO
|
||||
WARNING
|
||||
}
|
||||
|
||||
enum NotificationType {
|
||||
UNREAD
|
||||
ARCHIVE
|
||||
}
|
||||
|
||||
type Notifications implements Node {
|
||||
id: PrefixedID!
|
||||
|
||||
"""A cached overview of the notifications in the system & their severity."""
|
||||
overview: NotificationOverview!
|
||||
list(filter: NotificationFilter!): [Notification!]!
|
||||
|
||||
"""
|
||||
Deduplicated list of unread warning and alert notifications, sorted latest first.
|
||||
"""
|
||||
warningsAndAlerts: [Notification!]!
|
||||
}
|
||||
|
||||
input NotificationFilter {
|
||||
importance: NotificationImportance
|
||||
type: NotificationType!
|
||||
offset: Int!
|
||||
limit: Int!
|
||||
}
|
||||
|
||||
type SsoSettings implements Node {
|
||||
id: PrefixedID!
|
||||
|
||||
|
|
@ -758,7 +822,7 @@ interface FormSchema {
|
|||
"""
|
||||
The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf).
|
||||
"""
|
||||
scalar JSON @specifiedBy(url: "http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf")
|
||||
scalar JSON
|
||||
|
||||
type ApiKeyFormSettings implements Node & FormSchema {
|
||||
id: PrefixedID!
|
||||
|
|
@ -1049,6 +1113,9 @@ type Onboarding {
|
|||
"""The activation code from the .activationcode file, if present"""
|
||||
activationCode: String
|
||||
|
||||
"""Whether the onboarding modal should currently be shown"""
|
||||
shouldOpen: Boolean!
|
||||
|
||||
"""Runtime onboarding state values used by the onboarding flow"""
|
||||
onboardingState: OnboardingState!
|
||||
}
|
||||
|
|
@ -1064,10 +1131,13 @@ enum OnboardingStatus {
|
|||
}
|
||||
|
||||
type Customization {
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **ACTIVATION_CODE**"
|
||||
activationCode: ActivationCode
|
||||
|
||||
"""Onboarding completion state and context"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **CUSTOMIZATIONS**\n\n#### Description:\n\nOnboarding completion state and context"
|
||||
onboarding: Onboarding!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DISPLAY**"
|
||||
availableLanguages: [Language!]
|
||||
}
|
||||
|
||||
|
|
@ -1078,6 +1148,18 @@ type OnboardingInternalBootResult {
|
|||
output: String!
|
||||
}
|
||||
|
||||
"""Current onboarding context for configuring internal boot"""
|
||||
type OnboardingInternalBootContext {
|
||||
arrayStopped: Boolean!
|
||||
bootEligible: Boolean
|
||||
bootedFromFlashWithInternalBootSetup: Boolean!
|
||||
enableBootTransfer: String
|
||||
reservedNames: [String!]!
|
||||
shareNames: [String!]!
|
||||
poolNames: [String!]!
|
||||
assignableDisks: [Disk!]!
|
||||
}
|
||||
|
||||
type RCloneDrive {
|
||||
"""Provider name"""
|
||||
name: String!
|
||||
|
|
@ -1166,30 +1248,38 @@ type PluginInstallEvent {
|
|||
}
|
||||
|
||||
type ArrayMutations {
|
||||
"""Set array state"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **ARRAY**\n\n#### Description:\n\nSet array state"
|
||||
setState(input: ArrayStateInput!): UnraidArray!
|
||||
|
||||
"""Add new disk to array"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **ARRAY**\n\n#### Description:\n\nAdd new disk to array"
|
||||
addDiskToArray(input: ArrayDiskInput!): UnraidArray!
|
||||
|
||||
"""
|
||||
Remove existing disk from array. NOTE: The array must be stopped before running this otherwise it'll throw an error.
|
||||
"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **ARRAY**\n\n#### Description:\n\nRemove existing disk from array. NOTE: The array must be stopped before running this otherwise it'll throw an error."
|
||||
removeDiskFromArray(input: ArrayDiskInput!): UnraidArray!
|
||||
|
||||
"""Mount a disk in the array"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **ARRAY**\n\n#### Description:\n\nMount a disk in the array"
|
||||
mountArrayDisk(id: PrefixedID!): ArrayDisk!
|
||||
|
||||
"""Unmount a disk from the array"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **ARRAY**\n\n#### Description:\n\nUnmount a disk from the array"
|
||||
unmountArrayDisk(id: PrefixedID!): ArrayDisk!
|
||||
|
||||
"""Clear statistics for a disk in the array"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **ARRAY**\n\n#### Description:\n\nClear statistics for a disk in the array"
|
||||
clearArrayDiskStatistics(id: PrefixedID!): Boolean!
|
||||
}
|
||||
|
||||
input ArrayStateInput {
|
||||
"""Array state"""
|
||||
desiredState: ArrayStateInputState!
|
||||
|
||||
"""
|
||||
Optional password used to unlock encrypted array disks when starting the array
|
||||
"""
|
||||
decryptionPassword: String
|
||||
|
||||
"""
|
||||
Optional keyfile contents used to unlock encrypted array disks when starting the array. Accepts a data URL or raw base64 payload.
|
||||
"""
|
||||
decryptionKeyfile: String
|
||||
}
|
||||
|
||||
enum ArrayStateInputState {
|
||||
|
|
@ -1206,31 +1296,31 @@ input ArrayDiskInput {
|
|||
}
|
||||
|
||||
type DockerMutations {
|
||||
"""Start a container"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **DOCKER**\n\n#### Description:\n\nStart a container"
|
||||
start(id: PrefixedID!): DockerContainer!
|
||||
|
||||
"""Stop a container"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **DOCKER**\n\n#### Description:\n\nStop a container"
|
||||
stop(id: PrefixedID!): DockerContainer!
|
||||
|
||||
"""Pause (Suspend) a container"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **DOCKER**\n\n#### Description:\n\nPause (Suspend) a container"
|
||||
pause(id: PrefixedID!): DockerContainer!
|
||||
|
||||
"""Unpause (Resume) a container"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **DOCKER**\n\n#### Description:\n\nUnpause (Resume) a container"
|
||||
unpause(id: PrefixedID!): DockerContainer!
|
||||
|
||||
"""Remove a container"""
|
||||
"\n#### Required Permissions:\n\n- Action: **DELETE_ANY**\n- Resource: **DOCKER**\n\n#### Description:\n\nRemove a container"
|
||||
removeContainer(id: PrefixedID!, withImage: Boolean): Boolean!
|
||||
|
||||
"""Update auto-start configuration for Docker containers"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **DOCKER**\n\n#### Description:\n\nUpdate auto-start configuration for Docker containers"
|
||||
updateAutostartConfiguration(entries: [DockerAutostartEntryInput!]!, persistUserPreferences: Boolean): Boolean!
|
||||
|
||||
"""Update a container to the latest image"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **DOCKER**\n\n#### Description:\n\nUpdate a container to the latest image"
|
||||
updateContainer(id: PrefixedID!): DockerContainer!
|
||||
|
||||
"""Update multiple containers to the latest images"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **DOCKER**\n\n#### Description:\n\nUpdate multiple containers to the latest images"
|
||||
updateContainers(ids: [PrefixedID!]!): [DockerContainer!]!
|
||||
|
||||
"""Update all containers that have available updates"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **DOCKER**\n\n#### Description:\n\nUpdate all containers that have available updates"
|
||||
updateAllContainers: [DockerContainer!]!
|
||||
}
|
||||
|
||||
|
|
@ -1246,43 +1336,43 @@ input DockerAutostartEntryInput {
|
|||
}
|
||||
|
||||
type VmMutations {
|
||||
"""Start a virtual machine"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **VMS**\n\n#### Description:\n\nStart a virtual machine"
|
||||
start(id: PrefixedID!): Boolean!
|
||||
|
||||
"""Stop a virtual machine"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **VMS**\n\n#### Description:\n\nStop a virtual machine"
|
||||
stop(id: PrefixedID!): Boolean!
|
||||
|
||||
"""Pause a virtual machine"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **VMS**\n\n#### Description:\n\nPause a virtual machine"
|
||||
pause(id: PrefixedID!): Boolean!
|
||||
|
||||
"""Resume a virtual machine"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **VMS**\n\n#### Description:\n\nResume a virtual machine"
|
||||
resume(id: PrefixedID!): Boolean!
|
||||
|
||||
"""Force stop a virtual machine"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **VMS**\n\n#### Description:\n\nForce stop a virtual machine"
|
||||
forceStop(id: PrefixedID!): Boolean!
|
||||
|
||||
"""Reboot a virtual machine"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **VMS**\n\n#### Description:\n\nReboot a virtual machine"
|
||||
reboot(id: PrefixedID!): Boolean!
|
||||
|
||||
"""Reset a virtual machine"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **VMS**\n\n#### Description:\n\nReset a virtual machine"
|
||||
reset(id: PrefixedID!): Boolean!
|
||||
}
|
||||
|
||||
"""API Key related mutations"""
|
||||
type ApiKeyMutations {
|
||||
"""Create an API key"""
|
||||
"\n#### Required Permissions:\n\n- Action: **CREATE_ANY**\n- Resource: **API_KEY**\n\n#### Description:\n\nCreate an API key"
|
||||
create(input: CreateApiKeyInput!): ApiKey!
|
||||
|
||||
"""Add a role to an API key"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **API_KEY**\n\n#### Description:\n\nAdd a role to an API key"
|
||||
addRole(input: AddRoleForApiKeyInput!): Boolean!
|
||||
|
||||
"""Remove a role from an API key"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **API_KEY**\n\n#### Description:\n\nRemove a role from an API key"
|
||||
removeRole(input: RemoveRoleFromApiKeyInput!): Boolean!
|
||||
|
||||
"""Delete one or more API keys"""
|
||||
"\n#### Required Permissions:\n\n- Action: **DELETE_ANY**\n- Resource: **API_KEY**\n\n#### Description:\n\nDelete one or more API keys"
|
||||
delete(input: DeleteApiKeyInput!): Boolean!
|
||||
|
||||
"""Update an API key"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **API_KEY**\n\n#### Description:\n\nUpdate an API key"
|
||||
update(input: UpdateApiKeyInput!): ApiKey!
|
||||
}
|
||||
|
||||
|
|
@ -1327,13 +1417,13 @@ input UpdateApiKeyInput {
|
|||
|
||||
"""Customization related mutations"""
|
||||
type CustomizationMutations {
|
||||
"""Update the UI theme (writes dynamix.cfg)"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **CUSTOMIZATIONS**\n\n#### Description:\n\nUpdate the UI theme (writes dynamix.cfg)"
|
||||
setTheme(
|
||||
"""Theme to apply"""
|
||||
theme: ThemeName!
|
||||
): Theme!
|
||||
|
||||
"""Update the display locale (language)"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **CUSTOMIZATIONS**\n\n#### Description:\n\nUpdate the display locale (language)"
|
||||
setLocale(
|
||||
"""Locale code to apply (e.g. en_US)"""
|
||||
locale: String!
|
||||
|
|
@ -1344,25 +1434,25 @@ type CustomizationMutations {
|
|||
Parity check related mutations, WIP, response types and functionaliy will change
|
||||
"""
|
||||
type ParityCheckMutations {
|
||||
"""Start a parity check"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **ARRAY**\n\n#### Description:\n\nStart a parity check"
|
||||
start(correct: Boolean!): JSON!
|
||||
|
||||
"""Pause a parity check"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **ARRAY**\n\n#### Description:\n\nPause a parity check"
|
||||
pause: JSON!
|
||||
|
||||
"""Resume a parity check"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **ARRAY**\n\n#### Description:\n\nResume a parity check"
|
||||
resume: JSON!
|
||||
|
||||
"""Cancel a parity check"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **ARRAY**\n\n#### Description:\n\nCancel a parity check"
|
||||
cancel: JSON!
|
||||
}
|
||||
|
||||
"""RClone related mutations"""
|
||||
type RCloneMutations {
|
||||
"""Create a new RClone remote"""
|
||||
"\n#### Required Permissions:\n\n- Action: **CREATE_ANY**\n- Resource: **FLASH**\n\n#### Description:\n\nCreate a new RClone remote"
|
||||
createRCloneRemote(input: CreateRCloneRemoteInput!): RCloneRemote!
|
||||
|
||||
"""Delete an existing RClone remote"""
|
||||
"\n#### Required Permissions:\n\n- Action: **DELETE_ANY**\n- Resource: **FLASH**\n\n#### Description:\n\nDelete an existing RClone remote"
|
||||
deleteRCloneRemote(input: DeleteRCloneRemoteInput!): Boolean!
|
||||
}
|
||||
|
||||
|
|
@ -1378,20 +1468,35 @@ input DeleteRCloneRemoteInput {
|
|||
|
||||
"""Onboarding related mutations"""
|
||||
type OnboardingMutations {
|
||||
"""Mark onboarding as completed"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **WELCOME**\n\n#### Description:\n\nMark onboarding as completed"
|
||||
completeOnboarding: Onboarding!
|
||||
|
||||
"""Reset onboarding progress (for testing)"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **WELCOME**\n\n#### Description:\n\nReset onboarding progress (for testing)"
|
||||
resetOnboarding: Onboarding!
|
||||
|
||||
"""Override onboarding state for testing (in-memory only)"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **WELCOME**\n\n#### Description:\n\nForce the onboarding modal open"
|
||||
openOnboarding: Onboarding!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **WELCOME**\n\n#### Description:\n\nClose the onboarding modal"
|
||||
closeOnboarding: Onboarding!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **WELCOME**\n\n#### Description:\n\nTemporarily bypass onboarding in API memory"
|
||||
bypassOnboarding: Onboarding!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **WELCOME**\n\n#### Description:\n\nClear the temporary onboarding bypass"
|
||||
resumeOnboarding: Onboarding!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **WELCOME**\n\n#### Description:\n\nOverride onboarding state for testing (in-memory only)"
|
||||
setOnboardingOverride(input: OnboardingOverrideInput!): Onboarding!
|
||||
|
||||
"""Clear onboarding override state and reload from disk"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **WELCOME**\n\n#### Description:\n\nClear onboarding override state and reload from disk"
|
||||
clearOnboardingOverride: Onboarding!
|
||||
|
||||
"""Create and configure internal boot pool via emcmd operations"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **WELCOME**\n\n#### Description:\n\nCreate and configure internal boot pool via emcmd operations"
|
||||
createInternalBootPool(input: CreateInternalBootPoolInput!): OnboardingInternalBootResult!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **WELCOME**\n\n#### Description:\n\nRefresh the internal boot onboarding context from the latest emhttp state"
|
||||
refreshInternalBootContext: OnboardingInternalBootContext!
|
||||
}
|
||||
|
||||
"""Onboarding override input for testing"""
|
||||
|
|
@ -1406,6 +1511,7 @@ input OnboardingOverrideInput {
|
|||
input OnboardingOverrideCompletionInput {
|
||||
completed: Boolean
|
||||
completedAtVersion: String
|
||||
forceOpen: Boolean
|
||||
}
|
||||
|
||||
"""Activation code override input"""
|
||||
|
|
@ -1478,10 +1584,10 @@ input CreateInternalBootPoolInput {
|
|||
|
||||
"""Unraid plugin management mutations"""
|
||||
type UnraidPluginsMutations {
|
||||
"""Install an Unraid plugin and track installation progress"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **CONFIG**\n\n#### Description:\n\nInstall an Unraid plugin and track installation progress"
|
||||
installPlugin(input: InstallPluginInput!): PluginInstallOperation!
|
||||
|
||||
"""Install an Unraid language pack and track installation progress"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **CONFIG**\n\n#### Description:\n\nInstall an Unraid language pack and track installation progress"
|
||||
installLanguage(input: InstallPluginInput!): PluginInstallOperation!
|
||||
}
|
||||
|
||||
|
|
@ -2121,36 +2227,40 @@ type DockerContainer implements Node {
|
|||
autoStartWait: Int
|
||||
templatePath: String
|
||||
|
||||
"""Project/Product homepage URL"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DOCKER**\n\n#### Description:\n\nProject/Product homepage URL"
|
||||
projectUrl: String
|
||||
|
||||
"""Registry/Docker Hub URL"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DOCKER**\n\n#### Description:\n\nRegistry/Docker Hub URL"
|
||||
registryUrl: String
|
||||
|
||||
"""Support page/thread URL"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DOCKER**\n\n#### Description:\n\nSupport page/thread URL"
|
||||
supportUrl: String
|
||||
|
||||
"""Icon URL"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DOCKER**\n\n#### Description:\n\nIcon URL"
|
||||
iconUrl: String
|
||||
|
||||
"""Resolved WebUI URL from template"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DOCKER**\n\n#### Description:\n\nResolved WebUI URL from template"
|
||||
webUiUrl: String
|
||||
|
||||
"""Shell to use for console access (from template)"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DOCKER**\n\n#### Description:\n\nShell to use for console access (from template)"
|
||||
shell: String
|
||||
|
||||
"""Port mappings from template (used when container is not running)"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DOCKER**\n\n#### Description:\n\nPort mappings from template (used when container is not running)"
|
||||
templatePorts: [ContainerPort!]
|
||||
|
||||
"""Whether the container is orphaned (no template found)"""
|
||||
isOrphaned: Boolean!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DOCKER**"
|
||||
isUpdateAvailable: Boolean
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DOCKER**"
|
||||
isRebuildReady: Boolean
|
||||
|
||||
"""Whether Tailscale is enabled for this container"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DOCKER**\n\n#### Description:\n\nWhether Tailscale is enabled for this container"
|
||||
tailscaleEnabled: Boolean!
|
||||
|
||||
"""Tailscale status for this container (fetched via docker exec)"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DOCKER**\n\n#### Description:\n\nTailscale status for this container (fetched via docker exec)"
|
||||
tailscaleStatus(forceRefresh: Boolean = false): TailscaleStatus
|
||||
}
|
||||
|
||||
|
|
@ -2280,16 +2390,26 @@ type TailscaleStatus {
|
|||
|
||||
type Docker implements Node {
|
||||
id: PrefixedID!
|
||||
containers(skipCache: Boolean! = false @deprecated(reason: "Caching has been removed; this parameter is now ignored")): [DockerContainer!]!
|
||||
networks(skipCache: Boolean! = false @deprecated(reason: "Caching has been removed; this parameter is now ignored")): [DockerNetwork!]!
|
||||
portConflicts(skipCache: Boolean! = false @deprecated(reason: "Caching has been removed; this parameter is now ignored")): DockerPortConflicts!
|
||||
|
||||
"""
|
||||
Access container logs. Requires specifying a target container id through resolver arguments.
|
||||
"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DOCKER**"
|
||||
containers: [DockerContainer!]!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DOCKER**"
|
||||
networks: [DockerNetwork!]!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DOCKER**"
|
||||
portConflicts: DockerPortConflicts!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DOCKER**\n\n#### Description:\n\nAccess container logs. Requires specifying a target container id through resolver arguments."
|
||||
logs(id: PrefixedID!, since: DateTime, tail: Int): DockerContainerLogs!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DOCKER**"
|
||||
container(id: PrefixedID!): DockerContainer
|
||||
organizer(skipCache: Boolean! = false @deprecated(reason: "Caching has been removed; this parameter is now ignored")): ResolvedOrganizerV1!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DOCKER**"
|
||||
organizer: ResolvedOrganizerV1!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DOCKER**"
|
||||
containerUpdateStatuses: [ExplicitStatusItem!]!
|
||||
}
|
||||
|
||||
|
|
@ -2326,65 +2446,6 @@ type FlatOrganizerEntry {
|
|||
meta: DockerContainer
|
||||
}
|
||||
|
||||
type NotificationCounts {
|
||||
info: Int!
|
||||
warning: Int!
|
||||
alert: Int!
|
||||
total: Int!
|
||||
}
|
||||
|
||||
type NotificationOverview {
|
||||
unread: NotificationCounts!
|
||||
archive: NotificationCounts!
|
||||
}
|
||||
|
||||
type Notification implements Node {
|
||||
id: PrefixedID!
|
||||
|
||||
"""Also known as 'event'"""
|
||||
title: String!
|
||||
subject: String!
|
||||
description: String!
|
||||
importance: NotificationImportance!
|
||||
link: String
|
||||
type: NotificationType!
|
||||
|
||||
"""ISO Timestamp for when the notification occurred"""
|
||||
timestamp: String
|
||||
formattedTimestamp: String
|
||||
}
|
||||
|
||||
enum NotificationImportance {
|
||||
ALERT
|
||||
INFO
|
||||
WARNING
|
||||
}
|
||||
|
||||
enum NotificationType {
|
||||
UNREAD
|
||||
ARCHIVE
|
||||
}
|
||||
|
||||
type Notifications implements Node {
|
||||
id: PrefixedID!
|
||||
|
||||
"""A cached overview of the notifications in the system & their severity."""
|
||||
overview: NotificationOverview!
|
||||
list(filter: NotificationFilter!): [Notification!]!
|
||||
|
||||
"""
|
||||
Deduplicated list of unread warning and alert notifications, sorted latest first.
|
||||
"""
|
||||
warningsAndAlerts: [Notification!]!
|
||||
}
|
||||
|
||||
input NotificationFilter {
|
||||
importance: NotificationImportance
|
||||
type: NotificationType!
|
||||
offset: Int!
|
||||
limit: Int!
|
||||
}
|
||||
|
||||
type FlashBackupStatus {
|
||||
"""Status message indicating the outcome of the backup initiation."""
|
||||
status: String!
|
||||
|
|
@ -2613,14 +2674,6 @@ enum ServerStatus {
|
|||
NEVER_CONNECTED
|
||||
}
|
||||
|
||||
type ApiConfig {
|
||||
version: String!
|
||||
extraOrigins: [String!]!
|
||||
sandbox: Boolean
|
||||
ssoSubIds: [String!]!
|
||||
plugins: [String!]!
|
||||
}
|
||||
|
||||
type OidcAuthorizationRule {
|
||||
"""The claim to check (e.g., email, sub, groups, hd)"""
|
||||
claim: String!
|
||||
|
|
@ -3129,59 +3182,110 @@ input AccessUrlObjectInput {
|
|||
scalar PrefixedID
|
||||
|
||||
type Query {
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **API_KEY**"
|
||||
apiKeys: [ApiKey!]!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **API_KEY**"
|
||||
apiKey(id: PrefixedID!): ApiKey
|
||||
|
||||
"""All possible roles for API keys"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **PERMISSION**\n\n#### Description:\n\nAll possible roles for API keys"
|
||||
apiKeyPossibleRoles: [Role!]!
|
||||
|
||||
"""All possible permissions for API keys"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **PERMISSION**\n\n#### Description:\n\nAll possible permissions for API keys"
|
||||
apiKeyPossiblePermissions: [Permission!]!
|
||||
|
||||
"""Get the actual permissions that would be granted by a set of roles"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **PERMISSION**\n\n#### Description:\n\nGet the actual permissions that would be granted by a set of roles"
|
||||
getPermissionsForRoles(roles: [Role!]!): [Permission!]!
|
||||
|
||||
"""
|
||||
Preview the effective permissions for a combination of roles and explicit permissions
|
||||
"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **PERMISSION**\n\n#### Description:\n\nPreview the effective permissions for a combination of roles and explicit permissions"
|
||||
previewEffectivePermissions(roles: [Role!], permissions: [AddPermissionInput!]): [Permission!]!
|
||||
|
||||
"""Get all available authentication actions with possession"""
|
||||
getAvailableAuthActions: [AuthAction!]!
|
||||
|
||||
"""Get JSON Schema for API key creation form"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **API_KEY**\n\n#### Description:\n\nGet JSON Schema for API key creation form"
|
||||
getApiKeyCreationFormSchema: ApiKeyFormSettings!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **CONFIG**"
|
||||
config: Config!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DISPLAY**"
|
||||
display: InfoDisplay!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **FLASH**"
|
||||
flash: Flash!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **ME**"
|
||||
me: UserAccount!
|
||||
|
||||
"""Get all notifications"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **NOTIFICATIONS**\n\n#### Description:\n\nGet all notifications"
|
||||
notifications: Notifications!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **ONLINE**"
|
||||
online: Boolean!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **OWNER**"
|
||||
owner: Owner!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **WELCOME**\n\n#### Description:\n\nGet the latest onboarding context for configuring internal boot"
|
||||
internalBootContext: OnboardingInternalBootContext!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **REGISTRATION**"
|
||||
registration: Registration
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **SERVERS**"
|
||||
server: Server
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **SERVERS**"
|
||||
servers: [Server!]!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **SERVICES**"
|
||||
services: [Service!]!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **SHARE**"
|
||||
shares: [Share!]!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **VARS**"
|
||||
vars: Vars!
|
||||
|
||||
"""Get information about all VMs on the system"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **VMS**\n\n#### Description:\n\nGet information about all VMs on the system"
|
||||
vms: Vms!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **ARRAY**"
|
||||
parityHistory: [ParityCheck!]!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **ARRAY**"
|
||||
array: UnraidArray!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **CUSTOMIZATIONS**"
|
||||
customization: Customization
|
||||
|
||||
"""Whether the system is a fresh install (no license key)"""
|
||||
isFreshInstall: Boolean!
|
||||
publicTheme: Theme!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **INFO**"
|
||||
info: Info!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DOCKER**"
|
||||
docker: Docker!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DISK**"
|
||||
disks: [Disk!]!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DISK**"
|
||||
assignableDisks: [Disk!]!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DISK**"
|
||||
disk(id: PrefixedID!): Disk!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **FLASH**"
|
||||
rclone: RCloneBackupSettings!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **LOGS**"
|
||||
logFiles: [LogFile!]!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **LOGS**"
|
||||
logFile(path: String!, lines: Int, startLine: Int): LogFileContent!
|
||||
settings: Settings!
|
||||
isSSOEnabled: Boolean!
|
||||
|
|
@ -3189,42 +3293,52 @@ type Query {
|
|||
"""Get public OIDC provider information for login buttons"""
|
||||
publicOidcProviders: [PublicOidcProvider!]!
|
||||
|
||||
"""Get all configured OIDC providers (admin only)"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **CONFIG**\n\n#### Description:\n\nGet all configured OIDC providers (admin only)"
|
||||
oidcProviders: [OidcProvider!]!
|
||||
|
||||
"""Get a specific OIDC provider by ID"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **CONFIG**\n\n#### Description:\n\nGet a specific OIDC provider by ID"
|
||||
oidcProvider(id: PrefixedID!): OidcProvider
|
||||
|
||||
"""Get the full OIDC configuration (admin only)"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **CONFIG**\n\n#### Description:\n\nGet the full OIDC configuration (admin only)"
|
||||
oidcConfiguration: OidcConfiguration!
|
||||
|
||||
"""Validate an OIDC session token (internal use for CLI validation)"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **CONFIG**\n\n#### Description:\n\nValidate an OIDC session token (internal use for CLI validation)"
|
||||
validateOidcSession(token: String!): OidcSessionValidation!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **INFO**"
|
||||
metrics: Metrics!
|
||||
|
||||
"""Retrieve current system time configuration"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **VARS**\n\n#### Description:\n\nRetrieve current system time configuration"
|
||||
systemTime: SystemTime!
|
||||
|
||||
"""Retrieve available time zone options"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **CONFIG**\n\n#### Description:\n\nRetrieve available time zone options"
|
||||
timeZoneOptions: [TimeZoneOption!]!
|
||||
upsDevices: [UPSDevice!]!
|
||||
upsDeviceById(id: String!): UPSDevice
|
||||
upsConfiguration: UPSConfiguration!
|
||||
|
||||
"""Retrieve a plugin installation operation by identifier"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **CONFIG**\n\n#### Description:\n\nRetrieve a plugin installation operation by identifier"
|
||||
pluginInstallOperation(operationId: ID!): PluginInstallOperation
|
||||
|
||||
"""List all tracked plugin installation operations"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **CONFIG**\n\n#### Description:\n\nList all tracked plugin installation operations"
|
||||
pluginInstallOperations: [PluginInstallOperation!]!
|
||||
|
||||
"""List installed Unraid OS plugins by .plg filename"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **CONFIG**\n\n#### Description:\n\nList installed Unraid OS plugins by .plg filename"
|
||||
installedUnraidPlugins: [String!]!
|
||||
|
||||
"""List all installed plugins with their metadata"""
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **CONFIG**\n\n#### Description:\n\nList all installed plugins with their metadata"
|
||||
plugins: [Plugin!]!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **CONNECT**"
|
||||
remoteAccess: RemoteAccess!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **CONNECT**"
|
||||
connect: Connect!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **NETWORK**"
|
||||
network: Network!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **CLOUD**"
|
||||
cloud: Cloud!
|
||||
}
|
||||
|
||||
|
|
@ -3263,47 +3377,77 @@ type Mutation {
|
|||
onboarding: OnboardingMutations!
|
||||
unraidPlugins: UnraidPluginsMutations!
|
||||
|
||||
"""Update server name, comment, and model"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **SERVERS**\n\n#### Description:\n\nUpdate server name, comment, and model"
|
||||
updateServerIdentity(name: String!, comment: String, sysModel: String): Server!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **VARS**"
|
||||
updateSshSettings(input: UpdateSshInput!): Vars!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **DOCKER**"
|
||||
createDockerFolder(name: String!, parentId: String, childrenIds: [String!]): ResolvedOrganizerV1!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **DOCKER**"
|
||||
setDockerFolderChildren(folderId: String, childrenIds: [String!]!): ResolvedOrganizerV1!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **DOCKER**"
|
||||
deleteDockerEntries(entryIds: [String!]!): ResolvedOrganizerV1!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **DOCKER**"
|
||||
moveDockerEntriesToFolder(sourceEntryIds: [String!]!, destinationFolderId: String!): ResolvedOrganizerV1!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **DOCKER**"
|
||||
moveDockerItemsToPosition(sourceEntryIds: [String!]!, destinationFolderId: String!, position: Float!): ResolvedOrganizerV1!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **DOCKER**"
|
||||
renameDockerFolder(folderId: String!, newName: String!): ResolvedOrganizerV1!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **DOCKER**"
|
||||
createDockerFolderWithItems(name: String!, parentId: String, sourceEntryIds: [String!], position: Float): ResolvedOrganizerV1!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **DOCKER**"
|
||||
updateDockerViewPreferences(viewId: String = "default", prefs: JSON!): ResolvedOrganizerV1!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **DOCKER**"
|
||||
syncDockerTemplatePaths: DockerTemplateSyncResult!
|
||||
|
||||
"""
|
||||
Reset Docker template mappings to defaults. Use this to recover from corrupted state.
|
||||
"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **DOCKER**\n\n#### Description:\n\nReset Docker template mappings to defaults. Use this to recover from corrupted state."
|
||||
resetDockerTemplateMappings: Boolean!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **DOCKER**"
|
||||
refreshDockerDigests: Boolean!
|
||||
|
||||
"""Initiates a flash drive backup using a configured remote."""
|
||||
initiateFlashBackup(input: InitiateFlashBackupInput!): FlashBackupStatus!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **CONFIG**"
|
||||
updateSettings(input: JSON!): UpdateSettingsResponse!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **INFO**"
|
||||
updateTemperatureConfig(input: TemperatureConfigInput!): Boolean!
|
||||
|
||||
"""Update system time configuration"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **CONFIG**\n\n#### Description:\n\nUpdate system time configuration"
|
||||
updateSystemTime(input: UpdateSystemTimeInput!): SystemTime!
|
||||
configureUps(config: UPSConfigInput!): Boolean!
|
||||
|
||||
"""
|
||||
Add one or more plugins to the API. Returns false if restart was triggered automatically, true if manual restart is required.
|
||||
"""
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **CONFIG**\n\n#### Description:\n\nAdd one or more plugins to the API. Returns false if restart was triggered automatically, true if manual restart is required."
|
||||
addPlugin(input: PluginManagementInput!): Boolean!
|
||||
|
||||
"""
|
||||
Remove one or more plugins from the API. Returns false if restart was triggered automatically, true if manual restart is required.
|
||||
"""
|
||||
"\n#### Required Permissions:\n\n- Action: **DELETE_ANY**\n- Resource: **CONFIG**\n\n#### Description:\n\nRemove one or more plugins from the API. Returns false if restart was triggered automatically, true if manual restart is required."
|
||||
removePlugin(input: PluginManagementInput!): Boolean!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **CONFIG**"
|
||||
updateApiSettings(input: ConnectSettingsInput!): ConnectSettingsValues!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **CONNECT**"
|
||||
connectSignIn(input: ConnectSignInInput!): Boolean!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **CONNECT**"
|
||||
connectSignOut: Boolean!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **CONNECT**"
|
||||
setupRemoteAccess(input: SetupRemoteAccessInput!): Boolean!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **UPDATE_ANY**\n- Resource: **CONNECT__REMOTE_ACCESS**"
|
||||
enableDynamicRemoteAccess(input: EnableDynamicRemoteAccessInput!): Boolean!
|
||||
}
|
||||
|
||||
|
|
@ -3551,20 +3695,49 @@ input AccessUrlInput {
|
|||
}
|
||||
|
||||
type Subscription {
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DISPLAY**"
|
||||
displaySubscription: InfoDisplay!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **NOTIFICATIONS**"
|
||||
notificationAdded: Notification!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **NOTIFICATIONS**"
|
||||
notificationsOverview: NotificationOverview!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **NOTIFICATIONS**"
|
||||
notificationsWarningsAndAlerts: [Notification!]!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **OWNER**"
|
||||
ownerSubscription: Owner!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **SERVERS**"
|
||||
serversSubscription: Server!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **ARRAY**"
|
||||
parityHistorySubscription: ParityCheck!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **ARRAY**"
|
||||
arraySubscription: UnraidArray!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **DOCKER**"
|
||||
dockerContainerStats: DockerContainerStats!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **LOGS**"
|
||||
logFile(path: String!): LogFileContent!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **INFO**"
|
||||
systemMetricsCpu: CpuUtilization!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **INFO**"
|
||||
systemMetricsCpuTelemetry: CpuPackages!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **INFO**"
|
||||
systemMetricsMemory: MemoryUtilization!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **INFO**"
|
||||
systemMetricsTemperature: TemperatureMetrics
|
||||
upsUpdates: UPSDevice!
|
||||
|
||||
"\n#### Required Permissions:\n\n- Action: **READ_ANY**\n- Resource: **CONFIG**"
|
||||
pluginInstallUpdates(operationId: ID!): PluginInstallEvent!
|
||||
}
|
||||
|
|
@ -68,11 +68,11 @@ The Unraid API enforces approximately 100 requests per 10 seconds. The MCP serve
|
|||
## GraphQL schema reference
|
||||
|
||||
The full Unraid GraphQL schema is available in:
|
||||
- `docs/unraid-schema.graphql` -- Complete schema definition (74 KB)
|
||||
- `docs/unraid-api-introspection.json` -- Introspection result (236 KB)
|
||||
- `docs/UNRAID_API_COMPLETE_REFERENCE.md` -- Human-readable reference (73 KB)
|
||||
- `docs/UNRAID_API_OPERATIONS.md` -- All supported operations with examples
|
||||
- `docs/UNRAID_API_REFERENCE.md` -- Condensed reference
|
||||
- `docs/unraid/UNRAID-API-SUMMARY.md` -- Condensed overview
|
||||
- `docs/unraid/UNRAID-API-CHANGES.md` -- Diff against the prior introspection snapshot
|
||||
- `docs/unraid/UNRAID-SCHEMA.graphql` -- Complete schema definition
|
||||
- `docs/unraid/UNRAID-API-INTROSPECTION.json` -- Introspection result
|
||||
- `docs/unraid/UNRAID-API-COMPLETE-REFERENCE.md` -- Human-readable reference
|
||||
|
||||
### Query organization
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Generate a complete Markdown reference from Unraid GraphQL introspection."""
|
||||
"""Generate canonical Unraid GraphQL docs from live introspection."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import datetime as dt
|
||||
import json
|
||||
import os
|
||||
from collections import Counter, defaultdict
|
||||
|
|
@ -11,9 +12,17 @@ from pathlib import Path
|
|||
from typing import Any
|
||||
|
||||
import httpx
|
||||
from graphql import build_client_schema
|
||||
from graphql import print_schema
|
||||
|
||||
|
||||
DEFAULT_OUTPUT = Path("docs/UNRAID_API_COMPLETE_REFERENCE.md")
|
||||
DOCS_DIR = Path("docs/unraid")
|
||||
DEFAULT_COMPLETE_OUTPUT = DOCS_DIR / "UNRAID-API-COMPLETE-REFERENCE.md"
|
||||
DEFAULT_SUMMARY_OUTPUT = DOCS_DIR / "UNRAID-API-SUMMARY.md"
|
||||
DEFAULT_INTROSPECTION_OUTPUT = DOCS_DIR / "UNRAID-API-INTROSPECTION.json"
|
||||
DEFAULT_SCHEMA_OUTPUT = DOCS_DIR / "UNRAID-SCHEMA.graphql"
|
||||
DEFAULT_CHANGES_OUTPUT = DOCS_DIR / "UNRAID-API-CHANGES.md"
|
||||
LEGACY_INTROSPECTION_OUTPUT = Path("docs/unraid-api-introspection.json")
|
||||
|
||||
INTROSPECTION_QUERY = """
|
||||
query FullIntrospection {
|
||||
|
|
@ -371,10 +380,329 @@ def _build_markdown(schema: dict[str, Any], *, include_introspection: bool) -> s
|
|||
return "\n".join(lines).rstrip() + "\n"
|
||||
|
||||
|
||||
def _visible_types(
|
||||
schema: dict[str, Any], *, include_introspection: bool = False
|
||||
) -> list[dict[str, Any]]:
|
||||
"""Return visible types from the schema."""
|
||||
types = schema.get("types") or []
|
||||
return [
|
||||
item
|
||||
for item in types
|
||||
if item.get("name") and (include_introspection or not str(item["name"]).startswith("__"))
|
||||
]
|
||||
|
||||
|
||||
def _types_by_name(
|
||||
schema: dict[str, Any], *, include_introspection: bool = False
|
||||
) -> dict[str, dict[str, Any]]:
|
||||
"""Map visible types by name."""
|
||||
return {
|
||||
str(item["name"]): item
|
||||
for item in _visible_types(schema, include_introspection=include_introspection)
|
||||
}
|
||||
|
||||
|
||||
def _field_signature(field: dict[str, Any]) -> str:
|
||||
"""Render a stable field signature for change detection."""
|
||||
args = sorted(field.get("args") or [], key=lambda item: str(item["name"]))
|
||||
rendered_args = []
|
||||
for arg in args:
|
||||
arg_sig = f"{arg['name']}: {_type_to_str(arg.get('type'))}"
|
||||
if arg.get("defaultValue") is not None:
|
||||
arg_sig += f" = {arg['defaultValue']}"
|
||||
rendered_args.append(arg_sig)
|
||||
args_section = f"({', '.join(rendered_args)})" if rendered_args else "()"
|
||||
return f"{field['name']}{args_section}: {_type_to_str(field.get('type'))}"
|
||||
|
||||
|
||||
def _input_field_signature(field: dict[str, Any]) -> str:
|
||||
"""Render a stable input field signature for change detection."""
|
||||
signature = f"{field['name']}: {_type_to_str(field.get('type'))}"
|
||||
if field.get("defaultValue") is not None:
|
||||
signature += f" = {field['defaultValue']}"
|
||||
return signature
|
||||
|
||||
|
||||
def _enum_value_signature(enum_value: dict[str, Any]) -> str:
|
||||
"""Render a stable enum value signature for change detection."""
|
||||
signature = str(enum_value["name"])
|
||||
if enum_value.get("isDeprecated"):
|
||||
reason = _clean(enum_value.get("deprecationReason"))
|
||||
signature += f" [deprecated: {reason}]" if reason else " [deprecated]"
|
||||
return signature
|
||||
|
||||
|
||||
def _root_field_names(schema: dict[str, Any], root_key: str) -> set[str]:
|
||||
"""Return root field names for query/mutation/subscription."""
|
||||
root_type = (schema.get(root_key) or {}).get("name")
|
||||
if not root_type:
|
||||
return set()
|
||||
types = _types_by_name(schema)
|
||||
root = types.get(str(root_type))
|
||||
if not root:
|
||||
return set()
|
||||
return {str(field["name"]) for field in (root.get("fields") or [])}
|
||||
|
||||
|
||||
def _type_member_signatures(type_info: dict[str, Any]) -> set[str]:
|
||||
"""Return stable member signatures for a type."""
|
||||
kind = str(type_info.get("kind", "UNKNOWN"))
|
||||
if kind in {"OBJECT", "INTERFACE"}:
|
||||
return {_field_signature(field) for field in (type_info.get("fields") or [])}
|
||||
if kind == "INPUT_OBJECT":
|
||||
return {_input_field_signature(field) for field in (type_info.get("inputFields") or [])}
|
||||
if kind == "ENUM":
|
||||
return {_enum_value_signature(value) for value in (type_info.get("enumValues") or [])}
|
||||
if kind == "UNION":
|
||||
return {
|
||||
str(possible["name"])
|
||||
for possible in (type_info.get("possibleTypes") or [])
|
||||
if possible.get("name")
|
||||
}
|
||||
return set()
|
||||
|
||||
|
||||
def _build_summary_markdown(
|
||||
schema: dict[str, Any], *, source: str, generated_at: str, include_introspection: bool
|
||||
) -> str:
|
||||
"""Build condensed root-level summary markdown."""
|
||||
types = _types_by_name(schema, include_introspection=include_introspection)
|
||||
visible_types = _visible_types(schema, include_introspection=include_introspection)
|
||||
directives = sorted(schema.get("directives") or [], key=lambda item: str(item["name"]))
|
||||
kind_counts = Counter(str(item.get("kind", "UNKNOWN")) for item in visible_types)
|
||||
query_root = (schema.get("queryType") or {}).get("name")
|
||||
mutation_root = (schema.get("mutationType") or {}).get("name")
|
||||
subscription_root = (schema.get("subscriptionType") or {}).get("name")
|
||||
|
||||
lines = [
|
||||
"# Unraid API Introspection Summary",
|
||||
"",
|
||||
f"> Auto-generated from live API introspection on {generated_at}",
|
||||
f"> Source: {source}",
|
||||
"",
|
||||
"## Table of Contents",
|
||||
"",
|
||||
"- [Schema Summary](#schema-summary)",
|
||||
"- [Query Fields](#query-fields)",
|
||||
"- [Mutation Fields](#mutation-fields)",
|
||||
"- [Subscription Fields](#subscription-fields)",
|
||||
"- [Type Kinds](#type-kinds)",
|
||||
"",
|
||||
"## Schema Summary",
|
||||
f"- Query root: `{query_root}`",
|
||||
f"- Mutation root: `{mutation_root}`",
|
||||
f"- Subscription root: `{subscription_root}`",
|
||||
f"- Total types: **{len(visible_types)}**",
|
||||
f"- Total directives: **{len(directives)}**",
|
||||
"",
|
||||
]
|
||||
|
||||
def render_table(section_title: str, root_name: str | None) -> None:
|
||||
lines.append(f"## {section_title}")
|
||||
lines.append("")
|
||||
lines.append("| Field | Return Type | Arguments |")
|
||||
lines.append("|-------|-------------|-----------|")
|
||||
root = types.get(str(root_name)) if root_name else None
|
||||
for field in sorted(root.get("fields") or [], key=lambda item: str(item["name"])) if root else []:
|
||||
args = sorted(field.get("args") or [], key=lambda item: str(item["name"]))
|
||||
arg_text = (
|
||||
" — "
|
||||
if not args
|
||||
else ", ".join(
|
||||
(
|
||||
f"{arg['name']}: {_type_to_str(arg.get('type'))}"
|
||||
+ (
|
||||
f" (default: {arg['defaultValue']})"
|
||||
if arg.get("defaultValue") is not None
|
||||
else ""
|
||||
)
|
||||
)
|
||||
for arg in args
|
||||
)
|
||||
)
|
||||
lines.append(
|
||||
f"| `{field['name']}` | `{_type_to_str(field.get('type'))}` | {arg_text} |"
|
||||
)
|
||||
lines.append("")
|
||||
|
||||
render_table("Query Fields", query_root)
|
||||
render_table("Mutation Fields", mutation_root)
|
||||
render_table("Subscription Fields", subscription_root)
|
||||
|
||||
lines.append("## Type Kinds")
|
||||
lines.append("")
|
||||
for kind in sorted(kind_counts):
|
||||
lines.append(f"- `{kind}`: {kind_counts[kind]}")
|
||||
lines.extend(
|
||||
[
|
||||
"",
|
||||
"## Notes",
|
||||
"",
|
||||
"- This summary is intentionally condensed; the full schema reference lives in `UNRAID-API-COMPLETE-REFERENCE.md`.",
|
||||
"- Raw schema exports live in `UNRAID-API-INTROSPECTION.json` and `UNRAID-SCHEMA.graphql`.",
|
||||
"",
|
||||
]
|
||||
)
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def _build_changes_markdown(
|
||||
previous_schema: dict[str, Any] | None,
|
||||
current_schema: dict[str, Any],
|
||||
*,
|
||||
source: str,
|
||||
generated_at: str,
|
||||
include_introspection: bool,
|
||||
) -> str:
|
||||
"""Build a schema change report from a previous introspection snapshot."""
|
||||
lines = [
|
||||
"# Unraid API Schema Changes",
|
||||
"",
|
||||
f"> Generated on {generated_at}",
|
||||
f"> Source: {source}",
|
||||
"",
|
||||
]
|
||||
if previous_schema is None:
|
||||
lines.extend(
|
||||
[
|
||||
"No previous introspection snapshot was available, so no diff could be computed.",
|
||||
"",
|
||||
"The current canonical artifacts were regenerated successfully.",
|
||||
"",
|
||||
]
|
||||
)
|
||||
return "\n".join(lines)
|
||||
|
||||
current_types = _types_by_name(current_schema, include_introspection=include_introspection)
|
||||
previous_types = _types_by_name(previous_schema, include_introspection=include_introspection)
|
||||
|
||||
sections = [
|
||||
("Query fields", _root_field_names(previous_schema, "queryType"), _root_field_names(current_schema, "queryType")),
|
||||
(
|
||||
"Mutation fields",
|
||||
_root_field_names(previous_schema, "mutationType"),
|
||||
_root_field_names(current_schema, "mutationType"),
|
||||
),
|
||||
(
|
||||
"Subscription fields",
|
||||
_root_field_names(previous_schema, "subscriptionType"),
|
||||
_root_field_names(current_schema, "subscriptionType"),
|
||||
),
|
||||
]
|
||||
|
||||
all_kinds = {"OBJECT", "INPUT_OBJECT", "ENUM", "INTERFACE", "UNION", "SCALAR"}
|
||||
previous_by_kind = {
|
||||
kind: {name for name, info in previous_types.items() if str(info.get("kind")) == kind}
|
||||
for kind in all_kinds
|
||||
}
|
||||
current_by_kind = {
|
||||
kind: {name for name, info in current_types.items() if str(info.get("kind")) == kind}
|
||||
for kind in all_kinds
|
||||
}
|
||||
|
||||
for label, old_set, new_set in sections:
|
||||
added = sorted(new_set - old_set)
|
||||
removed = sorted(old_set - new_set)
|
||||
lines.append(f"## {label}")
|
||||
lines.append("")
|
||||
lines.append(f"- Added: {len(added)}")
|
||||
if added:
|
||||
lines.extend(f" - `{name}`" for name in added)
|
||||
lines.append(f"- Removed: {len(removed)}")
|
||||
if removed:
|
||||
lines.extend(f" - `{name}`" for name in removed)
|
||||
if not added and not removed:
|
||||
lines.append("- No changes")
|
||||
lines.append("")
|
||||
|
||||
lines.append("## Type Changes")
|
||||
lines.append("")
|
||||
for kind in sorted(all_kinds):
|
||||
added = sorted(current_by_kind[kind] - previous_by_kind[kind])
|
||||
removed = sorted(previous_by_kind[kind] - current_by_kind[kind])
|
||||
if not added and not removed:
|
||||
continue
|
||||
lines.append(f"### {kind}")
|
||||
lines.append("")
|
||||
lines.append(f"- Added: {len(added)}")
|
||||
if added:
|
||||
lines.extend(f" - `{name}`" for name in added)
|
||||
lines.append(f"- Removed: {len(removed)}")
|
||||
if removed:
|
||||
lines.extend(f" - `{name}`" for name in removed)
|
||||
lines.append("")
|
||||
|
||||
changed_types: list[str] = []
|
||||
for name in sorted(set(previous_types) & set(current_types)):
|
||||
previous_info = previous_types[name]
|
||||
current_info = current_types[name]
|
||||
if str(previous_info.get("kind")) != str(current_info.get("kind")):
|
||||
changed_types.append(name)
|
||||
continue
|
||||
if _type_member_signatures(previous_info) != _type_member_signatures(current_info):
|
||||
changed_types.append(name)
|
||||
|
||||
lines.append("## Type Signature Changes")
|
||||
lines.append("")
|
||||
if not changed_types:
|
||||
lines.append("No existing type signatures changed.")
|
||||
lines.append("")
|
||||
return "\n".join(lines)
|
||||
|
||||
for name in changed_types:
|
||||
previous_info = previous_types[name]
|
||||
current_info = current_types[name]
|
||||
previous_members = _type_member_signatures(previous_info)
|
||||
current_members = _type_member_signatures(current_info)
|
||||
added = sorted(current_members - previous_members)
|
||||
removed = sorted(previous_members - current_members)
|
||||
lines.append(f"### `{name}` ({current_info.get('kind')})")
|
||||
lines.append("")
|
||||
lines.append(f"- Added members: {len(added)}")
|
||||
if added:
|
||||
lines.extend(f" - `{member}`" for member in added)
|
||||
lines.append(f"- Removed members: {len(removed)}")
|
||||
if removed:
|
||||
lines.extend(f" - `{member}`" for member in removed)
|
||||
if not added and not removed and previous_info.get("kind") != current_info.get("kind"):
|
||||
lines.append(
|
||||
f"- Kind changed: `{previous_info.get('kind')}` -> `{current_info.get('kind')}`"
|
||||
)
|
||||
lines.append("")
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def _extract_schema(payload: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Return the __schema payload or raise."""
|
||||
schema = (payload.get("data") or {}).get("__schema")
|
||||
if not schema:
|
||||
raise SystemExit("GraphQL introspection returned no __schema payload.")
|
||||
return schema
|
||||
|
||||
|
||||
def _load_previous_schema(path: Path) -> dict[str, Any] | None:
|
||||
"""Load a prior introspection snapshot if available."""
|
||||
if not path.exists():
|
||||
return None
|
||||
payload = json.loads(path.read_text(encoding="utf-8"))
|
||||
return _extract_schema(payload)
|
||||
|
||||
|
||||
def _write_schema_graphql(path: Path, payload: dict[str, Any]) -> None:
|
||||
"""Write SDL schema output."""
|
||||
schema_graphql = print_schema(build_client_schema(payload["data"]))
|
||||
banner = (
|
||||
"# ------------------------------------------------------\n"
|
||||
"# THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY)\n"
|
||||
"# ------------------------------------------------------\n\n"
|
||||
)
|
||||
path.write_text(banner + schema_graphql.rstrip() + "\n", encoding="utf-8")
|
||||
|
||||
|
||||
def _parse_args() -> argparse.Namespace:
|
||||
"""Parse CLI args."""
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generate complete Unraid GraphQL schema reference Markdown from introspection."
|
||||
description="Generate canonical Unraid GraphQL docs from introspection."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--api-url",
|
||||
|
|
@ -387,10 +715,43 @@ def _parse_args() -> argparse.Namespace:
|
|||
help="API key (default: UNRAID_API_KEY env var).",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--output",
|
||||
"--complete-output",
|
||||
type=Path,
|
||||
default=DEFAULT_OUTPUT,
|
||||
help=f"Output markdown file path (default: {DEFAULT_OUTPUT}).",
|
||||
default=DEFAULT_COMPLETE_OUTPUT,
|
||||
help=f"Full reference output path (default: {DEFAULT_COMPLETE_OUTPUT}).",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--summary-output",
|
||||
type=Path,
|
||||
default=DEFAULT_SUMMARY_OUTPUT,
|
||||
help=f"Summary output path (default: {DEFAULT_SUMMARY_OUTPUT}).",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--introspection-output",
|
||||
type=Path,
|
||||
default=DEFAULT_INTROSPECTION_OUTPUT,
|
||||
help=f"Introspection JSON output path (default: {DEFAULT_INTROSPECTION_OUTPUT}).",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--schema-output",
|
||||
type=Path,
|
||||
default=DEFAULT_SCHEMA_OUTPUT,
|
||||
help=f"SDL schema output path (default: {DEFAULT_SCHEMA_OUTPUT}).",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--changes-output",
|
||||
type=Path,
|
||||
default=DEFAULT_CHANGES_OUTPUT,
|
||||
help=f"Schema changes report path (default: {DEFAULT_CHANGES_OUTPUT}).",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--previous-introspection",
|
||||
type=Path,
|
||||
default=None,
|
||||
help=(
|
||||
"Previous introspection JSON used for diffing. Defaults to the current "
|
||||
"introspection output path, falling back to the legacy docs path if present."
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--timeout-seconds",
|
||||
|
|
@ -420,7 +781,7 @@ def main() -> int:
|
|||
if not args.api_key:
|
||||
raise SystemExit("Missing API key. Provide --api-key or set UNRAID_API_KEY.")
|
||||
|
||||
headers = {"Authorization": f"Bearer {args.api_key}", "Content-Type": "application/json"}
|
||||
headers = {"x-api-key": args.api_key, "Content-Type": "application/json"}
|
||||
|
||||
with httpx.Client(timeout=args.timeout_seconds, verify=args.verify_ssl) as client:
|
||||
response = client.post(args.api_url, json={"query": INTROSPECTION_QUERY}, headers=headers)
|
||||
|
|
@ -431,15 +792,53 @@ def main() -> int:
|
|||
errors = json.dumps(payload["errors"], indent=2)
|
||||
raise SystemExit(f"GraphQL introspection returned errors:\n{errors}")
|
||||
|
||||
schema = (payload.get("data") or {}).get("__schema")
|
||||
if not schema:
|
||||
raise SystemExit("GraphQL introspection returned no __schema payload.")
|
||||
schema = _extract_schema(payload)
|
||||
generated_at = dt.datetime.now(dt.UTC).replace(microsecond=0).isoformat()
|
||||
previous_path = (
|
||||
args.previous_introspection
|
||||
or (args.introspection_output if args.introspection_output.exists() else LEGACY_INTROSPECTION_OUTPUT)
|
||||
)
|
||||
previous_schema = _load_previous_schema(previous_path)
|
||||
|
||||
markdown = _build_markdown(schema, include_introspection=bool(args.include_introspection_types))
|
||||
args.output.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.output.write_text(markdown, encoding="utf-8")
|
||||
for path in {
|
||||
args.complete_output,
|
||||
args.summary_output,
|
||||
args.introspection_output,
|
||||
args.schema_output,
|
||||
args.changes_output,
|
||||
}:
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
print(f"Wrote {args.output}")
|
||||
full_reference = _build_markdown(
|
||||
schema, include_introspection=bool(args.include_introspection_types)
|
||||
)
|
||||
summary = _build_summary_markdown(
|
||||
schema,
|
||||
source=args.api_url,
|
||||
generated_at=generated_at,
|
||||
include_introspection=bool(args.include_introspection_types),
|
||||
)
|
||||
changes = _build_changes_markdown(
|
||||
previous_schema,
|
||||
schema,
|
||||
source=args.api_url,
|
||||
generated_at=generated_at,
|
||||
include_introspection=bool(args.include_introspection_types),
|
||||
)
|
||||
|
||||
args.complete_output.write_text(full_reference, encoding="utf-8")
|
||||
args.summary_output.write_text(summary, encoding="utf-8")
|
||||
args.introspection_output.write_text(
|
||||
json.dumps(payload, indent=2, sort_keys=True) + "\n", encoding="utf-8"
|
||||
)
|
||||
_write_schema_graphql(args.schema_output, payload)
|
||||
args.changes_output.write_text(changes, encoding="utf-8")
|
||||
|
||||
print(f"Wrote {args.complete_output}")
|
||||
print(f"Wrote {args.summary_output}")
|
||||
print(f"Wrote {args.introspection_output}")
|
||||
print(f"Wrote {args.schema_output}")
|
||||
print(f"Wrote {args.changes_output}")
|
||||
return 0
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -500,8 +500,8 @@ class TestDockerToolRequests:
|
|||
nonlocal call_count
|
||||
body = json.loads(request.content.decode())
|
||||
call_count += 1
|
||||
if "skipCache" in body["query"]:
|
||||
# Resolution query: docker { containers(skipCache: true) { id names } }
|
||||
if "ResolveContainerID" in body["query"]:
|
||||
# Resolution query: docker { containers { id names } }
|
||||
return _graphql_response(
|
||||
{"docker": {"containers": [{"id": resolved_id, "names": ["plex"]}]}}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import pytest
|
|||
from graphql import DocumentNode, GraphQLSchema, build_schema, parse, validate
|
||||
|
||||
|
||||
SCHEMA_PATH = Path(__file__).resolve().parents[2] / "docs" / "unraid-schema.graphql"
|
||||
SCHEMA_PATH = Path(__file__).resolve().parents[2] / "docs" / "unraid" / "UNRAID-SCHEMA.graphql"
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
|
|
@ -820,7 +820,7 @@ class TestHealthQueries:
|
|||
overview { unread { alert warning total } }
|
||||
}
|
||||
docker {
|
||||
containers(skipCache: true) { id state status }
|
||||
containers { id state status }
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
|
|
|||
154
tests/test_generate_unraid_api_reference.py
Normal file
154
tests/test_generate_unraid_api_reference.py
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from scripts.generate_unraid_api_reference import _build_changes_markdown
|
||||
|
||||
|
||||
def _type_ref(name: str | None = None, *, kind: str = "OBJECT", of_type: dict | None = None) -> dict:
|
||||
return {"kind": kind, "name": name, "ofType": of_type}
|
||||
|
||||
|
||||
def _field(
|
||||
name: str,
|
||||
return_type: dict,
|
||||
*,
|
||||
args: list[dict] | None = None,
|
||||
description: str | None = None,
|
||||
) -> dict:
|
||||
return {
|
||||
"name": name,
|
||||
"description": description,
|
||||
"isDeprecated": False,
|
||||
"deprecationReason": None,
|
||||
"args": args or [],
|
||||
"type": return_type,
|
||||
}
|
||||
|
||||
|
||||
def _arg(name: str, arg_type: dict, *, default: str | None = None) -> dict:
|
||||
return {
|
||||
"name": name,
|
||||
"description": None,
|
||||
"defaultValue": default,
|
||||
"type": arg_type,
|
||||
}
|
||||
|
||||
|
||||
def _schema(
|
||||
*,
|
||||
query_fields: list[dict],
|
||||
mutation_fields: list[dict] | None = None,
|
||||
subscription_fields: list[dict] | None = None,
|
||||
extra_types: list[dict] | None = None,
|
||||
) -> dict:
|
||||
types = [
|
||||
{"kind": "OBJECT", "name": "Query", "description": None, "fields": query_fields, "inputFields": None, "interfaces": [], "enumValues": None, "possibleTypes": None},
|
||||
{"kind": "OBJECT", "name": "Mutation", "description": None, "fields": mutation_fields or [], "inputFields": None, "interfaces": [], "enumValues": None, "possibleTypes": None},
|
||||
{"kind": "OBJECT", "name": "Subscription", "description": None, "fields": subscription_fields or [], "inputFields": None, "interfaces": [], "enumValues": None, "possibleTypes": None},
|
||||
]
|
||||
if extra_types:
|
||||
types.extend(extra_types)
|
||||
return {
|
||||
"queryType": {"name": "Query"},
|
||||
"mutationType": {"name": "Mutation"},
|
||||
"subscriptionType": {"name": "Subscription"},
|
||||
"directives": [],
|
||||
"types": types,
|
||||
}
|
||||
|
||||
|
||||
def test_changes_report_handles_missing_previous_snapshot() -> None:
|
||||
current = _schema(query_fields=[_field("online", _type_ref("Boolean", kind="SCALAR"))])
|
||||
|
||||
report = _build_changes_markdown(
|
||||
None,
|
||||
current,
|
||||
source="https://tower.local/graphql",
|
||||
generated_at="2026-04-05T18:00:00+00:00",
|
||||
include_introspection=False,
|
||||
)
|
||||
|
||||
assert "No previous introspection snapshot was available" in report
|
||||
assert "https://tower.local/graphql" in report
|
||||
|
||||
|
||||
def test_changes_report_lists_root_and_type_signature_deltas() -> None:
|
||||
previous = _schema(
|
||||
query_fields=[
|
||||
_field("online", _type_ref("Boolean", kind="SCALAR")),
|
||||
_field("server", _type_ref("Server")),
|
||||
],
|
||||
mutation_fields=[_field("connectSignIn", _type_ref("Boolean", kind="SCALAR"))],
|
||||
subscription_fields=[_field("ownerSubscription", _type_ref("Owner"))],
|
||||
extra_types=[
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "Server",
|
||||
"description": None,
|
||||
"fields": [_field("id", _type_ref("ID", kind="SCALAR"))],
|
||||
"inputFields": None,
|
||||
"interfaces": [],
|
||||
"enumValues": None,
|
||||
"possibleTypes": None,
|
||||
}
|
||||
],
|
||||
)
|
||||
current = _schema(
|
||||
query_fields=[
|
||||
_field("online", _type_ref("Boolean", kind="SCALAR")),
|
||||
_field(
|
||||
"server",
|
||||
_type_ref("Server"),
|
||||
args=[_arg("verbose", _type_ref("Boolean", kind="SCALAR"), default="false")],
|
||||
),
|
||||
_field("cloud", _type_ref("Cloud")),
|
||||
],
|
||||
mutation_fields=[],
|
||||
subscription_fields=[
|
||||
_field("ownerSubscription", _type_ref("Owner")),
|
||||
_field("dockerContainerStats", _type_ref("DockerContainerStats")),
|
||||
],
|
||||
extra_types=[
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "Server",
|
||||
"description": None,
|
||||
"fields": [
|
||||
_field("id", _type_ref("ID", kind="SCALAR")),
|
||||
_field("name", _type_ref("String", kind="SCALAR")),
|
||||
],
|
||||
"inputFields": None,
|
||||
"interfaces": [],
|
||||
"enumValues": None,
|
||||
"possibleTypes": None,
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "Cloud",
|
||||
"description": None,
|
||||
"fields": [],
|
||||
"inputFields": None,
|
||||
"interfaces": [],
|
||||
"enumValues": None,
|
||||
"possibleTypes": None,
|
||||
},
|
||||
],
|
||||
)
|
||||
|
||||
report = _build_changes_markdown(
|
||||
previous,
|
||||
current,
|
||||
source="https://tower.local/graphql",
|
||||
generated_at="2026-04-05T18:00:00+00:00",
|
||||
include_introspection=False,
|
||||
)
|
||||
|
||||
assert "## Query fields" in report
|
||||
assert "`cloud`" in report
|
||||
assert "## Mutation fields" in report
|
||||
assert "`connectSignIn`" in report
|
||||
assert "## Subscription fields" in report
|
||||
assert "`dockerContainerStats`" in report
|
||||
assert "### OBJECT" in report
|
||||
assert "### `Server` (OBJECT)" in report
|
||||
assert "`name(): String`" in report
|
||||
assert "`server(verbose: Boolean = false): Server`" in report
|
||||
|
|
@ -18,15 +18,15 @@ from ..core.utils import safe_get
|
|||
# ===========================================================================
|
||||
|
||||
_DOCKER_QUERIES: dict[str, str] = {
|
||||
"list": "query ListDockerContainers { docker { containers(skipCache: false) { id names image state status autoStart } } }",
|
||||
"details": "query GetContainerDetails { docker { containers(skipCache: false) { id names image imageId command created ports { ip privatePort publicPort type } sizeRootFs labels state status hostConfig { networkMode } networkSettings mounts autoStart } } }",
|
||||
"list": "query ListDockerContainers { docker { containers { id names image state status autoStart } } }",
|
||||
"details": "query GetContainerDetails { docker { containers { id names image imageId command created ports { ip privatePort publicPort type } sizeRootFs labels state status hostConfig { networkMode } networkSettings mounts autoStart } } }",
|
||||
"networks": "query GetDockerNetworks { docker { networks { id name driver scope } } }",
|
||||
"network_details": "query GetDockerNetwork { docker { networks { id name driver scope enableIPv6 internal attachable containers options labels } } }",
|
||||
}
|
||||
|
||||
# Internal query used only for container ID resolution — not a public subaction.
|
||||
_DOCKER_RESOLVE_QUERY = (
|
||||
"query ResolveContainerID { docker { containers(skipCache: true) { id names } } }"
|
||||
"query ResolveContainerID { docker { containers { id names } } }"
|
||||
)
|
||||
|
||||
_DOCKER_MUTATIONS: dict[str, str] = {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ _HEALTH_QUERIES: dict[str, str] = {
|
|||
" info { machineId time versions { core { unraid } } os { uptime } }"
|
||||
" array { state }"
|
||||
" notifications { overview { unread { alert warning total } } }"
|
||||
" docker { containers(skipCache: true) { id state status } }"
|
||||
" docker { containers { id state status } }"
|
||||
" }"
|
||||
),
|
||||
}
|
||||
|
|
|
|||
2
uv.lock
2
uv.lock
|
|
@ -1572,7 +1572,7 @@ wheels = [
|
|||
|
||||
[[package]]
|
||||
name = "unraid-mcp"
|
||||
version = "1.2.2"
|
||||
version = "1.2.4"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "fastapi" },
|
||||
|
|
|
|||
Loading…
Reference in a new issue