upload-files — Claude Code skill: upload files to ImageKit
A skill that pushes files into the ImageKit media library over DAM MCP: it signs each file and runs the POST where the file actually lives.
npx skills add imagekit-developer/skills --skill upload-files -a claude-codeWhat upload-files does
Reach for this when assets belong in the ImageKit media library and you would rather not shuttle their contents through the chat. File bytes stay out of the conversation — no base64, no data URIs, no buffers or streams. Large files break that route anyway.
Under the hood each upload is a multipart/form-data POST to ImageKit's upload endpoint, authorized by a short-lived single-use signature. The DAM server signs and nothing more. The file travels straight from its source: off the user's disk when it is local, or fetched by ImageKit when it is a public URL. With a shell available, call create_upload_signatures_in_bulk and then run the uploadCommand it returns. That command enters the local directory, pulls the manifest, and pushes up to 16 files at once, printing one line per file. No shell? Use upload_file with no parameters and a picker opens for filename, folder, tags and custom metadata. create_upload_signature is for the case where the user uploads elsewhere and needs the signed form fields.
Signatures last between 60 and 3,600 seconds, 600 by default. Re-run the same command before expiry and failed files are retried while anything already uploaded is rejected instead of duplicated. Once the window closes the command prints manifest unavailable and uploads nothing, so you sign again. Treat the manifest URL as a credential: whoever holds it can upload the signed files until it expires.
What it helps with
- push a batch of local files into the ImageKit media library
- sign an upload without pulling file contents into the chat
- have ImageKit fetch a file from a public URL
- hand a user signed form fields for their own upload
- confirm the files actually reached the library
Example prompts for the agent
- Upload every image in
assets/heroto ImageKit - Sign these files for upload, I'll push them with my own script
- Check with
search_media_librarythat the files are in the media library
How to install upload-files
1Skills CLI (Vercel)
npx skills add imagekit-developer/skills --skill upload-files -a claude-code2Manually: put the files in place
~/.claude/skills/upload-files/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/upload-files/
1Skills CLI (Vercel)
npx skills add imagekit-developer/skills --skill upload-files -a codex2Manually: put the files in place
.agents/skills/upload-files/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add imagekit-developer/skills --skill upload-files -a cursor2Manually: put the files in place
.cursor/skills/upload-files/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install imagekit-developer/skills upload-files2Manually: put the files in place
.github/skills/upload-files/SKILL.md1Skills CLI (Vercel)
npx skills add imagekit-developer/skills --skill upload-files -a gemini-cli2Platform CLI
gemini skills install https://github.com/imagekit-developer/skills --path skills/upload-filesManually: put the files in place
.devin/skills/upload-files/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add imagekit-developer/skills --skill upload-files -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about upload-files
How do I install upload-files in Claude Code?
Run npx skills add imagekit-developer/skills --skill upload-files -a claude-code. The skill then sits at ~/.claude/skills/upload-files/SKILL.md.
What does upload-files do?
It walks the agent through uploading files to the ImageKit media library over DAM MCP: it obtains signatures and runs the POST wherever the file lives, keeping file contents out of the conversation.
Why can't the file be passed as a tool argument?
The skill rules out base64, data URIs, buffers and streams — they burn tokens and fail on large files. Signatures are single-use and short-lived, so sign shortly before uploading.
Source text
SKILL.md · MIT
--- name: upload-files description: "Upload files to the ImageKit media library via DAM MCP. With a shell, use create_upload_signatures_in_bulk for any number of local files or URLs; without one, upload_file (interactive picker); create_upload_signature only when the user runs the upload elsewhere. Never inline file bytes into the conversation." --- # Upload files Uploads go through DAM (`https://imagekit.io/mcp/dam`). **Never put file bytes in the conversation or a tool argument.** No base64, data URIs, Buffers, or streams. That burns tokens and fails for large files. ## How an upload works An upload is a multipart/form-data POST to ImageKit's upload endpoint, authorized by a short-lived, single-use signature. The DAM server only signs. The file goes straight from where it lives to ImageKit: from the user's machine for a local file, or fetched by ImageKit for a public URL. Your job is to get a signature for each file and make sure the POST runs where the file is. ## Which tool | Situation | Call | |-----------|------| | You can run shell commands in the user's environment (one file or many, local paths or public URLs) | `create_upload_signatures_in_bulk`, then run the returned `uploadCommand`. | | No shell, and the user wants to pick a file on their computer (the client can show MCP Apps) | `upload_file` with **no parameters**. Opens a picker (filename, folder, tags, custom metadata). | | The user will run the upload themselves elsewhere and needs the signed form fields | `create_upload_signature`; they POST each file with its `formFields`. | Prefer `create_upload_signatures_in_bulk` whenever there is a shell, even for a single file: the signed tokens never enter the conversation, and one command uploads everything and reports a status line per file. If they asked you to write upload code for their app, use `search_docs` — do not upload to their library unless they asked for that. ## `create_upload_signatures_in_bulk` - Signs 1 to 1,000 entries in one call. Each entry is either a file directly inside one local directory or a public URL, with its own `fileName`, `folder`, and upload fields. - The tokens are not returned. They stay on the server behind `manifestUrl` until `expire` (60 to 3,600 seconds, default 600). Pass `localDirectory` so the command knows where the local files are. - Run the returned `uploadCommand` in the user's shell. It changes into the local directory, fetches the manifest, and uploads up to 16 files at a time. - It prints one line per file: `<status> <name>`. `200` means uploaded. `SKIP <name>` means the name was refused locally (empty, contains `/` or `"`, or starts with `.`). - Before expiry, re-running the same command retries failed files. Files that already uploaded are rejected, not duplicated. After expiry it prints `manifest unavailable` and uploads nothing, so sign again. - Treat the manifest URL like a credential: anyone who has it can upload the signed files until it expires. Do not paste it anywhere other than the command. ## `create_upload_signature` For when the user runs the upload themselves (their own script or another machine). The result contains the signed tokens. - One call can sign several files: send one entry per file with `fileName`, plus optional `folder`, `tags`, `customMetadata`, and other upload fields. `expire` applies to all of them. - The result has `uploadUrl` and, per file, `formFields`: the exact fields its signature is bound to, including `token`. - Each file is POSTed to `uploadUrl` with `file=@<LOCAL_FILE_PATH>`, or `file=<PUBLIC_URL>` to have ImageKit fetch it, plus that file's `formFields` exactly as returned. Adding, removing, or re-serializing fields fails the signature check. - Tokens are short-lived and single-use. Sign shortly before uploading. ## Procedure 1. Confirm folder, filename, tags, and custom metadata. Fields must already exist (`list_custom_metadata_fields`). 2. Call the tool from the table above. 3. Confirm the files landed with `search_media_library`, the upload responses, or the bulk command's status lines. ## Notes - Folder is a media-library path starting with `/`, not a local path. Nested folders are created as needed. - Free plan limits: 25MB images, 100MB videos. Max 100 versions per file. - To preserve a migrated asset's original creation date, set the reserved `_internal_original_created_datetime` custom metadata key to an ISO 8601 string. It exists only on accounts that enabled the original creation date setting; check `list_custom_metadata_fields` for it (`reserved: true`).
© imagekit-developer · MIT · imagekit-developer/skills