Skip to main content

Agent-first CLI for Microsoft 365 Outlook on the web endpoints

Project description

m365-owa-cli

m365-owa-cli is a personal, agent-first Python CLI for Microsoft 365 Outlook workflows through Outlook on the web / OWA internal service endpoints.

The current command surface is calendar-focused, but the package name leaves room for mail and tasks if the same OWA-authenticated endpoint strategy proves useful there. Microsoft Graph is intentionally out of scope.

Examples

m365-owa-cli capabilities
m365-owa-cli schema event
m365-owa-cli auth set-token --connection work
m365-owa-cli auth bookmarklet --connection work --raw
m365-owa-cli auth extract-token --connection work --devtools-url http://127.0.0.1:9222 --reload
m365-owa-cli auth list-connections
m365-owa-cli events list --connection work --day 2026-04-24
m365-owa-cli events delete --connection work --id AAMk... --confirm-event-id AAMk...

Commands emit JSON by default. Use --pretty where supported for local human-readable output.

Configuration

Tokens are stored as plaintext files under:

~/.config/m365-owa-cli/connections/<connection>.token

Tests and automation can override the config root with M365_OWA_CONFIG_DIR.

Connection names are the explicit account, company, tenant, or environment selector. Examples:

m365-owa-cli auth list-connections
m365-owa-cli events list --connection crayon --day 2026-04-24
m365-owa-cli events list --connection softwareone --day 2026-04-24
m365-owa-cli events list --connection swon --day 2026-04-24
m365-owa-cli events list --connection prod --day 2026-04-24

Browser Token Capture

Preferred method: watch a DevTools-enabled Edge or Chrome tab and store OWA auth material from browser traffic. Open Outlook on the web in that browser first. On macOS, use a reusable debug profile so Chrome first-run and search-engine-choice prompts do not come back every session:

open -na "Google Chrome" --args --remote-debugging-port=9222 --user-data-dir="$HOME/.config/m365-owa-cli/chrome-devtools-profile" --no-first-run --no-default-browser-check --disable-search-engine-choice-screen https://outlook.office.com/calendar/

Capture per connection:

m365-owa-cli auth extract-token --connection crayon --browser chrome --devtools-url http://127.0.0.1:9222 --reload
m365-owa-cli auth extract-token --connection softwareone --browser chrome --devtools-url http://127.0.0.1:9222 --reload
m365-owa-cli auth extract-token --connection swon --browser chrome --devtools-url http://127.0.0.1:9222 --reload

Each command stores separate local auth state:

~/.config/m365-owa-cli/connections/crayon.token
~/.config/m365-owa-cli/connections/softwareone.token
~/.config/m365-owa-cli/connections/swon.token
~/.config/m365-owa-cli/connections/crayon.credential.json

The command only accepts bearer headers from known Outlook hosts on /owa/service.svc and Microsoft identity token responses from login.microsoftonline.com; it stores secrets locally and emits metadata only. If the capture times out, interact with the open Calendar tab and retry without --reload.

Manual Token Capture Fallback

Use the bookmarklet helper only when DevTools capture is unavailable:

m365-owa-cli auth bookmarklet --connection crayon --raw

Create a browser bookmark with the generated value as the URL, open Outlook on the web, click the bookmarklet, then refresh or open Calendar. If OWA sends an Authorization: Bearer ... header to /owa/service.svc, the helper displays it for copying into auth set-token.

Opsec

  • Do not print, paste, commit, screenshot, or document bearer token values.
  • Do not copy ~/.config/m365-owa-cli/connections/*.token or *.credential.json into this repository.
  • Use --connection names like crayon, softwareone, swon, prod, dev, or another explicit company/environment name so agents never depend on hidden account state.
  • Keep remote debugging bound to the local machine, for example http://127.0.0.1:9222.
  • Prefer JSON command output and rely on built-in redaction for errors; do not add ad hoc debug logging around auth headers.

Releases

New versions are published to PyPI from GitHub Actions when a v* tag is pushed. The workflow uses PyPI trusted publishing against the pypi environment in this repository, so no long-lived PyPI API token is stored in GitHub.

Before the first release, configure a pending trusted publisher on PyPI:

  • PyPI project name: m365-owa-cli
  • Owner: okms
  • Repository: m365-owa-cli
  • Workflow: publish.yml
  • Environment: pypi

Release flow:

# bump version in pyproject.toml, commit
git tag vX.Y.Z
git push origin main --tags

The .github/workflows/publish.yml workflow runs tests, builds the source and wheel distributions, checks them with Twine, and publishes them to PyPI. Tag-less runs can also be triggered manually from the Actions tab.

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

m365_owa_cli-0.1.3.tar.gz (80.6 kB view details)

Uploaded Source

Built Distribution

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

m365_owa_cli-0.1.3-py3-none-any.whl (42.7 kB view details)

Uploaded Python 3

File details

Details for the file m365_owa_cli-0.1.3.tar.gz.

File metadata

  • Download URL: m365_owa_cli-0.1.3.tar.gz
  • Upload date:
  • Size: 80.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for m365_owa_cli-0.1.3.tar.gz
Algorithm Hash digest
SHA256 68af894cd8f1d92d0c217d33cdd128e6e31a6c9ed3f633ee928e370d3d42d150
MD5 b29842275168996b07a96ae045718356
BLAKE2b-256 e1720b0bec45802a4ad1c905c28c355d2502d85294d2e31d32811aeecd7e4d62

See more details on using hashes here.

Provenance

The following attestation bundles were made for m365_owa_cli-0.1.3.tar.gz:

Publisher: publish.yml on okms/m365-owa-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file m365_owa_cli-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: m365_owa_cli-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 42.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for m365_owa_cli-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 229772b72c79dd608485a55f6f2b2dd47781d695c412dacdf71b3f4752ffb25e
MD5 cdbb1d1b88f90c7e6b69d7d83af6f306
BLAKE2b-256 8125d54ea19f51e1f36ba4bbd34a162cdace77fcfb3b19f506ec443dd28bd057

See more details on using hashes here.

Provenance

The following attestation bundles were made for m365_owa_cli-0.1.3-py3-none-any.whl:

Publisher: publish.yml on okms/m365-owa-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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