Upload Center
Image upload manager with a file-browser UI, REST API, and MCP server for any AI agent.
Upload demo and product images, organize them in folders, copy public URLs (one per line or comma-separated for Excel), and let AI agents upload images programmatically.
Production
| Web app | https://uploads.craffo.com |
| Documentation | https://uploads.craffo.com/docs/ |
| Agent API | https://uploads.craffo.com/agent.php |
For developers
Use the web UI or HTTP API to upload and manage images. Integrate with scripts via API key auth.
For AI agents
Connect via URL at /agent.php from Cursor, Claude Desktop, VS Code, or any HTTP/MCP client.
Quick Start
1. Open the web app
Production:
https://uploads.craffo.com
Local Herd: https://uploads.test
Default web password: 2030 (change in index.php).
2. Generate an API key
Required for MCP and programmatic API access:
php -r "file_put_contents('.api-key', bin2hex(random_bytes(32)));"
Or set the environment variable UPLOAD_CENTER_API_KEY.
3. Connect your AI agent
Run ./bin/setup-mcp-config.sh or point your MCP client at /agent.php with your API key.
See Agent API for details.
Web UI
Log in and use the file browser to manage uploads.
| Feature | Description |
|---|---|
| File browser | List view with thumbnails, sortable columns, preview pane |
| Upload | Drag & drop or toolbar — uploads go to the current folder |
| New Folder | Create subfolders under /uploads |
| Multi-select | Click, Shift+click, Ctrl/Cmd+click — copy or delete in bulk |
| URL export | One-per-line and comma-separated copy buttons |
| Breadcrumb | Navigate folders; double-click to open |
Keyboard shortcuts
Ctrl/Cmd + A— select allCtrl/Cmd + C— copy selected URLsDelete— delete selected items
Authentication
All API endpoints support two auth methods:
Session (web UI)
Log in via the web interface. Requests use the PHP session cookie.
API key (MCP, scripts, curl)
X-API-Key: your-api-key-here
Or Bearer token:
Authorization: Bearer your-api-key-here
The key is read from UPLOAD_CENTER_API_KEY env var or the .api-key file in the project root.
HTTP API
All endpoints return JSON. Paths are relative to /uploads (e.g. products/banner.jpg).
GET list.php
List folders and images.
| Param | Description |
|---|---|
path | Folder inside uploads (optional) |
curl -H "X-API-Key: $(cat .api-key)" \
"https://uploads.craffo.com/list.php?path=products"
POST upload.php
Upload images. Body: multipart/form-data
| Field | Description |
|---|---|
files[] | Image file(s) |
path | Target folder (optional) |
Max 8 MB per file. Types: jpg, jpeg, png, webp, gif.
curl -H "X-API-Key: $(cat .api-key)" \
-F "files[]=@/path/to/image.jpg" \
-F "path=products" \
https://uploads.craffo.com/upload.php
POST mkdir.php
curl -H "X-API-Key: $(cat .api-key)" \
-H "Content-Type: application/json" \
-d '{"path":"products","name":"summer-sale"}' \
https://uploads.craffo.com/mkdir.php
POST delete.php
curl -H "X-API-Key: $(cat .api-key)" \
-H "Content-Type: application/json" \
-d '{"paths":["products/old.jpg","products/archive"]}' \
https://uploads.craffo.com/delete.php
POST clean.php
Empty a folder (all files and subfolders).
curl -H "X-API-Key: $(cat .api-key)" \
-H "Content-Type: application/json" \
-d '{"path":"products"}' \
https://uploads.craffo.com/clean.php
Configuration
| Setting | Location | Default |
|---|---|---|
| Web password | index.php | 2030 |
| Max upload size | upload.php | 8 MB |
| Allowed types | helpers.php | jpg, jpeg, png, webp, gif |
| MCP base URL | UPLOAD_CENTER_URL | https://uploads.craffo.com |
Uploaded files are stored as: {timestamp}_{random}_{name}.{ext}
Security
- Change the default web password before deploying
- Keep
.api-keysecret — never commit it - Path traversal is blocked on all endpoints
uploads/.htaccessdenies script execution- API key comparison uses timing-safe
hash_equals()
Agent API (URL)
All AI agents connect via HTTP to a single URL. No local Node process or project path required.
https://uploads.craffo.com/agent.phpAuth header:
X-API-Key: your-key-from-.api-keyProtocols: Simple JSON API + MCP JSON-RPC 2.0
Discover capabilities
curl -H "X-API-Key: $(cat .api-key)" \
https://uploads.craffo.com/agent.php
Returns a manifest with all tools, endpoints, and auth info.
Call a tool (simple JSON)
curl -H "X-API-Key: $(cat .api-key)" \
-H "Content-Type: application/json" \
-d '{"tool":"list_uploads","arguments":{"folder":""}}' \
https://uploads.craffo.com/agent.php
Upload images (base64)
curl -H "X-API-Key: $(cat .api-key)" \
-H "Content-Type: application/json" \
-d '{
"tool": "upload_images",
"arguments": {
"folder": "products",
"files": [
{
"name": "photo.jpg",
"content_base64": "'$(base64 -i photo.jpg)'"
}
]
}
}' \
https://uploads.craffo.com/agent.php
MCP JSON-RPC (for MCP clients)
curl -H "X-API-Key: $(cat .api-key)" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' \
https://uploads.craffo.com/agent.php
Connect any MCP client via URL
Use this config in Cursor, Claude Desktop, VS Code, or any MCP client that supports remote URL servers. Replace the API key with your value from .api-key:
{
"mcpServers": {
"upload-center": {
"url": "https://uploads.craffo.com/agent.php",
"headers": {
"X-API-Key": "paste-your-api-key-here"
}
}
}
}
| Client | Config file |
|---|---|
| Cursor | .cursor/mcp.json |
| Claude Desktop | ~/Library/Application Support/Claude/claude_desktop_config.json |
| VS Code / Continue | Extension MCP settings |
| Custom scripts | POST to agent.php with X-API-Key |
MCP Tools
Five tools exposed to connected agents:
Upload images via base64 and return public URLs.
| Param | Required | Description |
|---|---|---|
files | yes | Array of { name, content_base64 } |
folder | no | Target folder inside uploads |
For multipart upload from a script, use POST /upload.php instead.
List folders and files in a directory.
| Param | Required | Description |
|---|---|---|
folder | no | Folder path (empty = root) |
Create a new folder.
| Param | Required | Description |
|---|---|---|
name | yes | Folder name |
folder | no | Parent folder path |
Delete files or folders (recursive). Destructive — confirm with user first.
| Param | Required | Description |
|---|---|---|
paths | yes | Array of paths relative to uploads |
Export public URLs in various formats.
| Param | Required | Description |
|---|---|---|
folder | no | All URLs in folder |
paths | no | Specific file paths |
format | no | lines · comma · json |
Common Workflows
Upload and return URLs
create_upload_folder(optional)upload_imageswith file pathsget_upload_urlswith desired format
Excel / comma-separated URLs
upload_imagesget_upload_urlswithformat: "comma"
Path conventions
| Correct | Wrong |
|---|---|
photo.jpg | uploads/photo.jpg |
products/banner.png | /uploads/products/banner.png |
AI Agent Guide
https://uploads.craffo.com/agent.php with X-API-Key. Use MCP JSON-RPC or simple JSON { tool, arguments }. Never invent URLs.
Decision guide
| User request | Action |
|---|---|
| "Upload this image" | upload_images |
| "Upload to products folder" | create_upload_folder → upload_images |
| "Comma-separated URLs for Excel" | get_upload_urls format comma |
| "What's uploaded?" | list_uploads |
| "Delete this image" | delete_uploads (confirm first) |
Do's and don'ts
Do
- Use absolute paths for
file_paths - Return URLs directly to the user
- Use
commaformat for Excel - List folder before deleting unknown paths
Don't
- Don't invent URLs
- Don't delete without user confirmation
- Don't upload non-image files
- Don't assume filenames stay the same after upload
Troubleshooting
| Problem | Solution |
|---|---|
| 401 Unauthorized | Check .api-key or log in via web UI |
| 301 redirect / HTML response | Use HTTPS URL |
| MCP client not loading | Use URL config pointing to agent.php, set X-API-Key header, restart client |
| Invalid MIME type | File must be a real image, not empty/renamed |
| Invalid folder name | Use letters, numbers, hyphens, underscores only |