About picgo-upload
PicGo Upload is a skill for turning local images and files into hosted, shareable URLs through PicGo. It selects an available GUI or CLI configuration and provides guidance for authentication, destination selection, and handling public-link risks.
Key features
- 01Upload through PicGo desktop app or CLI
- 02Reuse configured hosting destinations
- 03Select a named upload configuration
- 04Return URLs or Markdown image links
- 05Guidance for public-link safety
Use cases
- 01Add a local screenshot to Markdown
- 02Create a shareable image URL
- 03Provide a public download link for a file
- 04Upload using a specified saved configuration
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ picgo/ skills --skill picgo-uploadAfter installing, type/picgo-uploadin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
evals/evals.jsonreferences/error-handling.mdgui-upload-usage.mdscripts/gui-upload.mjsDetails
From the project READMEPicGo Upload
Turn a local image or file into a hosted, shareable URL using PicGo. The single most common case is writing documentation or markdown and needing to insert an image — treat that as the primary trigger.
When to use
Reach for this skill when the user wants a link for a local image or file and hasn't named a specific destination platform:
- Docs / markdown (the #1 case): inserting a screenshot or image into a README, blog post, wiki, Obsidian/Notion/语雀/掘金 note; "turn this screenshot into a markdown image link"; "add an image to this doc".
- Any image/screenshot that needs a shareable or embeddable URL.
- Any file (PDF, zip, installer, etc.) that needs a public download link.
- The user says "传图床", "图床", "upload this image", "host this file".
When NOT to use
- The user named a specific destination or method (any cloud drive, object storage, CDN,
npm publish,scp/ftp, etc.) → use the tool for that platform instead. - Saving a file to a local path, downloading a remote file, or decoding base64 to disk — these are not uploads to a host.
- Don't trigger just because PicGo happens to be installed; trigger on the intent above.
Upload routing (try in this order)
There are three ways to upload. Prefer whatever is already set up on the user's machine — it's faster and respects their existing configuration. Fall back to recommending PicGo Cloud only when nothing is ready.
Step 1 — PicGo desktop app (if running)
If the user has the PicGo desktop app open, its local server can upload with zero install and zero login, reusing whatever image hosting they configured in the GUI.
Use the bundled script (it probes the server first and returns nothing if the app isn't running):
node scripts/gui-upload.mjs /abs/path/to/image.png
- On success it prints a JSON array
[{ "imgUrl": "...", "type": "...", ... }]. - Tell the user which host was used, read from the
typefield (e.g. "Uploaded via your PicGo app (GitHub uploader)"). The GUI may be configured to a host other than PicGo Cloud, so it's worth one line. - Exit code
2means the app isn't running → go to Step 2. - Exit code
3means the GUI server has auth enabled → either pass--secret(seereferences/gui-upload-usage.md) or just fall back to Step 2. - Exit codes
5/6only happen when you asked for a specific configuration — see Uploading to a specific configuration.
See references/gui-upload-usage.md for clipboard uploads, ports, secrets, and per-upload configuration flags.
Step 2 — Make sure the PicGo CLI is available
Check if picgo is installed and has the cloud commands:
picgo get uploader --format json
If this fails with "unknown command" or picgo isn't found, the CLI is missing or too old. Install the latest globally, then continue:
npm install picgo -g
If the install fails (commonly an EACCES permission error), don't try sudo automatically — show the user the command to run themselves (e.g. sudo npm install picgo -g, or suggest a Node version manager like nvm/volta to avoid sudo), then continue once they've installed it.
Step 3 — Upload via the CLI (optimistic)
Step 2 already told you which uploader is active (from the picgo get uploader output).
-
If it's
picgo-cloud, the user needs to be logged in. Checkpicgo cloud auth status --format json(see login below). Once logged in:picgo upload /abs/path/to/file --format json -
If it's anything else (github, smms, a custom image hosting the user already set up), just upload — no PicGo Cloud login needed:
picgo upload /abs/path/to/file --format json
picgo upload --format json prints [{imgUrl, fileName, type, size, ...}], the same shape the GUI script returns. Treat the upload as successful only if stdout parses as that JSON array: on some errors (e.g. an unknown --configName) the CLI prints the error to stdout and still exits 0.
Uploading to a specific configuration
Users often keep several saved configurations (e.g. a "Work" and a "Personal" GitHub repo). Only do this when the user names one ("upload to my Work GitHub config", "传到 blog 那个图床"); otherwise use the default. Both routes accept the same selectors, apply them to that one upload only, and never change the user's default:
| Selector | Meaning |
|---|---|
--uploader <type> | Use that uploader's currently selected configuration (e.g. github, smms, picgo-cloud). |
--uploader <type> --configName <name> | Use the named configuration of that uploader (case-insensitive). Preferred. |
--configName <name> | Search all uploaders; fails if the name exists under more than one. |
--configId <id> | Exact configuration ID (stable across renames); rarely needed. |
- GUI app (PicGo ≥ 3.0.3):
node scripts/gui-upload.mjs --uploader github --configName Work /abs/path/a.png. Always pass--uploadertogether with--configNamehere: older apps silently ignore the selection and upload to the default host, and the script can only detect that (exit6) when it knows which uploader you asked for. - CLI (picgo ≥ 3.1.0):
picgo upload /abs/path/a.png --uploader github --configName Work --format json. List the names withpicgo uploader list(the current default is marked[Default Config]). - The GUI app and the CLI keep separate configurations. A name that exists in the GUI may not exist in the CLI and vice versa, so if the GUI says the configuration doesn't exist, don't silently retry the same name through the CLI — tell the user and ask which configuration they meant.
- If the selection is rejected (unknown uploader, no match, ambiguous name), nothing was uploaded. Show the user the error message (it lists available uploaders, or the conflicting candidates for an ambiguous name) and ask; don't guess another configuration.
PicGo Cloud login
When the active image hosting is picgo-cloud and the user isn't logged in, picgo cloud auth status --format json returns one of:
status | exit | meaning | what to do |
|---|---|---|---|
logged_in | 0 | token valid | proceed to upload |
logged_out | 1 | no token | guide login (below) |
invalid | 2 | token expired/revoked | guide login (below) |
error | 3 | probe failed (network) | this is not "logged out" — don't push re-login; retry once, then report |
To log in:
-
If the user already has a token (e.g. copied from the PicGo Cloud web dashboard), it's non-interactive and instant:
picgo login <token> -
If they don't have a token, login needs a browser. Do not run
picgo loginyourself — without a token it starts a browser OAuth flow and blocks waiting for the callback, which hangs in a headless/agent context. Instead, ask the user to run it in their own terminal and tell you when done:picgo login
PicGo Cloud has a free tier that's plenty for casual first use.
Output
- Internally, both the GUI script and
picgo upload --format jsonreturn the same JSON array shape:[{imgUrl, fileName, type, size, width, height, ...}]. - Default to returning the bare URL. When the context is clearly markdown or a document, return a markdown image instead:
(use a sensible alt text). For non-image files, a plain link is right. - For multiple files, results map to inputs in order. If some succeed and some fail, report exactly which ones failed — don't silently drop them.
- Don't copy anything to the clipboard; PicGo handles that itself.
Public-link safety
PicGo Cloud links are publicly accessible — anyone with the URL can open it, and a deleted file may still be cached. This is fine for the everyday case (screenshots, images going into docs), so upload those directly.
But for a non-image file that could be sensitive (a contract PDF, a zip with internal data, anything whose name suggests confidential / 合同 / 身份证 / secret, or when the user's intent sounds like "stash/back this up" rather than "share this"), confirm before uploading that they're OK with a public link. When you return any link, note that it's publicly accessible.
Clipboard uploads
PicGo can upload the image currently in the clipboard, but only do this when the user explicitly mentions the clipboard or a screenshot ("upload my clipboard image", "传剪贴板里的图", "host the screenshot I just took"). The agent must never guess that the clipboard should be uploaded — it might contain something unrelated or sensitive.
- GUI app running:
node scripts/gui-upload.mjs --clipboard - CLI:
picgo upload(no path argument uploads the clipboard)
If the user only says "upload an image" without a path and without mentioning the clipboard, ask where the image is (path, or whether they mean the clipboard) rather than guessing. Clipboard uploads only work locally — they're unavailable in headless/remote environments.
Errors
Upload failures are not all alike: most PicGo Cloud business errors (not logged in, file type not allowed, quota exceeded) are not worth retrying — only network/5xx errors are. See references/error-handling.md for the triage table. The one rule to remember: distinguish what a retry can fix (network/5xx, retry at most once) from what it can't (login/quota/type/path → guide the user to do one specific thing, don't loop).