Seafile

v1.0.1

Search, download, and upload files in a single Seafile library using a repo token. Use when an agent needs library-scoped filename or path search, exact-path...

0· 104·1 current·1 all-time
byAndrew Reid@andrewreid

Install

OpenClaw Prompt Flow

Install with OpenClaw

Best for remote or guided setup. Copy the exact prompt, then paste it into OpenClaw for andrewreid/seafile.

Previewing Install & Setup.
Prompt PreviewInstall & Setup
Install the skill "Seafile" (andrewreid/seafile) from ClawHub.
Skill page: https://clawhub.ai/andrewreid/seafile
Keep the work scoped to this skill only.
After install, inspect the skill metadata and help me finish setup.
Required env vars: SEAFILE_BASE_URL, SEAFILE_REPO_TOKEN
Required binaries: curl, jq
Use only the metadata you can verify from ClawHub; do not invent missing requirements.
Ask before making any broader environment changes.

Command Line

CLI Commands

Use the direct CLI path if you want to install manually and keep every step visible.

OpenClaw CLI

Bare skill slug

openclaw skills install seafile

ClawHub CLI

Package manager switcher

npx clawhub@latest install seafile
Security Scan
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Benign
high confidence
Purpose & Capability
The skill's name and description match the actual requirements and actions. Required binaries (curl, jq) and the two env vars (SEAFILE_BASE_URL, SEAFILE_REPO_TOKEN) are exactly what a repo-token-based Seafile integration needs.
Instruction Scope
SKILL.md contains only repo-token API calls (dir/, download-link/, upload-link/, repo-info/) and local jq filtering. It does not instruct the agent to read unrelated files, other environment variables, or to transmit data to endpoints outside the constructed SEAFILE_BASE_URL API base.
Install Mechanism
No install spec and no code files — the skill is instruction-only, which minimizes disk persistence and supply-chain risk.
Credentials
Only SEAFILE_BASE_URL and SEAFILE_REPO_TOKEN are required (the repo token is declared as the primary credential). Requesting a repo token is proportionate to the described functionality; there are no unrelated secrets or additional credential requirements.
Persistence & Privilege
The skill is not always-enabled (always:false). The included agents/openai.yaml sets allow_implicit_invocation: true, so the agent may autonomously invoke the skill when eligible — this is normal but worth being aware of because it gives the skill runtime invocation capability.
Assessment
This skill appears to do only what it says: interact with a single Seafile library via a repo token. Before installing, ensure you: 1) Provide a repo token scoped to only the intended library (least privilege) and not a broad admin token; 2) Verify SEAFILE_BASE_URL is the correct, trusted server (the token will be sent to that origin); 3) Avoid populating SEAFILE_OUTPUT_DIR with sensitive system paths to prevent accidental overwrites; 4) Be comfortable with the agent being able to invoke the skill autonomously (allow_implicit_invocation is enabled in the skill metadata); and 5) Rotate the token if you later revoke the skill. If you need higher assurance, request a copy of the skill's provenance or run its commands in a restricted test environment first.

Like a lobster shell, security has layers — review code before you run it.

Runtime requirements

🗂️ Clawdis
Binscurl, jq
EnvSEAFILE_BASE_URL, SEAFILE_REPO_TOKEN
Primary envSEAFILE_REPO_TOKEN
latestvk97bqkkdn68sddvv9r2kg66dxx855ram
104downloads
0stars
2versions
Updated 1w ago
v1.0.1
MIT-0

Seafile Skill

Overview

Use this skill to interact with one Seafile library through the repo-token API. It is designed for three tasks only:

  • Search for files or folders by filename or path fragment inside the token's library scope
  • Download a file by exact Seafile path
  • Upload a local file into an existing Seafile directory

This skill does not cover full-text content search, cross-library discovery, deletes, renames, moves, or share-link management.

For endpoint details, see references/seafile-api.md. For reusable shell patterns, see references/command-patterns.md.

Prerequisites

Required:

  • curl
  • jq
  • Network access to the Seafile server
  • SEAFILE_BASE_URL
  • SEAFILE_REPO_TOKEN with access to the target library

