Skip to main content

Command-line interfaces for macOS native apps (Mail, Reminders, Calendar, Notes, Contacts)

Project description

Apple CLIs

A collection of Python CLIs for controlling Apple applications through AppleScript (osascript). No dependency on third-party Python packages, just the standard library. Each CLI is self-contained and can be installed separately, but they share a common design and codebase for AppleScript interaction.

mail-app is a Python CLI that controls Apple Mail that can view and send messages.

reminders-app is a companion Python CLI for Apple Reminders with list/reminder management and query-based bulk actions.

calendar-app is a Python CLI for Apple Calendar to manage calendars and events.

notes-app is a Python CLI for Apple Notes to manage notes and folders.

contacts-app is a Python CLI for macOS Contacts to manage contacts and groups.

Requirements

  • macOS
  • Python 3.9+

Installation

To install the latest release from PyPI:

python3 -m pip install apple-cli

Editable/Development Install

To install in editable mode for development:

git clone https://github.com/evilmarty/apple-cli.git
cd apple-cli
python3 -m pip install -e .

After installation, the following commands will be available in your PATH:

  • mail-app
  • reminders-app
  • calendar-app
  • notes-app
  • contacts-app

mail-app command overview

Messages

mail-app messages list [--account ACCOUNT] [--mailbox MAILBOX] [--limit N] [--order desc|asc] [--json]
mail-app messages view (--id "<id>" | --message-id "<message-id>") [--account ACCOUNT] [--mailbox MAILBOX] [--body-only] [--json]
mail-app messages show (--id "<id>" | --message-id "<message-id>") [--account ACCOUNT] [--mailbox MAILBOX]
mail-app messages send --to "a@example.com,b@example.com" --subject "Hello" --body "Hi there" [--cc ...] [--bcc ...] [--account ACCOUNT]
mail-app messages move (--id "<id>" | --message-id "<message-id>") --destination-mailbox DEST [--account ACCOUNT] [--source-mailbox MAILBOX]
mail-app messages archive (--id "<id>" | --message-id "<message-id>") [--account ACCOUNT] [--mailbox MAILBOX]
mail-app messages trash (--id "<id>" | --message-id "<message-id>") [--account ACCOUNT] [--mailbox MAILBOX]
mail-app messages spam (--id "<id>" | --message-id "<message-id>") [--account ACCOUNT] [--mailbox MAILBOX]

Mailboxes

mail-app mailboxes list [--account ACCOUNT] [--json]
mail-app mailboxes create --account ACCOUNT --name NAME [--parent-mailbox MAILBOX]
mail-app mailboxes rename --account ACCOUNT --mailbox MAILBOX --new-name NEW_NAME
mail-app mailboxes delete --account ACCOUNT --mailbox MAILBOX

reminders-app command overview

Reminders

reminders-app reminders list [--list LIST] [--limit N] [--order desc|asc] [--completed|--all] [--json]
reminders-app reminders view --id ID [--body-only] [--json]
reminders-app reminders show --id ID
reminders-app reminders create --title TITLE [--notes TEXT] [--list LIST] [--due-date DATE] [--priority N]
reminders-app reminders update --id ID [--title TITLE] [--notes TEXT] [--due-date DATE] [--priority N] [--list LIST]
reminders-app reminders complete [--id ID | selectors | --all]
reminders-app reminders uncomplete [--id ID | selectors | --all]
reminders-app reminders delete [--id ID | selectors | --all]
reminders-app reminders move --destination-list LIST [--id ID | selectors | --all]

Lists

reminders-app lists list [--json]
reminders-app lists create --name NAME
reminders-app lists rename --list NAME --new-name NEW_NAME
reminders-app lists delete --list NAME

Note on Performance

Due to inefficiencies in how the Apple Reminders application handles bulk queries and property retrieval through AppleScript, some commands (especially list when querying many items) may experience delays or timeouts. If you encounter timeouts, try narrowing the scope of your command by specifying a --list.

calendar-app command overview

Events

