Skip to main content

Nextcloud

@kneel/nextcloudv2026.10.19.1· 7d agoBEHAVIORS
01README

Drive a Nextcloud instance from swamp over its CalDAV / CardDAV / WebDAV / OCS surfaces using an app-password (HTTP Basic) credential — a first-class swamp node for a self-hosted cloud.

The model's first job is event-level calendar sync: upsert real VEVENTs (keyed by iCalUID) into a Nextcloud calendar so a source calendar — e.g. a Google calendar read by @swamp/gcp/calendar — appears as editable native events that propagate to every CalDAV client, with swamp in the data path.

Methods

  • whoami — verify app-password auth via OCS cloud/user; record the authenticated {userId, displayName, email}. Auth smoke-test.
  • list_calendars — PROPFIND the user's calendar home; record calendars as {displayName, path, color, hasSource}. Webcal subscription source URLs are masked (recorded as a boolean, never persisted).
  • create_calendar — provision a calendar collection via MKCALENDAR (idempotent: an existing collection reports created=false, not an error).
  • list_events — CalDAV calendar-query REPORT over a time window; records {uid, dtstart, hasProvenance} per event — UID/DTSTART/provenance only, no PII. The read side of reconciliation.
  • put_events — Rule-6 fan-out: CalDAV PUT a whole batch of events as VEVENTs keyed by iCalUID (idempotent upsert). Every VEVENT is stamped with the X-SWAMP-SYNC provenance marker and recurring timed events keep their TZID (DST-correct expansion). Records UIDs + per-item outcomes only — no event PII. An empty batch is a no-op.
  • delete_events — Rule-6 fan-out: verify-then-DELETE events by iCalUID (idempotent). By default (requireProvenance=true) it refuses to delete any event lacking the X-SWAMP-SYNC marker, so foreign events sharing the calendar are never removed. Supports dryRun=true to preview (would-delete) without mutating. An empty batch is a no-op.

Security

  • appPassword is a sensitive global argument — wire it to a vault at model-create time, never inline.
  • baseUrl is refined to require https:// (Basic auth is only protected by TLS).
  • The Authorization header is never logged; event PII (SUMMARY/DESCRIPTION/ LOCATION/raw VEVENT bodies) is never logged and never persisted in resource snapshots.

Quickstart

# 1. store the app password in a vault
swamp vault put nextcloud appPassword     # hidden prompt

# 2. create the model, wiring the sensitive arg from the vault
swamp model create @kneel/nextcloud nc \
  --global-arg baseUrl=https://cloud.example.com \
  --global-arg username=neil \
  --global-arg appPassword='${{ vault.get(nextcloud, appPassword) }}'

swamp model method run nc whoami          # auth proof
swamp model method run nc list_calendars  # discover the target calendar

Reference recorded data with CEL:

data.latest("nc", "main").attributes.calendars
02Behaviors1
nextcloud.tsv2026.10.19.1

Global Arguments

