Skip to content

Arcane v2 support#7

Open
Xitee1 wants to merge 8 commits into
RandomSynergy17:mainfrom
Xitee1:arcane-v2-support
Open

Arcane v2 support#7
Xitee1 wants to merge 8 commits into
RandomSynergy17:mainfrom
Xitee1:arcane-v2-support

Conversation

@Xitee1

@Xitee1 Xitee1 commented Jul 11, 2026

Copy link
Copy Markdown

Summary

Updates the MCP server for Arcane v2 (OpenAPI spec refreshed from v1.17.0 to v2.3.2, pulled from a live instance). No v1 compatibility shims — per semver this is a breaking 3.0.0; installs on Arcane v1.x should stay on 2.x.

Every client.* call in src/ now validates against the v2 spec (a script matched method+path for all 25 modules — 0 mismatches). Where the spec was ambiguous (prune modes, notification providers, deployment snippets, project destroy), behavior was verified against the Arcane backend source (getarcaneapp/arcane).

Removed tools (endpoints gone in v2) — 180 → 174

  • arcane_dashboard_get_action_items (/dashboard/action-items removed)
  • arcane_event_create (POST /events removed)
  • arcane_updater_update_container (dropped; arcane_container_update covers it)
  • arcane_notification_apprise_get/update/test (Apprise replaced by the provider model)
  • arcane_swarm_get_service_logs (v2 streams logs over WebSocket only)

Added: arcane_notification_delete_settings

Breaking changes (following the v2 API)

  • Notifications rebuilt on the per-provider model (discord, email, telegram, signal, slack, ntfy, pushover, matrix, generic)
  • Vulnerabilities: scan result at GET .../images/{id}/vulnerabilities, list at /vulnerabilities/list; ignore requires pkgName, unignore takes the ignore-entry ID; v2 field names (vulnerabilityId, pkgName, severity summary object)
  • Image updates: check is GET with imageRef; batch = POST /image-updates/check-batch with imageRefs; responses keyed by image ref; summary reports imagesWithUpdates/digestUpdates/errorsCount
  • System: docker info at /system/docker/info (native Docker PascalCase fields); system prune sends the v2 per-resource body (mode per containers/images/networks/volumes/buildCache, new buildCache option); image prune sends mode/dangling and reads the wrapped response
  • Moved paths: project destroy (DELETE .../destroy with body, new removeFiles param), volume backup delete/files (no longer volume-scoped), template variables + public settings (environment-scoped), deployment snippets (/deployment, dockerRun field)
  • Updater: run gains forceUpdate/resourceIds; result/status/history follow the v2 shapes (items, in-flight updates, AutoUpdateRecord)
  • Events: filter by severity (v2 dropped resourceType); display uses title/description/severity
  • Users: role removed from create/update (v2 uses role assignments); displayName/email/password supported; displays isGlobalAdmin
  • Builds: follows v2 BuildRequest (contextDir required, dockerfileInline, tags/platforms arrays, noCache); Git-URL builds were dropped by the API
  • Auth: login/refresh responses unwrapped from the {success, data} envelope; ArcaneClient.delete() accepts an optional JSON body

Docs & housekeeping

  • README (tables, counts, version callout), CLAUDE.md, SKILL.md, /arcane:configure, MCP prompts, plugin manifests, CI smoke check (≥174)
  • CHANGELOG entry for 3.0.0; version bumped

Testing

  • npm run build clean
  • npm test: 117/117 passing (updated tests that referenced removed tools/counts)
  • Endpoint validation script: 0 method/path mismatches against the v2.3.2 spec

Not included (possible follow-up)

v2 adds ~58 new endpoints (container pause/unpause/kill/commit, project compose files & archiving, roles API, activities, image tag/export/history, swarm join-tokens, …). This PR only restores compatibility; new tools for those could come separately.

🤖 Generated with Claude Code

Xitee1 and others added 8 commits July 11, 2026 20:53
… follow the new API

- Refresh OpenAPI spec + generated types from v1.17.0 to v2.3.2
- Remove tools whose endpoints were dropped in v2: dashboard action items,
  event create, updater single-container update, the three Apprise tools,
  and swarm service logs (WebSocket-only in v2); add notification delete (180 → 174 tools)
- Rebuild notifications on the per-provider model (discord/email/telegram/…)
- Vulnerabilities: new scan-result/list paths, ignore payload (pkgName),
  unignore via ignore-entry ID, v2 field names throughout
- Image updates: GET check with imageRef, check-batch with imageRefs,
  map-shaped batch responses, new summary fields
- System: docker/info path + native Docker fields, per-resource prune body
  with modes (+ buildCache option), image prune mode/dangling
- Moved paths: project destroy (body via DELETE), volume backup delete/files,
  env-scoped template variables + public settings, /deployment snippets
- Updater/events/users follow v2 response shapes; auth unwraps {success, data}
- Update docs, skill, /arcane:configure, prompts, CI smoke check, tests

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Tested against a live v2.3.2 instance:

