Skip to main content

🔑 apwcli

Apple Passwords (iCloud Keychain) from the terminal. Read passwords and one-time codes, save logins, script it all.

CI License: MIT Python 3.12+ macOS

Website · Commands · Python library · Examples · How it works


  • Passwords & one-time codes — read, save, and update Apple Passwords entries
  • ✨ Agent-ready — bundled Claude skill and MCP server (apwcli mcp install)
  • Safe by default — passwords are masked on screen; -c copies to the clipboard instead
  • Scriptable — JSON/TSV output everywhere; Python API via apwlib
  • Zero setup — everything starts and pairs automatically on first use

Install

brew install michel-tricot/tap/apwcli   # or: uv tool install apwcli, pipx install apwcli

Or from a clone: uv sync, then uv run apwcli --help.

Requires macOS with a supported browser installed (Chrome, Brave, Edge, or Chromium); the iCloud Passwords extension itself is downloaded automatically from the Chrome Web Store.

Quick start

apwcli pw get github.com                 # saved entries (passwords masked)
apwcli pw get github.com me@example.com  # narrow to one account
apwcli otp get github.com                # current one-time code

The first command sets everything up. If pairing is needed, macOS shows a 6-digit PIN and apwcli prompts for it — that's the whole ceremony. Anything misbehaving? See Troubleshooting.

Security

This is a tool for your passwords, so here's exactly what it does with them:

  • Nothing leaves your Mac. apwcli talks only to Apple's local iCloud Passwords helper, through the official extension running in a browser on your machine. There are no servers, telemetry, or network calls of our own.
  • Apple's crypto does the crypto. Pairing (SRP) and per-command encryption (AES-GCM) run inside the real extension; apwcli is transport around it and never implements or handles key material itself.
  • Secrets stay off your screen and out of scrollback. Tables mask passwords by default (--show to reveal); text/json output is unmasked for piping. -c copies to the clipboard instead of printing, and the clipboard is auto-cleared after 20s (--clear-after).
  • Agents never see plaintext passwords by default. The MCP server exposes one-time codes, saving, and pairing — but not password reads unless you explicitly run it with --allow-passwords (MCP results travel to the model provider).
  • Nothing sensitive is logged. The log records lifecycle and errors only; command bodies are encrypted inside the browser and never written in plaintext.

Full details — the launch constraint, the pairing handshake, the threat model — are in the design notes. Found a vulnerability? See SECURITY.md.

Commands

Passwords

apwcli pw get github.com                      # entries for a site, passwords masked
apwcli pw get github.com me@example.com       # narrow to one account
apwcli pw get github.com me@example.com -c    # copy to clipboard, print nothing
apwcli pw get github.com me@example.com --show   # reveal in the table
apwcli pw save github.com me@example.com      # create/update (prompts)
printf '%s' "$PW" | apwcli pw save github.com me@example.com   # piped: no prompt
apwcli pw generate github.com me@example.com  # make a strong password and save it
apwcli pw generate github.com me@example.com -c   # …and copy it, don't print

Sites match by registrable domain: github.com, https://gist.github.com/x, and www.github.com all find the same accounts. Clipboard copies (-c) are wiped after 20 seconds; tune it with --clear-after (0 keeps them).

One-time codes

apwcli otp get github.com        # the current code
apwcli otp get github.com -c     # straight to the clipboard
apwcli otp list github.com       # accounts that have codes

Scripting

Data commands take --format / -o: table (default), json, or text (TSV for piping). Pipes always carry the real values — masking is only for tables on screen.

apwcli pw get github.com me@example.com -o text | cut -f3
apwcli otp get github.com -o json | jq -r '.results[0].code'

Errors exit with the protocol status code (9 = not paired, or nothing to talk to — see Troubleshooting) and print error: … to stderr, or a JSON object with -o json.

Agents

apwcli ships with integrations for AI agents:

apwcli skills install          # install the Claude skill into ~/.claude/skills
apwcli mcp install             # wire the MCP server into Claude, Cursor, VS Code, …

The MCP server exposes one-time codes, saving, and pairing — never plaintext passwords unless you start it with apwcli mcp run --allow-passwords (MCP tool results travel to the model provider; see the design notes).

Library

apwlib is the Python API behind the CLI:

from apwlib import ApplePasswords

pw = ApplePasswords(pin_provider=lambda: input("PIN: "))
for entry in pw.get_password("github.com", "me@example.com"):
    login(entry.username, entry.password)  # typed entries; nothing printed

Full guide and API reference on the website; runnable scripts in examples/.

Troubleshooting

You never launch or supervise anything: under the hood a background daemon starts on first use, and an unpaired command pops the macOS PIN dialog and prompts for the code (a small on-screen PIN window when there's no terminal). A pairing lasts as long as the daemon runs, so the PIN stays rare.

If something misbehaves, start with doctor — it checks the whole chain and suggests the fix:

apwcli doctor           # diagnose the setup (browser, extension, daemon, pairing)
apwcli daemon status    # daemon / extension / pairing state (--json for scripts)
apwcli daemon pair      # (re)pair; --pin 123456 to skip the prompt
apwcli daemon restart   # replace a wedged daemon with a fresh one
apwcli daemon logs      # tail the log (-f to follow, --clear to wipe)
apwcli daemon stop      # stop the daemon and its browser

Contributing

Contributions are welcome. The repository is a uv workspace with two packages: apwcli (this project, src/apwcli) and apwlib. Set up a checkout:

git clone https://github.com/michel-tricot/apwcli
cd apwcli
uv sync

Before committing, run the full validation suite — format, lint, typecheck, tests — and keep it green; CI runs the same thing:

scripts/check.sh

Work on the documentation site (MkDocs Material):

uv sync --group docs
uv run mkdocs serve      # live preview at http://127.0.0.1:8000

Contributor and agent guidelines live in AGENTS.md; design notes in docs/design/apwlib.md.

License

MIT © Michel Tricot · Not affiliated with Apple. Apple Passwords and iCloud Keychain are trademarks of Apple Inc.

Release files for apwcli 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for apwcli 0.1.2
File Size Uploaded
apwcli-0.1.2.tar.gz 16.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for apwcli 0.1.2
File Interpreter ABI Platform
apwcli-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 37.4 kB

Release files / apwcli-0.1.2.tar.gz

Download URL apwcli-0.1.2.tar.gz
Size 16.4 kB
Tags Source
SHA-256 checksum
How to use checksums
ed5283bf8b8498b44b679c0c080294d92b74afd7af89e0ff5b52ee4c00b522e2
BLAKE2b-256 checksum
How to use checksums
d494d455409a79cfd8c66779dec1cd70eee8c6ddd93316f8a34e80459f7e1bc7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / apwcli-0.1.2-py3-none-any.whl

Download URL apwcli-0.1.2-py3-none-any.whl
Size 21.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
88cecc235bb387672b79ca9706fc6e1f0a567703ebb91cbf42e3284306db8e46
BLAKE2b-256 checksum
How to use checksums
94f83e7ccc6771d39ba585bcae189c2363ee13ac8463cd8f83cb373b102b5c51
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page