Optional with defaults:

  • SEAFILE_LIBRARY_ROOT, which defaults to /
  • SEAFILE_OUTPUT_DIR, which is only needed when saving downloaded files locally

Export the required variables before running commands. The optional variables below are shown with their recommended defaults:

export SEAFILE_BASE_URL="https://seafile.example.com"
export SEAFILE_REPO_TOKEN="<repo-token>"
export SEAFILE_LIBRARY_ROOT="/"        # optional
export SEAFILE_OUTPUT_DIR="$PWD/downloads"  # optional, used for downloads
mkdir -p "$SEAFILE_OUTPUT_DIR"

Defaults and expectations:

  • SEAFILE_BASE_URL should be the server origin without a trailing slash
  • SEAFILE_LIBRARY_ROOT defaults to / if you do not override it
  • SEAFILE_OUTPUT_DIR is only needed for downloads
  • All Seafile paths in this skill are absolute library paths such as /, /docs, or /docs/report.pdf

Authentication

The repo-token endpoints use the repo token in the Authorization header. Use this default form unless your deployment documents a different token scheme:

AUTH_HEADER="Authorization: Token $SEAFILE_REPO_TOKEN"
API_BASE="${SEAFILE_BASE_URL%/}/api/v2.1/via-repo-token"

Before doing search, download, or upload, verify the token and library scope:

curl --fail --silent --show-error \
  -H "$AUTH_HEADER" \
  "$API_BASE/repo-info/" | jq

If this fails with 401 or 403, stop and fix the token, permissions, or server URL before continuing.

Search Workflow

Use repo-token directory listing and filter locally with jq. This is filename and path search, not full-text search.

1. List items from a starting path

START_PATH="${SEAFILE_LIBRARY_ROOT:-/}"

curl --fail --silent --show-error \
  -G \
  -H "$AUTH_HEADER" \
  --data-urlencode "path=$START_PATH" \
  --data-urlencode "recursive=1" \
  "$API_BASE/dir/"

Useful query parameters:

  • path: directory to inspect, default /
  • recursive=1: walk the subtree recursively
  • type=f: files only
  • type=d: directories only

2. Filter by filename fragment

NEEDLE="report"
START_PATH="${SEAFILE_LIBRARY_ROOT:-/}"