- All paginated list tools printed "Found undefined": v2 renamed
  pagination.total to pagination.totalItems (16 modules updated)
- Image `created` is a Unix timestamp in v2 — format as ISO date
- check-all image updates blocked until every image was checked, hitting
  the MCP timeout; the client's timeout retry then started duplicate
  server-side checks. Fire the check in the background instead
  (new no-retry postInBackground helper) and return immediately
- Add arcane_activity_list / arcane_activity_get so progress of
  background operations can be tracked (176 tools, 26 modules)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- The v2 API only accepts image IDs in path params — names like
  amir20/dozzle:latest 404 (slash breaks the route). Add resolveImageId
  which looks names up via the image list; used by image get/delete and
  the vulnerability scan/result/summary/list tools
- arcane_image_get threw "Invalid time value": the detail endpoint
  returns created as an ISO string while the list uses a Unix timestamp;
  format each accordingly and make formatUnixTimestamp defensive

Verified against a live v2.3.2 instance (name resolution, detail fetch,
short-ID passthrough).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
arcane_project_list now supports the v2 updates filter (has_update /
up_to_date / error / unknown) and a status filter, and renders each
project's updateInfo — including exactly which image refs are outdated.
arcane_project_get shows the same. This is the dashboard's update
overview; the skill now points Claude at it instead of checking images
one by one.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
POST /projects/{id}/update-services is the update action behind the
projects:update permission — it pulls latest images and recreates the
given services (all when unspecified). The manual pull + redeploy route
requires projects:deploy instead, which restricted API keys may lack.

The backend handler blocks until the update completes, so the tool
starts it via postInBackground and points at the activity tools for
progress. Skill guidance now prefers this per-project update for
compose stacks. 177 tools.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…test

Systematic pass instead of case-by-case fixes: every tool's response
field access and request payload was audited against the v2.3.2 spec
(three parallel audits covering all 26 modules), and every read-only
tool is now exercised against a live instance by scripts/live-smoke.mjs,
which flags undefined/[object Object]/NaN/Invalid Date in output and
tool errors (403s from restricted API keys count as skips).

Fixes ~60 mismatches, highlights:
- containers: list uses `names[]`, detail `state` is an object (health,
  exit code shown); counts use totalContainers/running/stopped
- dashboard: rewritten for the v2 snapshot (incl. aggregated action
  items and version info)
- ports: hostPort/containerPort/hostIp/isPublished field names
- auth: wrapped login/me/refresh responses, isGlobalAdmin instead of role
- jobs: `jobs` array + flat JobscheduleConfig (schedule get/update)
- webhooks: actionType/targetType/targetId model (spec has no events)
- environments: test/pair-token/version/create field fixes
- networks: create nests options, counts/prune unwrapped from data,
  containersList; topology metadata fields
- volumes: Docker-cased usageData, isDirectory, mkdir path as query
- gitops: composePath, lastSync* status fields, branches/files shapes,
  git repo token auth
- registries: registryType/description/token model
- templates: type filter, required envContent
- swarm: raw Docker ServiceSpec for create/update (with version index),
  runningReplicas, tasks/nodes fetched from their own endpoints
- vulnerabilities: scanner status `available`, image options string list
- builds: tags/platforms/errorMessage/output fields, multipart workspace
  upload (new client.postMultipart)
- images: pull relies on server-side registry credentials, delete drops
  unsupported pruneChildren
- projects: runtimeServices for per-service status, counts field names
- version endpoint: currentVersion/newestVersion
- OIDC config reports "not configured" instead of a server 500

Live smoke: 30 ok, 0 failed on both local and remote-agent environments.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Arcane v2 serves logs over WebSocket only (no REST endpoints), so the
client gains fetchLogs(): it connects with follow=false and X-API-Key
auth on the upgrade request, collects the backlog, and stops on server
close, a 2s idle gap, a 15s hard cap, or the maxLines limit. ANSI color
codes and CR are stripped.

New tools (180 total): arcane_container_get_logs,
arcane_project_get_logs, and arcane_swarm_get_service_logs (revived —
it was removed when the REST route disappeared). Each supports tail,
since, timestamps (default on), and a maxLines cap so the context
window stays manageable; live following works by passing the newest
seen timestamp as `since` on the next call, returning only new lines.

Verified against the live instance: container logs, project logs
through the remote-agent proxy, and the incremental since pattern.
Live smoke: 32 ok, 0 failed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Arcane's checker only compares digests within the pinned tag and never
resolves newer version tags (UpdateTypeTag exists in the models but is
never produced by the service as of v2.3.2) — label digest updates
accordingly so the output doesn't look like missing data.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Xitee1 Xitee1 marked this pull request as ready for review July 11, 2026 21:59
@Xitee1 Xitee1 changed the title Arcane v2 support (tested against v2.3.2) Arcane v2 support Jul 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant