Back to home

$ Documentation

Everything you need to know about using uldl.sh from the terminal.

#Getting Started

uldl.sh is a text and file upload service optimized for terminal usage. Upload files via curl, get a shareable URL back. No browser required.

quickstart.sh
# Upload text from stdin
$echo "hello world" | curl -X POST https://uldl.sh/yourname -d @-
https://uldl.sh/yourname/abc123
# Download it back
$curl https://uldl.sh/yourname/abc123
hello world

#Uploading

There are three ways to upload content to uldl.sh. All methods POST to your username endpoint.

Method 1: Pipe from stdin

Pipe any command output directly to uldl.sh.

stdin.sh
$echo "hello world" | curl -X POST https://uldl.sh/yourname -d @-
https://uldl.sh/yourname/abc123
$cat script.py | curl -X POST https://uldl.sh/yourname -d @-
https://uldl.sh/yourname/def456

Method 2: Multipart file upload

Upload a file with its original filename preserved.

multipart.sh
$curl -X POST https://uldl.sh/yourname -F file=@document.md
https://uldl.sh/yourname/ghi789

Method 3: Raw body upload

Upload file contents directly as the request body.

raw.sh
$curl -X POST https://uldl.sh/yourname --data-binary @config.yaml
https://uldl.sh/yourname/jkl012

#Downloading

Access your blobs via GET request to the returned URL.

download.sh
# Download to stdout
$curl https://uldl.sh/yourname/abc123
# Save to file
$curl -o output.txt https://uldl.sh/yourname/abc123
# Follow filename from server
$curl -OJ https://uldl.sh/yourname/abc123

#Listing Blobs

List all your blobs via an authenticated GET request to your username endpoint. Returns a JSON array of blob metadata.

list.sh
# List all your blobs
$curl "https://uldl.sh/yourname?key=$ULDL_KEY"
[{"slug":"abc123","title":"My Config",...}]
# Filter by visibility and search term
$curl "https://uldl.sh/yourname?key=$ULDL_KEY&visibility=private&search=config"
# Pretty-print with jq
$curl -s "https://uldl.sh/yourname?key=$ULDL_KEY" | jq .

Query Parameters

ParameterDescriptionExample
searchSearch in title, filename, description"config"
visibilityFilter by public or private"private"
languageFilter by programming language"python"
categoryFilter by category"config"
tagsComma-separated tags"docker,prod"

Response Format

Returns a JSON array of blob objects. Each object contains metadata only — no file content.

response.json
[
  {
    "slug": "abc123",
    "title": "My Config",
    "filename": "config.yaml",
    "mimeType": "text/yaml",
    "sizeBytes": 1234,
    "language": "yaml",
    "visibility": "private",
    "tags": ["config", "production"],
    "createdAt": "2026-03-28T12:00:00.000Z",
    "updatedAt": "2026-03-28T12:00:00.000Z"
  }
]

#Request Headers

Customize your uploads with these optional headers.

HeaderDescriptionExample
X-TitleSet blob title"My Config File"
X-DescriptionSet description"Production settings"
X-Visibilitypublic or private"private"
X-LanguageForce syntax highlighting"python"
X-CategorySet category"config"
X-TagsComma-separated tags"docker,config"
X-FilenameOverride filename (raw uploads)"script.sh"
X-MessageVersion commit message (PUT only)"Fix typo"
headers.sh
$curl -X POST https://uldl.sh/yourname \ -H "X-Title: Production Config" \ -H "X-Description: Server configuration" \ -H "X-Visibility: private" \ -H "X-Tags: config,production" \ -F file=@config.yaml
https://uldl.sh/yourname/mno345

#Visibility & Privacy

Blobs are private by default. Public blobs can be accessed by anyone with the URL. Private blobs require your authentication key.

visibility.sh
# Upload as public
$curl -X POST https://uldl.sh/yourname -H "X-Visibility: public" -d @-
# Access private blob with key
$curl "https://uldl.sh/yourname/abc123?key=$ULDL_KEY"

#Authentication

Your access key is a unique 24-character token generated when you sign up. Find it in your dashboard by clicking the curl command button. Use it to access private blobs and delete blobs.

auth.sh
# Set as environment variable
$export ULDL_KEY="xHnSfR01YZb9kL3mQp7wRt2v"
# Use for private access
$curl "https://uldl.sh/yourname/private-blob?key=$ULDL_KEY"

#Versioning

Every blob maintains a version history. Update a blob via PUT to create a new version. The latest version is always served by default.

versioning.sh
# Update a blob with a new version
$curl -X PUT "https://uldl.sh/yourname/abc123?key=$ULDL_KEY" \ -H "X-Message: Fix typo in config" \ --data-binary @config.yaml
https://uldl.sh/yourname/abc123
# Update metadata only (no new version)
$curl -X PUT "https://uldl.sh/yourname/abc123?key=$ULDL_KEY" \ -H "X-Title: Production Config" \ -H "X-Visibility: public"
Updated (metadata only)

Via MCP, pass the slug parameter to the upload tool to update an existing blob instead of creating a new one.

Version history can be viewed and managed from your dashboard.

#Deleting Blobs

Delete blobs via DELETE request with your authentication key.

delete.sh
$curl -X DELETE "https://uldl.sh/yourname/abc123?key=$ULDL_KEY"
Deleted

This removes the blob and all its versions. The storage space is immediately freed.

#Response Headers

uldl.sh returns useful metadata in response headers.

HeaderDescription
X-Blob-IdUnique blob identifier
X-SlugURL slug
X-Storage-UsedCurrent storage usage (bytes)
X-Storage-RemainingRemaining quota (bytes)
X-VersionVersion number (on PUT update)
X-Storage-FreedBytes freed on delete
X-Blob-TitleBlob title (on download)
headers-response.sh
$curl -I https://uldl.sh/yourname/abc123
HTTP/2 200
content-type: text/plain
x-blob-id: blob_123...
x-blob-title: My Config

#Error Handling

uldl.sh uses standard HTTP status codes.

StatusMessageCause
400No file providedMultipart request missing file
400Empty fileZero-byte upload
401UnauthorizedMissing/invalid key for private blob
404User not foundInvalid username
404Not foundInvalid slug
413File too largeExceeds 4.5MB limit
507Storage quota exceededUser quota full
check-status.sh
$curl -w "%{http_code}" -o /dev/null -s https://uldl.sh/yourname/abc123
200

#Limits & Quotas

Current service limits:

4.5MB
max file size
250MB
free storage
Unlimited
uploads per day

#MCP Integration

uldl.sh supports the Model Context Protocol (MCP) — an open standard for connecting AI agents to external tools and data sources. Connect your AI coding assistant to uldl and it can upload, download, search, and manage files on your behalf.

Why give your AI agent blob storage?

Persistent storage beyond the conversation

Agents can save work products — code, configs, notes, outputs — that survive after the session ends. No more losing everything when the context window resets.

Share files between agents and tools

One agent uploads a file, another retrieves it. Bridges the gap between different AI tools and workflows — your coding agent can hand off data to your research agent.

Move files between machines

Agent on your laptop uploads, agent on your server downloads. No manual scp or rsync needed — just ask your AI to "save this to uldl" and pull it from anywhere.

Searchable knowledge base

Agents can organize files with tags, categories, and descriptions, then search and retrieve them later. Acts as a lightweight external memory that any agent can tap into.

Collaboration

Share snippets, configs, or outputs with teammates by making blobs public. Your agent can publish results to a URL anyone can curl.

Connecting

You need your username and access key (available in the dashboard). Then pick your client:

Claude Code

bash
$claude mcp add uldl --transport http https://uldl.sh/api/mcp \ --header "Authorization: Bearer YOUR_ACCESS_KEY" \ --header "x-uldl-username: YOUR_USERNAME"

Cursor

Add to .cursor/mcp.json:

.cursor/mcp.json
{
  "mcpServers": {
    "uldl": {
      "type": "http",
      "url": "https://uldl.sh/api/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_ACCESS_KEY",
        "x-uldl-username": "YOUR_USERNAME"
      }
    }
  }
}

Claude Desktop

Add to your Claude Desktop config:

claude_desktop_config.json
{
  "mcpServers": {
    "uldl": {
      "type": "http",
      "url": "https://uldl.sh/api/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_ACCESS_KEY",
        "x-uldl-username": "YOUR_USERNAME"
      }
    }
  }
}

Available Tools

Once connected, your AI agent has access to these tools:

ToolDescriptionKey Parameters
uploadUpload new or update existing contentcontent, slug, message, title, filename, visibility, tags
downloadDownload a blob by slugslug
listSearch and list blobssearch, language, category, visibility, tags
deleteDelete a blob by slugslug
get_storage_infoCheck storage usage and quota

Example Usage

Once connected, just ask your AI agent in natural language:

"Save this deployment config to uldl so I can pull it on the server"

"Upload the test results and tag them with ci and staging"

"Find the Python script I uploaded last week about data migration"

"Download the config from uldl slug abc123 and apply it here"

"How much storage do I have left on uldl?"

#Real-World Examples

Common use cases and shell integrations.

Share error logs

logs.sh
$tail -100 /var/log/app.log | curl -X POST https://uldl.sh/yourname \ -H "X-Title: App Error Log" \ -H "X-Tags: logs,error" \ -d @-

Share command output

kubectl.sh
$kubectl get pods | curl -X POST https://uldl.sh/yourname -d @-

Share git diff

git.sh
$git diff | curl -X POST https://uldl.sh/yourname \ -H "X-Title: Feature Branch Diff" \ -H "X-Language: diff" \ -d @-

Shell alias

alias.sh
# Add to ~/.bashrc or ~/.zshrc
$alias share='curl -X POST https://uldl.sh/yourname -d @-'
# Then use it
$echo "quick note" | share
https://uldl.sh/yourname/xyz789

Private environment template

env.sh
$curl -X POST https://uldl.sh/yourname \ -H "X-Visibility: private" \ -H "X-Title: Env Template" \ -F file=@.env.example