ArgumentTypeDescription
metadatarecord
fn whoami()
Verify app-password auth via OCS and record the authenticated user.
fn serverInfo()
Fetch instance health via the OCS serverinfo app: Nextcloud/PHP/DB versions, active-user counts, storage totals, and system load/memory. Requires an admin app password and the 'serverinfo' app enabled. No secrets are persisted.
fn list_calendars()
List calendars in the user's calendar home (webcal source URLs masked).
fn list_events()
List events in a calendar within a time window via a CalDAV calendar-query REPORT. Returns UID + DTSTART + provenance flag only (no PII) — the read side of reconciliation.
fn create_calendar()
Provision a calendar collection via MKCALENDAR (idempotent: an existing collection is reported created=false, not an error).
fn put_events()
Upsert events (VEVENTs keyed by iCalUID) into a calendar via CalDAV PUT. Fan-out: one dispatch handles the whole batch.
fn delete_events()
Delete events by iCalUID from a calendar via CalDAV DELETE. Verifies existence first (idempotent); fan-out over the batch.
fn list_addressbooks()
List addressbooks in the user's addressbook home via PROPFIND.
fn create_addressbook()
Provision the gcontacts-sync addressbook collection via MKCOL (idempotent).
fn list_contacts()
List contacts in an addressbook via a CardDAV addressbook-query REPORT. Returns UID + FN + provenance flag only (no PII).
fn put_contacts()
Upsert contacts (VCards keyed by UID) into an addressbook via CardDAV PUT. Fan-out: one dispatch handles the whole batch.
fn delete_contacts()
Delete contacts by UID from an addressbook via CardDAV DELETE. Verifies provenance first; fan-out over the batch.
fn list_tasklists()
List task lists (VTODO calendar-type collections) in the user's calendar home via PROPFIND.
fn create_tasklist()
Provision the tasks-nc-sync tasklist via MKCALENDAR w/ VTODO (idempotent).
fn list_tasks()
List tasks in a tasklist via a CalDAV calendar-query REPORT. Returns UID + SUMMARY + STATUS + provenance flag only (no PII).
fn put_tasks()
Upsert tasks (VTODOs keyed by UID) into a tasklist via CalDAV PUT. Fan-out: one dispatch handles the whole batch.
fn delete_tasks()
Delete tasks by UID from a tasklist via CalDAV DELETE. Verifies provenance first; fan-out over the batch.
fn list_notes()
List notes from the NC Notes app (metadata only — no bodies fetched). GET /notes with Accept: application/json.
fn get_note()
Fetch a single note by ID. Returns the full body via methodResult (never persisted in resources — PII discipline).
fn put_note(id: number)
Create or update a note. If id is provided, PUT /notes/{id}; else POST /notes. Stamps provenance sentinel.
ArgumentTypeDescription
idnumber
fn delete_notes()
Delete notes by ID via REST DELETE. Fan-out over ids; verifies provenance first; supports dryRun + maxDeletes.
fn list_shares()
List shares from the OCS Share API. Optional filters: path, reshares, subfiles. Writes the shares resource.
fn create_share()
Create a share via the OCS Share API. Records the share ID in the managed_shares provenance snapshot.
fn create_public_link()
Create a public link share (shareType=3) for a file or folder. Write permissions require elevatedPublicLink=true.
fn update_share()
Update an existing share (permissions, password, expireDate, note, hideDownload).
fn revoke_share()
Revoke (DELETE) a share. Pre-checks the share ID is in the managed_shares provenance snapshot. Supports dryRun.
fn list_files()
List files in the swamp-sync provenance folder via PROPFIND Depth:1. Returns metadata only — no file bodies. Hard cap 1000 entries (SEC-5).
fn get_file()
Download a file from the swamp-sync folder. Returns the file body via methodResult ONLY — never persisted or logged (PII discipline). Writes metadata-only file_content resource.
fn put_file()
Upload a file to the swamp-sync folder. Validates content-type allowlist (SEC-3), size cap (10MB default), and blocked extensions. Supports optional If-Match ETag for drift detection (ADV-3).
fn delete_file()
Delete a file from the swamp-sync folder. NOTE: Nextcloud moves deleted files to trash by default (ADV-2). Supports dryRun.
fn mkdir()
Create a directory in the swamp-sync folder via MKCOL. Idempotent — returns success if directory already exists (HTTP 405). Uses same path validation as file ops (SEC-4).
fn lock_file()
Lock a file in the swamp-sync folder via the files_lock app (LOCK + X-User-Lock: 1). lockType 0=user (default)/1=app/2=token. Returns outcome=locked-by-other on HTTP 423 (held by someone else).
fn unlock_file()
Unlock a file in the swamp-sync folder via the files_lock app (UNLOCK + X-User-Lock: 1). lockType should match the lock. outcome=not-locked on HTTP 412, locked-by-other on HTTP 423.
fn lock_status()
Read the lock status of a file in the swamp-sync folder via PROPFIND of the files_lock nc:lock* properties. Returns {locked, owner, ownerType, lockTime, lockTimeout, lockToken, ...}.
fn list_boards()
List Deck boards (metadata + labels only; no nested stacks/cards). GET /boards with Accept: application/json.
fn get_board()
Fetch a single Deck board with stacks and cards (full shape). Card descriptions are returned via methodResult ONLY — never persisted in resources (PII).
fn create_board()
Create a new Deck board. Returns the created board's metadata.
fn delete_board()
Delete a Deck board. Cascade safety: counts all cards across all stacks before deleting — aborts if count exceeds maxDeletes (ADV-4). Supports dryRun.
fn list_stacks()
List stacks in a Deck board (metadata only; cards not nested). GET /boards/{boardId}/stacks.
fn create_stack()
Create a new stack in a Deck board. Returns the created stack's metadata.
fn delete_stack()
Delete a Deck stack. Cascade safety: counts cards in the stack before deleting — aborts if count exceeds maxDeletes (ADV-4). Supports dryRun.
fn list_cards()
List cards in a Deck stack (metadata only — descriptions NEVER persisted, PII). GET /stacks/{stackId}.
fn create_card()
Create a new card in a Deck stack. Auto-assigns the swamp-managed provenance label (SEC-1) — creates the label on the board if missing. Description is sent to the API but NEVER persisted (PII).
fn update_card()
Update a card's title and/or description. Description is NEVER persisted (PII). Provenance label is preserved by Deck automatically.
fn delete_card()
Delete a Deck card. When requireProvenance=true (default), refuses to delete cards that lack the swamp-managed label (SEC-1). Supports dryRun.
fn list_users()
List users via OCS Users API (admin only). Writes user IDs to resource (no PII). Returns full list via methodResult.
fn create_user()
Create a user via OCS Users API (admin only). Generates a CSPRNG password if none supplied. Password is returned ONCE in methodResult — NEVER logged. Records userid in managed_users provenance snapshot.
fn get_user()
Fetch a single user via OCS Users API (admin only). Returns full detail via methodResult — never persisted (PII).
fn edit_user()
Edit a user field via OCS Users API (admin only). key is one of: email, quota, display, password.
fn delete_user()
Delete a user via OCS Users API (admin only). Triple safety: confirmUserId must match userid, maxDeletes cap, dryRun mode. Refuses to delete admin account.
fn list_groups()
List groups via OCS Groups API (admin only). Writes group IDs to resource (no PII). Returns full list via methodResult.
fn get_group()
Fetch a single group via OCS Groups API (admin only). Returns group detail (groupId + members) via methodResult.

Resources

identity(1h)— Authenticated Nextcloud user (auth smoke-test result).
serverInfo(1h)— Instance health from the OCS serverinfo app (versions, active users, storage totals, load/memory). No secrets.
calendars(1h)— Calendars in the user's calendar home (secrets masked).
upsert(1d)— Outcome of an event upsert batch (UIDs + outcomes only, no PII).
deletions(1d)— Outcome of an event deletion batch (UIDs + outcomes only).
events(1d)— Events read back from a calendar within a time window (UID + DTSTART + provenance flag only, no PII).
provision(infinite)— Outcome of a calendar provisioning (MKCALENDAR) request.
addressbooks(1h)— Addressbooks in the user's addressbook home.
provision_addressbook(infinite)— Outcome of an addressbook provisioning (MKCOL) request.
contacts(1d)— Contacts read back from an addressbook (UID + FN + provenance flag only, no PII).
upsert_contacts(1d)— Outcome of a contact upsert batch (UIDs + outcomes only, no PII).
deletions_contacts(1d)— Outcome of a contact deletion batch (UIDs + outcomes only).
tasklists(1h)— Task lists (VTODO calendar-type collections) in the user's calendar home.
provision_tasklist(infinite)— Outcome of a tasklist provisioning (MKCALENDAR w/ VTODO) request.
tasks(1d)— Tasks read back from a tasklist (UID + SUMMARY + STATUS + provenance flag only, no PII).
upsert_tasks(1d)— Outcome of a task upsert batch (UIDs + outcomes only, no PII).
deletions_tasks(1d)— Outcome of a task deletion batch (UIDs + outcomes only).
notes(1d)— Notes metadata from the NC Notes app (id + title + modified + category + favorite; no bodies — PII).
upsert_notes(1d)— Outcome of a note upsert batch (IDs + outcomes only, no bodies).
deletions_notes(1d)— Outcome of a note deletion batch (IDs + outcomes only, no bodies).
shares(1d)— Shares listed from the OCS Share API (IDs + paths + permissions; no share-with PII beyond user IDs).
managed_shares(infinite)— Provenance snapshot: share IDs created/managed by swamp. revoke_share refuses to revoke IDs not in this snapshot.
share_result(1d)— Outcome of a create/update share operation (ID + URL + shareType).
files(1h)— Files listed from the WebDAV endpoint under the swamp-sync provenance folder (metadata only — no file bodies).
file_content(1h)— Metadata for a downloaded file (path + size + contentType + etag). File bodies are NEVER persisted (PII).
file_operation(1d)— Outcome of a file operation (put/delete/mkdir). Path + outcome only — no file bodies.
lock_status(1h)— Lock status of a file in the swamp-sync folder (files_lock app): locked flag + owner/time/token metadata.
boards(1d)— Deck boards (metadata + labels only; no nested stacks/cards — use list_stacks).
board_result(1d)— Outcome of a board operation (id + title + outcome; no nested content).
stacks(1d)— Deck stacks for a board (metadata only; no nested cards — use list_cards).
stack_result(1d)— Outcome of a stack operation.
cards(1d)— Deck cards for a stack (metadata only — descriptions NEVER persisted, PII).
card_result(1d)— Outcome of a card operation (id + title + outcome; no description — PII).
users(1d)— User IDs listed from the OCS Users API (IDs only, no PII).
managed_users(infinite)— Provenance snapshot: user IDs created/managed by swamp. delete_user refuses to delete IDs not in this snapshot.
user_detail(1h)— Full user detail (userId + email + displayname + quota + lastLogin). Returned via methodResult ONLY — never persisted (PII).
groups(1d)— Group IDs listed from the OCS Groups API (IDs only, no PII).
group_detail(1h)— Group detail (groupId + members). Returned via methodResult ONLY.
03Stats
A
93 / 100
Downloads
37
Archive size
79.5 KB
  • Has README or module doc2/2earned
  • README has a code example1/1earned
  • README is substantive1/1earned
  • Most symbols documented1/1earned
  • No slow types (deprecated)1/1earned
  • Dependencies pass trust audit2/2earned
  • Has description1/1earned
  • Platform support declared (or universal)2/2earned
  • License1/2partial

    no SPDX license declared

  • Verified public repository2/2earned
04Platforms
05Labels