file-sharing
Upload files, create expiring share links with optional password protection, and track downloads on a self-hosted file drop service.
Best use case
file-sharing is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Upload files, create expiring share links with optional password protection, and track downloads on a self-hosted file drop service.
Teams using file-sharing should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/file-sharing/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How file-sharing Compares
| Feature / Agent | file-sharing | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Upload files, create expiring share links with optional password protection, and track downloads on a self-hosted file drop service.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# File Sharing Skill
## When to use
Use this skill to:
- Upload files to the local server storage
- Create share links with expiry dates, download limits, and passwords
- Retrieve download counts and logs for specific files or links
- Manage link lifecycle (create, update, revoke, reactivate)
## Base URL
```
http://localhost:3000
```
No authentication required. This service is intended for local or private network deployment.
## Quick Reference
| Action | Method | Path |
|---|---|---|
| Upload file | POST | /api/files |
| List files | GET | /api/files |
| Get file metadata | GET | /api/files/:slug |
| Delete file | DELETE | /api/files/:slug |
| Create share link | POST | /api/files/:slug/links |
| List links for file | GET | /api/files/:slug/links |
| Get link metadata | GET | /api/links/:token |
| Update link | PUT | /api/links/:token |
| Revoke link | DELETE | /api/links/:token |
| Download file | GET | /dl/:token |
| Get download log | GET | /api/downloads |
| Get stats | GET | /api/stats |
## Upload a file
```bash
curl -X POST http://localhost:3000/api/files \
-F "file=@/path/to/Q1-report.pdf"
```
Response `201`:
```json
{
"id": 1,
"slug": "ab3kx9mz1qwe",
"original_name": "Q1-report.pdf",
"mime_type": "application/pdf",
"size_bytes": 2516582,
"created_at": "2026-03-20T10:00:00Z"
}
```
Files larger than `MAX_FILE_SIZE_MB` (default 100) return `413 Payload Too Large`.
## List files
```bash
curl http://localhost:3000/api/files?limit=20&offset=0
```
Response:
```json
{
"files": [
{
"slug": "ab3kx9mz1qwe",
"original_name": "Q1-report.pdf",
"mime_type": "application/pdf",
"size_bytes": 2516582,
"link_count": 3,
"download_count": 142,
"created_at": "2026-03-20T10:00:00Z"
}
],
"total": 37
}
```
## Create a share link
All fields are optional.
```bash
curl -X POST http://localhost:3000/api/files/ab3kx9mz1qwe/links \
-H "Content-Type: application/json" \
-d '{
"label": "Client share",
"expires_at": "2026-04-20T00:00:00Z",
"max_downloads": 10,
"password": "hunter2"
}'
```
Response `201`:
```json
{
"token": "pq7rn4xyz90a",
"download_url": "http://localhost:3000/dl/pq7rn4xyz90a",
"label": "Client share",
"expires_at": "2026-04-20T00:00:00Z",
"max_downloads": 10,
"download_count": 0,
"has_password": true,
"is_active": true,
"created_at": "2026-03-20T10:05:00Z"
}
```
## Create a permanent, public link (no restrictions)
```bash
curl -X POST http://localhost:3000/api/files/ab3kx9mz1qwe/links \
-H "Content-Type: application/json" \
-d '{}'
```
## Download a file
Use the token from the share link:
```bash
curl -L -O http://localhost:3000/dl/pq7rn4xyz90a
```
If password-protected:
```bash
curl -L -O http://localhost:3000/dl/pq7rn4xyz90a \
-H "X-Link-Password: hunter2"
```
Error responses:
| Status | Meaning |
|---|---|
| 401 | `{"requires_password": true}` - password required or wrong |
| 410 | Link has expired or exhausted its download limit |
| 404 | Token does not exist |
## Update a share link
Only `label`, `expires_at`, and `max_downloads` can be changed. To clear a field, pass `null`.
```bash
curl -X PUT http://localhost:3000/api/links/pq7rn4xyz90a \
-H "Content-Type: application/json" \
-d '{"expires_at": "2026-05-01T00:00:00Z", "max_downloads": 20}'
```
## Revoke a share link
```bash
curl -X DELETE http://localhost:3000/api/links/pq7rn4xyz90a
```
Response `204 No Content`. Link is deactivated (is_active = 0). Downloads previously recorded are retained.
## List downloads for a file
```bash
curl http://localhost:3000/api/files/ab3kx9mz1qwe/downloads?limit=50
```
## List downloads for a link
```bash
curl http://localhost:3000/api/links/pq7rn4xyz90a/downloads
```
## Get aggregate stats
```bash
curl http://localhost:3000/api/stats
```
Response:
```json
{
"total_files": 37,
"total_links": 35,
"active_links": 24,
"total_downloads": 1847,
"storage_bytes": 4509715456,
"data_served_bytes": 44040192000
}
```
## File object
```typescript
interface File {
id: number;
slug: string; // 12-character URL-safe base64url
original_name: string;
mime_type: string;
size_bytes: number;
created_at: string; // ISO 8601
}
```
## ShareLink object
```typescript
interface ShareLink {
token: string; // 12-character URL-safe base64url
file_id: number;
label: string | null;
expires_at: string | null; // ISO 8601
max_downloads: number | null;
download_count: number;
has_password: boolean;
is_active: boolean;
download_url: string;
created_at: string;
}
```
## Error responses
```json
{ "error": "File not found", "code": "NOT_FOUND" }
```
| Status | code | Meaning |
|---|---|---|
| 400 | VALIDATION_ERROR | Missing or invalid fields |
| 404 | NOT_FOUND | File or link does not exist |
| 410 | GONE | Link expired or download limit reached |
| 413 | FILE_TOO_LARGE | Upload exceeds MAX_FILE_SIZE_MB |
| 500 | INTERNAL_ERROR | Server error |
## Environment variables
| Variable | Default | Description |
|---|---|---|
| PORT | 3000 | HTTP server port |
| DATA_DIR | ./data | Storage path for DB and files |
| MAX_FILE_SIZE_MB | 100 | Maximum upload size |
| ALLOW_ANONYMOUS_UPLOAD | 1 | 1 = uploads are open, 0 = disabled |Related Skills
file-permissions
Reference guide for Unix file permission bits, octal notation, symbolic notation, and security-relevant permission combinations used by the permissions-auditor rules engine.
file-encryption
AES-256-GCM file encryption and PBKDF2 key derivation as used in health-records-vault. Use when you need to understand or implement the encryption model, derive a key from a password, encrypt or decrypt a file manually, restore an encrypted backup, or verify the cryptographic integrity of a .enc file. Triggers include "AES-256-GCM", "PBKDF2", "decrypt .enc file", "restore backup", "encryption key derivation", "IV", "salt", or any task about the cryptographic internals of the vault.
file-tree-diff
Compare two directory trees and show added, removed, and changed files with color output. Use when you need to compare two versions of a directory, find what changed between releases, audit differences between staging and production file sets, or verify a deployment. Triggers include "compare directories", "directory diff", "what changed in", "file differences between", "ftd", "tree diff".
machine-profiles
Use dotfile-sync profiles to manage machine-specific configurations. Use when different machines need different subsets of dotfiles, handling OS-specific configs, or setting up work vs personal machine profiles. Triggers include "machine profile", "per-machine config", "dfs profile", "different configs per machine", "work vs home dotfiles".
dotfile-sync
Manage dotfiles with symlinks from a central git repository. Use when tracking config files, syncing dotfiles between machines, or bootstrapping a new machine. Triggers include "dotfiles", "sync config", "dfs", "track dotfiles", "symlink config", "new machine setup".
file-processing
Handle file upload, validation, processing pipelines, and temporary file management in Node.js servers. Use when building file processing APIs with Express and multer, managing temporary files with cleanup, or implementing secure file handling patterns. Triggers include "file upload", "multipart form", "temp file cleanup", "multer config", or any server-side file handling task.
Skill: Uptime Monitoring
## Overview
Skill: Status Page
## Overview
Skill: unit-conversion
## Overview
Skill: recipe-scaler
## Overview
reading-list
Operate the reading-list API to save, manage, tag, search, and export articles.
email-digest
Configure, test, and troubleshoot the reading-list daily email digest delivered via nodemailer.