Download any GitHub folder without cloning — plan it first, verify it after, re-sync only what changed.
Addresses owner/repo/path#ref like degit, but streams big files past the 1 MB contents-API limit via the raw CDN, preserves folder structure, and gives every command --json for agents. The plan/verify/sync-dir loop — preview cost before downloading, prove local files match remote by git blob SHA, then fetch only the diff — exists in no other GitHub download tool.
Quick Start
# Health check first — works without a token; GITHUB_TOKEN raises the rate limit from 60 to 5000 req/h
github-contents-pp-cli doctor --dry-run
# One API call: how big is this folder, what file types are in it
github-contents-pp-cli stats mjwoon/AI-readings/books
# Preview the download: every file, sizes, total bytes, API cost — nothing is written
github-contents-pp-cli plan mjwoon/AI-readings/books
# Download recursively, preserving folder structure; big files stream via the raw CDN
github-contents-pp-cli fetch mjwoon/AI-readings/books --out ./books
# Prove every local file matches the remote by git blob SHA — no re-download
github-contents-pp-cli verify ./books mjwoon/AI-readings/books
Unique Features
These capabilities aren't available in any other tool for this API.
Plan-verify-sync loop
-
plan — Preview exactly what a fetch would download — file list, sizes, total bytes, API-request cost vs your remaining quota, and LFS-pointer warnings — before spending any bandwidth.
Run this before fetch to know a download is 122 files / 1.9 GB and costs only 2 API requests, instead of finding out mid-download.
github-contents-pp-cli plan mjwoon/AI-readings/books --agent
-
verify — Check whether a previously downloaded directory still matches the remote at a ref — match/changed/missing/extra per file — without re-downloading anything.
Proves 'this workspace matches ref X' cheaply — the post-download assertion CI and agents otherwise can't make without re-fetching.
github-contents-pp-cli verify ./books mjwoon/AI-readings/books --agent
-
sync-dir — Update an existing downloaded directory in place, fetching only files that changed upstream or are missing locally.
The weekly-mirror command: keeps a local collection current for the price of one API call plus only the changed bytes.
github-contents-pp-cli sync-dir ./books mjwoon/AI-readings/books --agent
Remote inspection
-
stats — Size and file-count breakdown of any repo path by subfolder and extension, plus the largest files, from a single API request.
Answers 'how big is this directory and what is in it' in one call before committing to a download.
github-contents-pp-cli stats mjwoon/AI-readings/books --agent --select by_folder
-
search — Search previously fetched repo listings from the local store — find files by name or pattern with zero API calls.
Lets agents answer 'which repo path had file X' from data already on disk instead of re-walking the API.
github-contents-pp-cli search "transformers" --limit 20
Recipes
Download a folder, keep the structure
github-contents-pp-cli fetch mjwoon/AI-readings/books --out ./books
Recursive download of one subdirectory; subfolders and filenames (including spaces) arrive intact.
Preview cost before a big download
github-contents-pp-cli plan mjwoon/AI-readings/books --agent
Machine-readable plan: files, total_bytes, api_cost, lfs_pointers — decide before spending bandwidth.
Only PDFs, nothing else
github-contents-pp-cli fetch mjwoon/AI-readings/books --include "*.pdf" --out ./pdfs
Glob filters restrict the download without changing the preserved structure.
Narrow a huge tree listing for an agent
github-contents-pp-cli trees mjwoon AI-readings main --recursive --agent --select tree.path,tree.size
The recursive tree of a repo is thousands of entries; --select keeps only the two fields an agent needs.
Keep a mirror current
github-contents-pp-cli sync-dir ./books mjwoon/AI-readings/books --agent
One API call to diff by blob SHA, then only changed or new files are streamed down.
Usage
Run github-contents-pp-cli --help for the full command reference and flag list.
Paths & environment variables
This CLI separates local files into four path kinds:
| Kind | Contents |
|---|
config | User-editable settings such as config.toml and saved profiles |
data | Durable local data: credentials.toml, data.db, cookies, browser-session proof files, and other auth sidecars |
state | Runtime state such as persisted queries, jobs, and teach.log |
cache | Regenerable HTTP/cache files |
Each kind resolves independently. The ladder is:
- Per-kind env var:
GITHUB_CONTENTS_CONFIG_DIR, GITHUB_CONTENTS_DATA_DIR, GITHUB_CONTENTS_STATE_DIR, or GITHUB_CONTENTS_CACHE_DIR
--home <dir> for this invocation
GITHUB_CONTENTS_HOME for a flat relocated root
- XDG env vars:
XDG_CONFIG_HOME, XDG_DATA_HOME, XDG_STATE_HOME, XDG_CACHE_HOME
- Platform defaults matching existing installs
For containers and agent sandboxes, prefer a single relocated root:
export GITHUB_CONTENTS_HOME=/srv/github-contents
github-contents-pp-cli doctor
Under GITHUB_CONTENTS_HOME=/srv/github-contents, the four dirs resolve to /srv/github-contents/config, /srv/github-contents/data, /srv/github-contents/state, and /srv/github-contents/cache.
MCP servers do not receive CLI flags from the host. Put relocation in the host env block:
{
"mcpServers": {
"github-contents": {
"command": "github-contents-pp-mcp",
"env": {
"GITHUB_CONTENTS_HOME": "/srv/github-contents"
}
}
}
}
Precedence matters in fleets: an ambient per-kind variable such as GITHUB_CONTENTS_DATA_DIR overrides an explicit --home for that kind. Use GITHUB_CONTENTS_HOME or the per-kind variables for durable fleet relocation; treat --home as the weaker per-invocation lever.
Relocation is one-way. Unsetting GITHUB_CONTENTS_HOME does not move files back to platform defaults, and doctor cannot find credentials left under a former root. Move the files manually before unsetting relocation variables.
Existing installs keep working because the platform-default rung matches the legacy layout. On the first auth write, stored secrets leave config.toml and are consolidated into credentials.toml under the data directory. Run github-contents-pp-cli doctor --fail-on warn to check path and credential-location warnings in automation.
Commands
blobs
Raw git blobs — fetch file content by SHA (works for files up to 100 MB)
github-contents-pp-cli blobs <owner> <repo> <file_sha> - Get a blob (base64-encoded content) by its git SHA
contents
List directories and read files via the repository contents API
github-contents-pp-cli contents <owner> <repo> <path> - Get a directory listing (JSON array) or file metadata+content (JSON object, base64, files up to 1 MB). Use trees <owner> <repo> <tree_sha> --recursive for large/deep listings and blobs <owner> <repo> <file_sha> or download_url for files over 1 MB.
rate-limit
API quota status — check headroom before and during bulk downloads
github-contents-pp-cli rate-limit - Show remaining API quota (5000/h with a token, 60/h without)
releases
Repository releases and their downloadable assets
github-contents-pp-cli releases latest - Get the latest published release
github-contents-pp-cli releases list - List releases with their assets
github-contents-pp-cli releases download <owner> <repo> - Download release assets (latest, or --tag) matching --pattern into --out; --list-only previews matches without downloading
repos
Repository metadata (default branch, visibility, size)
github-contents-pp-cli repos branches - List branches of a repository
github-contents-pp-cli repos commits - List commits, optionally filtered to a path (newest first)
github-contents-pp-cli repos get - Get repository metadata including the default branch
tarball
Full-repository snapshot as a .tar.gz
github-contents-pp-cli tarball <owner/repo[#ref]> - Download the whole repo at a ref as a tarball via GitHub's archive endpoint (use fetch for a subdirectory)
trees
Git trees — one-request recursive listings of an entire repo or subtree
github-contents-pp-cli trees <owner> <repo> <tree_sha> - Get a git tree. With --recursive, returns every file under it in one request (check the truncated flag on huge repos)
Self-learning loop
This CLI caches per-question discovery so repeat queries skip the walk and structurally similar queries get answered via entity substitution. The loop also self-captures: every invocation is journaled locally, and failed-flag corrections plus fresh teaches surface as candidates on the next recall for confirm/reject judgment. Agents call recall before discovery and fire teach & after answering. See the ## Automatic learning section in SKILL.md for the full protocol.
github-contents-pp-cli recall <query> - Look up cached resources for a query before running discovery
github-contents-pp-cli teach - Record a query -> resource mapping (silent on success, safe to background with &)
github-contents-pp-cli learnings list - Inspect taught rows
github-contents-pp-cli learnings forget <query> - Undo a teach
github-contents-pp-cli learnings candidates - List auto-captured candidates awaiting confirm/reject
github-contents-pp-cli learnings stats - Local loop metrics: recall hit rate, teach-to-reuse, playbook resolution, candidate counts
github-contents-pp-cli teach-pattern - Install a query/resource template up front
github-contents-pp-cli teach-lookup - Add an entity mapping (e.g. country code, team alias) for pattern substitution
Pass --no-learn or set GITHUB_CONTENTS_NO_LEARN=true to disable the loop for deterministic flows.
The local store's schema version stamp is one-way: once this version of github-contents-pp-cli opens the database, older binaries refuse it with a version error — upgrade the binary rather than downgrading.
Output Formats
# Human-readable table (default in terminal, JSON when piped)
github-contents-pp-cli blobs mock-value mock-value mock-value
# JSON for scripting and agents
github-contents-pp-cli blobs mock-value mock-value mock-value --json
# Filter to specific fields
github-contents-pp-cli blobs mock-value mock-value mock-value --json --select id,name,status
# Dry run — show the request without sending
github-contents-pp-cli blobs mock-value mock-value mock-value --dry-run
# Agent mode — JSON + compact + no prompts in one flag
github-contents-pp-cli blobs mock-value mock-value mock-value --agent
Agent Usage
This CLI is designed for AI agent consumption:
- Non-interactive - never prompts, every input is a flag
- Pipeable -
--json output to stdout, errors to stderr
- Filterable -
--select id,name returns only fields you need
- Previewable -
--dry-run shows the request without sending
- Read-only by default - this CLI does not create, update, delete, publish, send, or mutate remote resources
- Offline-friendly - sync/search commands can use the local SQLite store when available
- Agent-safe by default - no colors or formatting unless
--human-friendly is set
Exit codes: 0 success, 2 usage error, 3 not found, 4 auth error, 5 API error, 7 rate limited, 10 config error.
Health Check
github-contents-pp-cli doctor
Verifies configuration, credentials, and connectivity to the API.
Configuration
Run github-contents-pp-cli doctor to see the resolved config, data, state, and cache directories. The platform-default config path is ~/.config/github-contents-pp-cli/config.toml; --home, GITHUB_CONTENTS_HOME, and per-kind env vars can relocate it.
Static request headers can be configured under headers; per-command header overrides take precedence.
Environment variables:
| Name | Kind | Required | Description |
|---|
GITHUB_TOKEN | per_call | No (raises rate limit from 60 to 5000 req/h) | Set to your API credential. Public repos work unauthenticated. |
GH_TOKEN | per_call | No (raises rate limit from 60 to 5000 req/h) | Set to your API credential. Public repos work unauthenticated. |
agentcookie (optional)
If you use agentcookie to sync secrets across machines, this CLI auto-adopts agentcookie-managed credentials with no extra setup. When the daemon writes to this CLI's config, github-contents-pp-cli doctor reports agentcookie: detected and auth status labels the source as agentcookie. Skip this section if you don't use agentcookie - the CLI works the same as any other.
Troubleshooting
Authentication errors (exit code 4)
- Run
github-contents-pp-cli doctor to check credentials
- Verify the environment variable is set:
echo $GITHUB_TOKEN
Not found errors (exit code 3)
- Check the resource ID is correct
- Run the
list command to see available items
API-specific
- 404 on a repo you know exists — Private repos return 404 (not 403) without auth — export GITHUB_TOKEN= and retry
- 403 or rate-limit errors during listings — Run github-contents-pp-cli rate-limit show; unauthenticated is 60 req/h — set GITHUB_TOKEN for 5000 req/h (file downloads never count against the limit)
- plan or fetch reports the tree was truncated — The repo exceeds 100k entries or 7 MB of tree data — fetch a deeper subpath directly, e.g. fetch owner/repo/sub/dir
- A downloaded file is a few lines of text starting with 'version https://git-lfs...' — That file is stored in Git LFS; plan flags these as lfs_pointers — download it from the repo's web UI or with git lfs
- Paths with spaces return 404 — Quote the whole path argument; the CLI URL-escapes each segment automatically
Sources & Inspiration
This CLI was built by studying these projects and resources:
Generated by CLI Printing Press