This folder is a small HTTP JSON API for AI agents to upload, list, and delete public files on Vercel Blob. There is no database and nothing is stored on the PHP server’s filesystem — only in your Blob store under the prefix (blob root).
Humans open the returned url in a browser. Images and PDFs use the Vercel Blob URL directly; HTML uses view.php; audio and video use play.php with a mobile player. Agents use mcp.php for all operations.
Use this when an AI agent needs to publish a file (chart, screenshot, PDF report, simple HTML page) and get back a stable HTTPS link to share with a human or embed elsewhere.
Other extensions are rejected. The filename must include the correct extension so the MIME type is set for inline display.
secrets.php (not in git — copy from secrets.php.example):
CDN_AUTH_TOKEN — secret shared with your agent; required on every API call.VERCEL_BLOB_TOKEN — Vercel Blob read-write token from your Vercel project.settings.php (safe to commit):
VERCEL_BLOB_API_BASE — usually https://blob.vercel-storage.com.CDN_BLOB_PREFIX — folder prefix inside Blob (empty = root).CDN_PUBLIC_BASE_URL — optional full URL to this folder if auto-detect fails behind a proxy.CDN_MAX_UPLOAD_BYTES — max file size per upload (currently 100 MB).Every request to mcp.php must be authenticated. Send Authorization: Bearer <CDN_AUTH_TOKEN> or include "token" in the JSON body (or ?token= for read-only GET list).
Uploaded files are public on Vercel Blob. Anyone with the URL can open them. Do not upload secrets.
mcp.php (JSON API)Use POST with a JSON body. Every request must include "action" and authentication.
GET ?action=list&token=… is supported for read-only listing.
{"action":"list","token":"YOUR_TOKEN"}
Returns all files under the configured Blob prefix with pathname, url, size, and uploaded_at.
Look up one file by pathname or public url (play.php, stream.php, view.php, or Vercel Blob).
{"action":"get","token":"YOUR_TOKEN","url":"https://example.com/cdn/play.php?pathname=uuid-track.mp3"}
Send file bytes as base64 (recommended) or raw UTF-8/binary in content for small HTML. Max 100 MB per request (see CDN_MAX_UPLOAD_BYTES in settings.php).
{
"action": "upload",
"token": "YOUR_TOKEN",
"filename": "chart.png",
"content_base64": "iVBORw0KGgoAAAANSUhEUg..."
}
On success the response includes url — give this link to the human.
url (also in blob_url).url points to view.php?pathname=…. Raw blob URL is in blob_url.url points to play.php?pathname=… (mobile player with resume). Stream URL is stream.php; raw blob in blob_url.Delete one file by pathname or public url (play.php, stream.php, view.php, or Vercel Blob).
{"action":"delete","token":"YOUR_TOKEN","url":"https://example.com/cdn/play.php?pathname=uuid-track.mp3"}
Deletes every file under the configured CDN prefix. Use with care.
{"action":"delete_all","token":"YOUR_TOKEN"}
view.php (HTML proxy)Public, no auth. Fetches HTML from Vercel Blob and serves it with Content-Type: text/html and Content-Disposition: inline.
GET view.php?pathname=uuid-page.html
Only .html / .htm files under your CDN prefix are allowed.
play.php (audio / video player)Public, no auth. Mobile-friendly player with play/pause toggle, ±15 s skip, seek bar, sleep timer (15 / 30 / 60 min), download, and playback position saved in localStorage for resume.
GET play.php?pathname=uuid-track.mp3
Supported: mp3, m4a, webm. Media bytes are served via stream.php (Range-aware proxy).
stream.php (media proxy)Public stream proxy with byte-range support for seeking. Append &download=1 to force download.
GET stream.php?pathname=uuid-track.mp3 GET stream.php?pathname=uuid-track.mp3&download=1
filename.url from the upload response (not ?download=1).url from the upload response (the view.php link).url from the upload response (the play.php link).JSON includes "ok": true on success. Errors return HTTP 4xx/5xx with "ok": false and an error field.
PHP 7.2+, no database, no local file storage, Vercel Blob for public CDN URLs.