gh-image CLI
A GitHub CLI extension and agent skill that uploads screenshots, PDFs, archives and logs to issues and pull requests and returns a ready link
- 279 ★ on the repository
- Last commit
- MIT
Broad access
Why this level
- Reads the encrypted browser cookie store and takes `user_session`, which gives full access to your GitHub account
- Publishes the chosen files on GitHub under your name, and an upload cannot be removed
- Calls undocumented GitHub endpoints, and `gh image -- ...` also writes to issues and PRs
Install
- Works in
Manual install
gh extension install drogers0/gh-imageRequires an installed and authenticated `gh`. Prebuilt releases exist for macOS, Linux, Windows and Android (Termux).
Access and checks
How we reviewBroad accessThe tool can change data, run commands or handle secrets.
- Reads the encrypted browser cookie store and takes `user_session`, which gives full access to your GitHub account
- Publishes the chosen files on GitHub under your name, and an upload cannot be removed
- Calls undocumented GitHub endpoints, and `gh image -- ...` also writes to issues and PRs
This is third-party code. Review the repository files before installing.
What it does
gh-image is a Go extension for `gh`. The command `gh image screenshot.png` uploads a file through the internal endpoint used by the GitHub web interface and prints a ready link: an inline embed for images, a bare URL for video that GitHub shows with a player, and a download link for other files. You can pass several files at once and name the repository with `--repo` or let it come from `origin` of the current folder. If a `gh` command follows `--`, the extension uploads the files and puts the links into the message body: `gh image bug.png -- issue comment 42 --body-file repro.md`. References to local files such as `` are replaced with the uploaded ones, and files mentioned nowhere are appended at the end. The `gh image download` subcommand fetches attachments back to disk. Images and video going to a repository you can push to are uploaded with the `gh` token. Other file types and repositories you cannot push to are uploaded as your session: the extension reads the `user_session` cookie from the browser store or takes a token from `GH_SESSION_TOKEN`. It then fetches the `uploadToken` from the repository page, requests an upload policy, sends the file to S3 and confirms the upload with GitHub. The bundled `github-image-upload` skill checks that the extension is installed, asks for confirmation and inserts the result into a PR description, issue or comment.
Who it is for. For people who ask an agent, or do it themselves, to put screenshots, logs and PDFs into GitHub issues, pull requests and READMEs, especially in other people's repositories where there is no write access.
Good fit when
- A bug report in a project where you lack write access needs a screenshot
- An issue or PR needs a PDF, archive, CSV or log attached, not only an image
- You need a file link for a README, a commit message or a chat rather than an issue
- An agent should attach evidence to a PR on a request like "add the screenshot to the description"
- CI needs to publish test screenshots to a PR with no human involved
Not a fit when
- The attachment goes to an issue or PR in a repository you can push to and it is an image or video: `gh` 2.99.0 and newer has the `--attach` flag for that
- You cannot give the extension access to your GitHub session: some uploads work only through the `user_session` cookie or `GH_SESSION_TOKEN`
- You need a stable contract: the extension uses an undocumented internal GitHub interface that may change without notice
- You are on Windows with Chrome 127 or newer, or in Termux without a browser, and have no session token to substitute: the cookie store is unavailable there
Example request
Attach this screenshot to a comment on PR 42 so it renders inlineLimitations
- Use the tool only with your own GitHub account and repositories you have access to. The `user_session` cookie grants full account access and is not scoped like a personal token. If it leaks, sign out of GitHub on that machine or revoke the session in settings.
- The extension reads the encrypted cookie store of Chrome, Brave, Chromium, Edge, Firefox, Opera or Safari. On macOS a Keychain prompt may appear.
- It uses an undocumented internal GitHub interface. Uploads are tied to the account whose session was found: if your browser and `gh` are logged in as different accounts, images and other files end up under different authors.
- A file that no published text links to resolves only for the uploader.
- For CI the authors advise a separate bot account, since a leaked personal session secret compromises your account.
- Building from source needs Go 1.26 or newer. MIT license.
How to disable. Run `gh extension remove gh-image`. A skill installed with `npx skills add drogers0/gh-image` is removed with `npx skills remove`. If a session token sits in CI secrets or in the `GH_SESSION_TOKEN` variable, delete it and, if in doubt, end the session on the Settings, Sessions page. Uploaded attachments stay on GitHub while they are referenced.
FAQ
Why gh-image if gh now has --attach?
Since 1 September 2026 `gh` 2.99.0 and newer can attach an image or video to an issue or PR in a repository you can push to, and the flag takes nine extensions. The extension covers the rest: any file type, repositories without write access, a link on its own, downloading attachments and CI, where `--attach` rejects the `GITHUB_TOKEN`.
Where does the session token come from?
The order is the `--token` flag, then the `GH_SESSION_TOKEN` variable, then the browser cookie store. The `gh image extract-token` subcommand prints the token to stdout, and `gh image check-token --token ...` checks which user it works as. The `--token` flag shows up in the process list, so the variable is preferable.
Who can see an uploaded file?
Until the link appears in published text, the URL opens only for the uploader, even in a public repository. Once linked, visibility follows the text, and uploads to private repositories stay private.
How do I run it in GitHub Actions?
Get the token locally with `extract-token`, create an environment restricted to trusted branches, store the token as its `GH_SESSION_TOKEN` secret and call `gh image` in a job bound to that environment. The authors advise a separate bot account and a scheduled `check-token`, since the session expires when GitHub invalidates it.
How do I verify the binary?
Releases carry build provenance attestations. Download the file from the releases page and run `gh attestation verify darwin-arm64 --owner drogers0`, using your own file name. The `gh extension install` command itself does not verify attestations.
Discussion
No questions or reviews yet.
Related
CLI toolsThe GitHub CLI extension gh stack and an agent skill: a chain of dependent branches and PRs with rebase, submit and merge of the whole stack
GitHub CLI skills
GitHub CLI skills (gh, gh-skill)
Official GitHub CLI skills: how an agent should call gh correctly and how to manage skills with gh skill
A CLI that opens a local git diff in the browser like GitHub's Files changed tab; comments copy out as prompts for an agent
A terminal diff viewer: all files in one stream, and an agent with the hunk-review skill walks through the changes and leaves line comments
A git worktree CLI with a fuzzy finder: one folder per branch so several agents can work in parallel without conflicts
GitFlic MCP built on gitflic-cli
gitflic-cli MCP-сервер
An MCP server with 76 typed tools over a GitFlic CLI: merge requests, issues, releases, package registry, with group filters and a read-only mode
Comparison with similar tools
Entries that share the main search query, and how they differ.
| Entry | Official | Repository stars | Main difference |
|---|---|---|---|
| gh-image (this entry) | no | 279 | |
| GitHub CLI skills | no | 46,712 | official GitHub CLI skills on how an agent calls gh and manages skills, without attachment uploads |
| gh-axi | no | 345 | a wrapper around gh with compact TOON output and next-step hints for issues, PRs and CI |
README in short
The description opens with a banner and sample output, then explains how the extension complements the built-in `--attach`. It continues with installation including build provenance checks, building from source and a variant with another cookie reader, usage, downloading and one-command posting, an agent section, user examples, authentication methods, CI, how it works and limitations. The documentation folder separately holds write-ups of the architecture and of the reverse-engineered upload and download protocols.
README badge
Original SKILL.md
--- name: github-image-upload description: >- Upload local images and other files (PDF, zip, log, …) to GitHub and embed them in a pull request description, an issue, or a comment — producing canonical github.com/user-attachments URLs (private-repo uploads stay private). Use when asked to "attach a screenshot to the PR", "add an image to the PR description", "put this image in the issue", "attach this PDF/log/zip to the issue", "show test results in the PR", "embed before/after screenshots", or any request to visually document or attach files to changes on GitHub. Powered by the `gh-image` gh CLI extension. license: MIT compatibility: Requires the GitHub CLI (`gh`), network access to GitHub, and the `drogers0/gh-image` extension v1.1.0 or newer. # gh pr/issue edit and comment are listed for hosts that check each pipeline stage; # whole-string matchers resolve them via the leading printf. allowed-tools: >- Glob Bash(gh auth status) Bash(gh extension list:*) Bash(gh image:*) Bash(gh pr view:*) Bash(gh pr edit:*) Bash(gh pr comment:*) Bash(gh issue view:*) Bash(gh issue edit:*) Bash(gh issue comment:*) Bash(printf:*) Bash(grep:*) Bash(cat:*) --- # Upload images and files to GitHub (gh-image) [`gh-image`](https://github.com/drogers0/gh-image) (MIT, same author as this skill) uploads files through the internal endpoint GitHub's web UI uses — there is no public API — and prints a ready-to-paste reference: an `` embed for images, a bare URL for videos, a `[name](url)` link for anything else. This skill runs it and embeds the result. Follow these steps exactly unless they conflict with security policies you have been given; if they do, stop and present the conflict rather than resolving it yourself. ## Prerequisites Check these first. Report failures — do not install or authenticate for the user. 1. `gh auth status` — if it fails, tell the user to run `gh auth login`. 2. `gh extension list | grep 'drogers0/gh-image' && gh image --version` Needs v1.4.0+, the release that added the `--` form used below (`--version` prints `gh-image 1.4.0`; compare semantically, so `1.10.0` ≥ `1.4.0`). Missing → the user runs `gh extension install drogers0/gh-image`. Older → the user runs `gh extension upgrade gh-image`. `dev` → a local build, warn and continue. Never run install or upgrade yourself.