curl --fail --silent --show-error \
  -G \
  -H "$AUTH_HEADER" \
  --data-urlencode "path=$START_PATH" \
  --data-urlencode "recursive=1" \
  "$API_BASE/dir/" |
  jq -r --arg needle "$NEEDLE" '
    .dirent_list[]
    | select((.name // "") | ascii_downcase | contains($needle | ascii_downcase))
    | [.type, .parent_dir, .name]
    | @tsv
  '

3. Filter by full path fragment

PATH_FRAGMENT="2026/q2"
START_PATH="${SEAFILE_LIBRARY_ROOT:-/}"

curl --fail --silent --show-error \
  -G \
  -H "$AUTH_HEADER" \
  --data-urlencode "path=$START_PATH" \
  --data-urlencode "recursive=1" \
  "$API_BASE/dir/" |
  jq -r --arg needle "$PATH_FRAGMENT" '
    .dirent_list[]
    | (.parent_dir + "/" + .name | gsub("//+"; "/")) as $full_path
    | select($full_path | ascii_downcase | contains($needle | ascii_downcase))
    | [$full_path, .type]
    | @tsv
  '

When you need exact metadata for one known file path, consult the repo-token file-info section in references/seafile-api.md and confirm the route shape against the target deployment if needed.

Download Workflow

Downloads are exact-path only. SEAFILE_OUTPUT_DIR is optional overall and only matters if you want this skill to save the downloaded file to a local directory.

1. Request a one-time download link

REMOTE_FILE="/docs/report.pdf"

DOWNLOAD_LINK=$(curl --fail --silent --show-error \
  -G \
  -H "$AUTH_HEADER" \
  --data-urlencode "path=$REMOTE_FILE" \
  "$API_BASE/download-link/" |
  jq -r '.')

2. Download the file to a local path

LOCAL_FILE="$SEAFILE_OUTPUT_DIR/$(basename "$REMOTE_FILE")"

curl --fail --silent --show-error --location \
  "$DOWNLOAD_LINK" \
  -o "$LOCAL_FILE"

Notes:

  • download-link/ returns a URL string, not a JSON object
  • Use --location because the returned URL may redirect
  • Keep the remote path exact, including spaces, case, and file extension

Upload Workflow

Uploads send a local file into an existing Seafile directory.

1. Request an upload link

UPLOAD_LINK=$(curl --fail --silent --show-error \
  -H "$AUTH_HEADER" \
  "$API_BASE/upload-link/" |
  jq -r '.')

2. Upload one local file

LOCAL_FILE="./artifact.zip"
TARGET_DIR="/incoming"

curl --fail --silent --show-error \
  -F "file=@${LOCAL_FILE}" \
  -F "parent_dir=${TARGET_DIR}" \
  -F "replace=0" \
  "${UPLOAD_LINK}?ret-json=1" |
  jq

Upload behavior:

  • parent_dir must be an absolute library path like /incoming
  • replace=1 overwrites an existing file with the same name
  • replace=0 preserves the existing file and lets Seafile rename the new upload if needed
  • ?ret-json=1 returns structured JSON and should be used by default

If you need Seafile to create nested folders beneath an existing parent, add -F "relative_path=subdir1/subdir2/" to the upload request.

Error Handling

Check failures in this order:

  • 401 or 403 The token is missing, expired, malformed, or does not allow the requested action.
  • 404 The base URL or endpoint is wrong, or the server is not exposing that API path.
  • 440 or similar upload validation errors The filename is invalid for the target server.
  • 442 or 443 The file is too large or the library is out of quota.
  • Directory listing or download returns no match Re-check the starting directory, exact remote path, and case sensitivity.
  • Upload succeeds but lands in the wrong place Re-check parent_dir and any relative_path value.

When a request is failing and the server output is unclear, remove --silent temporarily and inspect headers with curl -i.

Examples

Find files matching a name fragment

NEEDLE="invoice"
START_PATH="/finance"

curl --fail --silent --show-error \
  -G \
  -H "Authorization: Token $SEAFILE_REPO_TOKEN" \
  --data-urlencode "path=$START_PATH" \
  --data-urlencode "recursive=1" \
  --data-urlencode "type=f" \
  "${SEAFILE_BASE_URL%/}/api/v2.1/via-repo-token/dir/" |
  jq -r --arg needle "$NEEDLE" '
    .dirent_list[]
    | select((.name // "") | ascii_downcase | contains($needle | ascii_downcase))
    | (.parent_dir + "/" + .name | gsub("//+"; "/"))
  '

Download one file by exact path

REMOTE_FILE="/finance/invoices/april-2026.pdf"
DOWNLOAD_LINK=$(curl --fail --silent --show-error \
  -G \
  -H "Authorization: Token $SEAFILE_REPO_TOKEN" \
  --data-urlencode "path=$REMOTE_FILE" \
  "${SEAFILE_BASE_URL%/}/api/v2.1/via-repo-token/download-link/" |
  jq -r '.')

curl --fail --silent --show-error --location \
  "$DOWNLOAD_LINK" \
  -o "$SEAFILE_OUTPUT_DIR/april-2026.pdf"

Upload one local file into a target folder

TARGET_DIR="/incoming/reports"
LOCAL_FILE="./build/report.csv"
UPLOAD_LINK=$(curl --fail --silent --show-error \
  -H "Authorization: Token $SEAFILE_REPO_TOKEN" \
  "${SEAFILE_BASE_URL%/}/api/v2.1/via-repo-token/upload-link/" |
  jq -r '.')

curl --fail --silent --show-error \
  -F "file=@${LOCAL_FILE}" \
  -F "parent_dir=${TARGET_DIR}" \
  -F "replace=1" \
  "${UPLOAD_LINK}?ret-json=1" |
  jq

Comments

Loading comments...