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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

apwcli-0.1.2.tar.gz (16.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

apwcli-0.1.2-py3-none-any.whl (21.0 kB view details)

Uploaded Python 3

File details

Details for the file apwcli-0.1.2.tar.gz.

File metadata

  • Download URL: apwcli-0.1.2.tar.gz
  • Upload date:
  • Size: 16.4 kB
  • Tags: Source
  • Uploaded using 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}

File hashes

Hashes for apwcli-0.1.2.tar.gz
Algorithm Hash digest
SHA256 ed5283bf8b8498b44b679c0c080294d92b74afd7af89e0ff5b52ee4c00b522e2
MD5 9aba8781f2df0a5308d32f14384fc70a
BLAKE2b-256 d494d455409a79cfd8c66779dec1cd70eee8c6ddd93316f8a34e80459f7e1bc7

See more details on using hashes here.

File details

Details for the file apwcli-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: apwcli-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 21.0 kB
  • Tags: Python 3
  • Uploaded using 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}

File hashes

Hashes for apwcli-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 88cecc235bb387672b79ca9706fc6e1f0a567703ebb91cbf42e3284306db8e46
MD5 8147e3bc6e98cc699ca0a595720b0de0
BLAKE2b-256 94f83e7ccc6771d39ba585bcae189c2363ee13ac8463cd8f83cb373b102b5c51

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page