calendar-app events list [--calendar CALENDAR] [--start-after DATE] [--start-before DATE] [--limit N] [--order desc|asc] [--json]
calendar-app events view --id ID [--json]
calendar-app events show --id ID
calendar-app events create --summary SUMMARY --start-date DATE (--end-date DATE | --duration DURATION) [--location LOC] [--notes TEXT] [--all-day] [--url URL] [--calendar CAL] [--alarm MIN]
calendar-app events update --id ID [--summary SUMMARY] [--start-date DATE] [--end-date DATE | --duration DURATION] [--location LOC] [--notes TEXT] [--all-day|--no-all-day] [--url URL] [--calendar CAL]
calendar-app events delete --id ID
  • events list defaults to events starting from "now" if no date range is provided.
  • events list output includes a human-friendly duration column (e.g., 15m, 2h, 1d).
  • events create/update --duration accepts human-friendly strings like 30m, 3h, 2d.

Calendars

calendar-app calendars list [--json]
calendar-app calendars create --name NAME
calendar-app calendars rename --calendar NAME --new-name NEW_NAME
calendar-app calendars delete --calendar NAME

notes-app command overview

Notes

notes-app notes list [--folder FOLDER] [--limit N] [--order desc|asc] [--json]
notes-app notes view --id ID [--json]
notes-app notes show --id ID
notes-app notes create --name NAME --body TEXT [--folder FOLDER]
notes-app notes update --id ID [--name NAME] [--body TEXT] [--folder FOLDER]
notes-app notes delete --id ID

Folders

notes-app folders list [--json]
notes-app folders create --name NAME
notes-app folders delete --name NAME

contacts-app command overview

Contacts

contacts-app contacts list [--search TEXT] [--group GROUP] [--limit N] [--order desc|asc] [--json]
contacts-app contacts view --id ID [--json]
contacts-app contacts show --id ID
contacts-app contacts create --first-name NAME [--last-name NAME] [--organization ORG] [--job-title JOB] [--nickname NICK] [--note TEXT] [--email EMAIL] [--phone PHONE]
contacts-app contacts delete --id ID

Groups

contacts-app groups list [--json]
contacts-app groups create --name NAME
contacts-app groups delete --name NAME

Building from source

To build a wheel and source distribution:

  1. Clone the repository:

    git clone https://github.com/evilmarty/apple-cli.git
    cd apple-cli
    
  2. (Optional) Create and activate a virtual environment:

    python3 -m venv .venv
    source .venv/bin/activate
    
  3. Run the build command:

    make build
    

The build artifacts will be available in the dist/ directory.

Testing

The project uses the standard library unittest framework.

To run all tests:

make test

To run tests for a specific application:

PYTHONPATH=src python3 -m unittest tests/test_calendar_app.py

Tests use mocking extensively to avoid actually executing AppleScripts that would interact with your native apps, making them safe to run in any environment.

Contributing

Contributions are welcome! If you'd like to contribute:

  1. Report Bugs or Request Features: Open an issue on GitHub.
  2. Submit Pull Requests:
    • Fork the repository.
    • Create a new branch for your feature or fix.
    • Ensure your code follows the existing style and is well-documented.
    • Important: Add tests for any new functionality or bug fixes.
    • Run the full test suite (make test) before submitting.
  3. Coding Standards:
    • Use type hints for all function signatures.
    • Keep the codebase compatible with Python 3.9+.
    • Maintain the zero-dependency goal (use only the Python standard library).

Project details


Download files

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

Source Distribution

apple_cli-1.0.1.tar.gz (27.5 kB view details)

Uploaded Source

Built Distribution

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

apple_cli-1.0.1-py3-none-any.whl (32.5 kB view details)

Uploaded Python 3

File details

Details for the file apple_cli-1.0.1.tar.gz.

File metadata

  • Download URL: apple_cli-1.0.1.tar.gz
  • Upload date:
  • Size: 27.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for apple_cli-1.0.1.tar.gz
Algorithm Hash digest
SHA256 190917f1e84b7dee7aeb7753223a6db36c0ca9d1b28ab316189fb05b436284ac
MD5 be1a68393e2e5d60a1a110eb7b759645
BLAKE2b-256 bda941dc2164d0a350adbeeb2a8982e8ba8286aa9ce22a352207ec5af4d52ef4

See more details on using hashes here.

File details

Details for the file apple_cli-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: apple_cli-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 32.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for apple_cli-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 6653dc5057417ffea2b640680304225529a7dbd7273d1c72f452852193b86ad3
MD5 28aeeac8bbac5c0140b1180b824de3cc
BLAKE2b-256 3f4cbf3b88d6fbdb186a2132b480ee1948a871fb81972a791dbffd2790c4a4c1

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