Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Printing Press CLI for Google Photos. Google Photos Library and Picker APIs for app-created media, albums, uploads, and user-selected media.
.claude/skills/mvanhorn-pp-google-photos/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 94% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 154% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 40% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 88% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 69% | 0% |
This skill drives the google-photos-pp-cli binary. You must verify the CLI is installed before invoking any command from this skill. If it is missing, install it first:
$HOME/.local/bin on macOS/Linux and %LOCALAPPDATA%\Programs\PrintingPress\bin on Windows:bash npx -y @mvanhorn/printing-press-library install google-photos --cli-only
google-photos-pp-cli --version$PATH for the agent/runtime that will invoke this skill.If the npx install fails (no Node, offline, etc.), fall back to a direct Go install (requires Go 1.26.6 or newer):
bashgo install github.com/mvanhorn/printing-press-library/library/media-and-entertainment/google-photos/cmd/google-photos-pp-cli@latest
If --version reports "command not found" after install, the runtime cannot see the binary directory on $PATH. Do not proceed with skill commands until verification succeeds.
albums — Manage app-created Google Photos albums.
google-photos-pp-cli albums add-enrichment — Add text, location, or map enrichment to an app-created album.google-photos-pp-cli albums batch-add-media-items — Add app-created media items to an app-created album.google-photos-pp-cli albums batch-remove-media-items — Remove app-created media items from an app-created album.google-photos-pp-cli albums create — Create an album in the user's Google Photos library.google-photos-pp-cli albums get — Get an app-created album by ID.google-photos-pp-cli albums list — List albums created by this app.google-photos-pp-cli albums patch — Update title or cover photo on an app-created album.media-items — Manage app-created Google Photos media items.
google-photos-pp-cli media-items batch-create — Create media items from upload tokens.google-photos-pp-cli media-items batch-get — Get multiple app-created media items by ID.google-photos-pp-cli media-items get — Get an app-created media item by ID.google-photos-pp-cli media-items list — List media items created by this app.google-photos-pp-cli media-items patch — Update the description on an app-created media item.google-photos-pp-cli media-items search — Search app-created media items by album or filters.picker — Create, poll, clean up, and read Google Photos Picker sessions.
google-photos-pp-cli picker create-session — Create a Picker session and return the picker URI.google-photos-pp-cli picker delete-session — Delete a Picker session after selected media bytes have been retrieved.google-photos-pp-cli picker get-session — Get Picker session status.google-photos-pp-cli picker list-media-items — List media items picked by the user during a Picker session.Hand-written commands
google-photos-pp-cli upload file <path> — Upload raw photo or video bytes and print the upload token for media-items batch-create.google-photos-pp-cli picker wait <session-id> — Poll a Picker session until selected media items are ready.google-photos-pp-cli schema --pretty — Emit machine-readable command, flag, auth, and safety-policy metadata.google-photos-pp-cli auth list — List stored OAuth accounts.google-photos-pp-cli auth use <account-email> — Set the default OAuth account.google-photos-pp-cli auth remove <account-email> — Remove a stored OAuth account.Google Photos Library API read and edit scopes are limited to app-created albums and media. Use Library API commands here for app-created content, uploads, and album/media management. Use Picker commands when a user needs to select media from their broader Google Photos library.
When you know what you want to do but not which command does it, ask the CLI directly:
bashgoogle-photos-pp-cli which "<capability in your own words>"
which resolves a natural-language capability query to the best matching command from this CLI's curated feature index. Exit code 0 means at least one match; exit code 2 means no confident match — fall back to --help or use a narrower query.
Authenticate via the browser:
bashgoogle-photos-pp-cli auth login --client-id "$GOOGLE_PHOTOS_CLIENT_ID"
Tokens are stored locally and refreshed automatically.
For multiple Google accounts, store tokens under account emails and select the account explicitly:
bashgoogle-photos-pp-cli auth login you@example.com --client-id "$GOOGLE_PHOTOS_CLIENT_ID" google-photos-pp-cli auth list --json google-photos-pp-cli auth use you@example.com google-photos-pp-cli --account you@example.com albums list --agent
Account selection order: --account, GOOGLE_PHOTOS_ACCOUNT, auth use default, then legacy single-token config.
Run google-photos-pp-cli doctor to verify setup.
Add --agent to any command. Expands to: --json --compact --no-input --no-color --yes.
--select keeps a subset of fields. Dotted paths descend into nested structures; arrays traverse element-wise. Critical for keeping context small on verbose APIs:bash google-photos-pp-cli albums list --agent --select id,name,status
--dry-run shows the request without sending--enable-commands / --disable-commands with dotted command paths:bash google-photos-pp-cli --enable-commands albums.list albums list --agent google-photos-pp-cli --disable-commands picker.delete-session picker delete-session SESSION_ID --agent
schema --pretty or agent-context --pretty for the full JSON command contract.Build stronger local guardrails when exposing this CLI or MCP server to autonomous agents:
bashmake build-readonly make build-agent-safe make build-mcp-readonly make build-mcp-agent-safe
safety_readonly permits read/list/search/export/schema-style commands and blocks Google Photos mutations. safety_agent_safe permits reads and local archive/search workflows while blocking auth writes, uploads, creates, patches, deletes, and album/media mutations.
Commands that read from the local store or the API wrap output in a provenance envelope:
json{ "meta": {"source": "live" | "local", "synced_at": "...", "reason": "..."}, "results": <data> }
Parse .results for data and .meta.source to know whether it's live or local. A human-readable N results (live) summary is printed to stderr only when stdout is a terminal — piped/agent consumers get pure JSON on stdout.
When you (or the agent) notice something off about this CLI, record it:
google-photos-pp-cli feedback "the --since flag is inclusive but docs say exclusive"
google-photos-pp-cli feedback --stdin < notes.txt
google-photos-pp-cli feedback list --json --limit 10Entries are stored locally at ~/.google-photos-pp-cli/feedback.jsonl. They are never POSTed unless GOOGLE_PHOTOS_FEEDBACK_ENDPOINT is set AND either --send is passed or GOOGLE_PHOTOS_FEEDBACK_AUTO_SEND=true. Default behavior is local-only.
Write what surprised you, not a bug report. Short, specific, one line: that is the part that compounds.
Every command accepts --deliver <sink>. The output goes to the named sink in addition to (or instead of) stdout, so agents can route command results without hand-piping. Three sinks are supported:
| Sink | Effect | |------|--------| | stdout | Default; write to stdout only | | file:<path> | Atomically write output to <path> (tmp + rename) | | webhook:<url> | POST the output body to the URL (application/json or application/x-ndjson when --compact) |
Unknown schemes are refused with a structured error naming the supported set. Webhook failures return non-zero and log the URL + HTTP status on stderr.
A profile is a saved set of flag values, reused across invocations. Use it when a scheduled agent calls the same command every run with the same configuration - HeyGen's "Beacon" pattern.
google-photos-pp-cli profile save briefing --json
google-photos-pp-cli --profile briefing albums list
google-photos-pp-cli profile list --json
google-photos-pp-cli profile show briefing
google-photos-pp-cli profile delete briefing --yesExplicit flags always win over profile values; profile values win over defaults. agent-context lists all available profiles under available_profiles so introspecting agents discover them at runtime.
| Code | Meaning | |------|---------| | 0 | Success | | 2 | Usage error (wrong arguments) | | 3 | Resource not found | | 4 | Authentication required | | 5 | API error (upstream issue) | | 7 | Rate limited (wait and retry) | | 10 | Config error |
Parse $ARGUMENTS:
help, or --help → show google-photos-pp-cli --help outputinstall → ends with mcp → MCP installation; otherwise → see Prerequisites above--agent)bash go install github.com/mvanhorn/printing-press-library/library/media-and-entertainment/google-photos/cmd/google-photos-pp-mcp@latest
bash claude mcp add google-photos-pp-mcp -- google-photos-pp-mcp
claude mcp listwhich google-photos-pp-cliIf not found, offer to install (see Prerequisites at the top of this skill).
--agent flag:bash google-photos-pp-cli <command> [subcommand] [args] --agent
google-photos-pp-cli <command> --help.| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-11 | pass→pass | 6,089 | 3,598 | -41% | 1 | 1 | 0% | 1,008 | 3,163 | +214% | 0 | 0 | — |
case-01 | fail→fail | 8,383 | 36,244 | +332% | 1 | 1 | 0% | 423 | 2,996 | +608% | 0 | 0 | — |
case-02 | fail→fail | 8,367 | 6,265 | -25% | 1 | 1 | 0% | 1,557 | 2,959 | +90% | 0 | 0 | — |
case-03 | fail→fail | 17,074 | 6,181 | -64% | 1 | 1 | 0% | 2,739 | 2,999 | +9% | 0 | 0 | — |
case-04 | fail→pass | 10,175 | 4,977 | -51% | 1 | 1 | 0% | 1,753 | 3,398 | +94% | 0 | 0 | — |
case-05 | pass→pass | 8,515 | 8,476 | -0% | 1 | 1 | 0% | 1,477 | 3,349 | +127% | 0 | 0 | — |
case-06 | pass→pass | 9,069 | 6,773 | -25% | 1 | 1 | 0% | 1,292 | 3,645 | +182% | 0 | 0 | — |
case-07 | fail→pass | 6,397 | 2,785 | -56% | 1 | 1 | 0% | 1,217 | 3,096 | +154% | 0 | 0 | — |
case-08 | fail→pass | 17,554 | 2,996 | -83% | 1 | 1 | 0% | 2,239 | 3,139 | +40% | 0 | 0 | — |
case-09 | fail→pass | 10,497 | 3,446 | -67% | 1 | 1 | 0% | 1,697 | 3,182 | +88% | 0 | 0 | — |
case-10 | fail→fail | 13,600 | 2,296 | -83% | 1 | 1 | 0% | 1,870 | 3,060 | +64% | 0 | 0 | — |
case-12 | fail→pass | 11,822 | 3,763 | -68% | 1 | 1 | 0% | 1,983 | 3,358 | +69% | 0 | 0 | — |
case-13 | fail→pass | 17,291 | 3,778 | -78% | 1 | 1 | 0% | 2,773 | 3,182 | +15% | 0 | 0 | — |
case-14 | fail→pass | 10,510 | 2,789 | -73% | 1 | 1 | 0% | 1,926 | 3,072 | +60% | 0 | 0 | — |
case-15 | fail→pass | 6,753 | 1,959 | -71% | 1 | 1 | 0% | 1,107 | 3,062 | +177% | 0 | 0 | — |
case-16 | pass→pass | 10,362 | 2,721 | -74% | 1 | 1 | 0% | 1,716 | 3,067 | +79% | 0 | 0 | — |
case-17 | fail→pass | 18,827 | 1,974 | -90% | 1 | 1 | 0% | 3,141 | 3,027 | -4% | 0 | 0 | — |
case-18 | fail→pass | 13,280 | 2,652 | -80% | 1 | 1 | 0% | 2,289 | 3,128 | +37% | 0 | 0 | — |
case-19 | pass→pass | 9,957 | 2,193 | -78% | 1 | 1 | 0% | 1,398 | 3,048 | +118% | 0 | 0 | — |
case-20 | fail→fail | 7,788 | 2,893 | -63% | 1 | 1 | 0% | 1,187 | 3,232 | +172% | 0 | 0 | — |
case-21 | fail→pass | 11,917 | 3,011 | -75% | 1 | 1 | 0% | 1,920 | 3,088 | +61% | 0 | 0 | — |
case-22 | fail→fail | 9,218 | 5,806 | -37% | 1 | 1 | 0% | 1,745 | 3,761 | +116% | 0 | 0 | — |
case-23 | fail→pass | 11,766 | 4,236 | -64% | 1 | 1 | 0% | 1,610 | 3,436 | +113% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted, and 20 counted toward the lift figure. The other 3 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +52 percentage points is the difference between those two pass rates over the 20 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.