blink-storage
MCP Tools
| Tool | Description |
|---|---|
blink_storage_list |
List files in project storage with optional path prefix |
blink_storage_url |
Get the public CDN URL for a stored file |
blink_storage_delete |
Delete a file from storage |
Getting Started
# Upload a file
blink storage upload ./photo.jpg --path uploads/photo.jpg
# List files
blink storage list
# List files in a path
blink storage list uploads/
Auth Requirements
| Operation | Auth Required | Notes |
|---|---|---|
upload() |
❌ No | Public add-only (no overwrite) |
download() |
✅ Yes | Signed URL |
remove() |
✅ Yes | Requires JWT |
Upload
const { publicUrl } = await blink.storage.upload(
file,
`uploads/${Date.now()}.${file.name.split('.').pop()}`,
{ onProgress: (percent) => console.log(`${percent}%`) }
)
SDK auto-detects file type from content and corrects the extension. Uploads are add-only — duplicate paths return 409. Use timestamps or random IDs for uniqueness.
Download
const { downloadUrl, filename } = await blink.storage.download('images/photo.jpg')
window.open(downloadUrl, '_blank')
// Custom filename
const { downloadUrl } = await blink.storage.download('images/photo.jpg', {
filename: 'my-photo.jpg',
})
Remove
await blink.storage.remove('uploads/file1.jpg')
await blink.storage.remove('file1.jpg', 'file2.jpg', 'file3.png') // multiple
Common Patterns
Avatar Upload
const handleAvatarUpload = async (file: File) => {
const { publicUrl } = await blink.storage.upload(
file,
`avatars/${user.id}-${Date.now()}.${file.name.split('.').pop()}`
)
await blink.auth.updateMe({ avatar: publicUrl })
return publicUrl
}
Upload with Progress
const [progress, setProgress] = useState(0)
const handleUpload = async (file: File) => {
const { publicUrl } = await blink.storage.upload(
file,
`documents/${Date.now()}.${file.name.split('.').pop()}`,
{ onProgress: (percent) => setProgress(percent) }
)
return publicUrl
}
For AI Image Input
Upload first to get an HTTPS URL with extension — required for AI vision.
const { publicUrl } = await blink.storage.upload(photo, `photos/${Date.now()}.jpg`)
const { text } = await blink.ai.generateText({
messages: [{ role: "user", content: [
{ type: "text", text: "What's in this image?" },
{ type: "image", image: publicUrl },
]}],
})
URL Format
Uploaded files return direct HTTPS URLs: https://storage.googleapis.com/{project}/uploads/{filename}.{ext} — publicly accessible, HTTPS, with file extension.
Common Errors
| Error | Cause | Fix |
|---|---|---|
| 409 conflict | Path already exists | Add timestamp/random ID |
| Invalid path | Special characters | Sanitize: path.replace(/[^a-zA-Z0-9_\-\/\.]/g, '_') |
| File too large | Exceeds limit | Compress or split file |
More from blink-new/blink-plugin
blink-backend
Blink Backend — Hono server on CF Workers for webhooks, server-side secrets, custom APIs. Pro+ only. Deploy via CLI.
4blink-full-stack
End-to-end guide for building and shipping a Blink app. Project setup, SDK init, auth, database, backend, deploy, and custom domains. Index to all other skills.
4blink-ai
AI Gateway for text generation, image generation/editing, video generation, text-to-speech, audio transcription, and AI phone calls. Unified access to 50+ models.
3blink-domains
Custom domain management. Add domains, DNS setup, SSL verification, domain search, and domain purchase via CLI.
3blink-realtime
WebSocket pub/sub messaging with channels, presence tracking, and message history. Real-time communication for chat, collaboration, and live updates.
3blink-queue
Background task queue and cron schedules. Enqueue tasks, named FIFO queues with parallelism, auto-retry. Requires Blink Backend (Pro+).
3