Skip to main content

blumkin

Personal Microsoft 365 / Graph skills CLI — named after Rose “Mrs. B” Blumkin, Berkshire’s legendary operator.

Blumkin turns Graph flows into small, invokable skills any coding agent (Cursor, GitHub Copilot, Claude, …) can run via shell — instead of re-implementing auth and Microsoft Graph calls.

It uses delegated Microsoft Graph access (acts as the signed-in user).

Status

M1 shipped (#10): packaging, auth under ~/.config/blumkin/, skills / doctor, calendar today, Cursor skill, hermetic CI + local live tests.

Tracking: #9 Cursor agent integration (M1 MVP).

Install (blumkin on PATH)

pipx install blumkin
pipx ensurepath          # first pipx install only; opens a new shell

Then invoke the binary directly — not uv run blumkin:

blumkin --version           # version, commit, and which binary answered
blumkin auth login          # once per machine / when cache is cold
blumkin auth status
blumkin skills list --json
blumkin calendar today --json

pipx puts blumkin in its bin dir (usually ~/.local/bin); pipx ensurepath makes sure that is on PATH.

Upgrade

blumkin upgrade

Wraps pipx upgrade blumkin and prints the version and commit you were on and the one you moved to — bare pipx upgrade cannot tell you whether PATH still resolves to a dev checkout.

From a clone (developing blumkin)

uv sync --group dev
uv tool install -e .        # editable; `blumkin` now points at the checkout

blumkin --version reports the checkout's commit, and blumkin upgrade will say it is running from a source checkout and leave the tree alone.

To use blumkin from agent sessions in other repos (Cursor personal skill, or Copilot CLI instructions), see docs/agent-integration.md. For cutting a release, see docs/RELEASING.md.

Discovering commands

Every group and leaf command has --help with a description and worked examples:

blumkin --help                     # top-level map, common workflows, exit codes
blumkin calendar --help            # a group's commands + typical flows
blumkin calendar create --help     # one command: args, notes, example invocations

blumkin skills list --json is the machine-readable catalog for agents.

Shell completion

blumkin completion <bash|zsh|fish> prints a completion script. Install it once:

# bash
blumkin completion bash > ~/.blumkin-complete.bash
echo 'source ~/.blumkin-complete.bash' >> ~/.bashrc

# zsh
blumkin completion zsh > ~/.blumkin-complete.zsh
echo 'source ~/.blumkin-complete.zsh' >> ~/.zshrc

# fish
blumkin completion fish > ~/.config/fish/completions/blumkin.fish

Open a new shell afterwards. The script calls back into blumkin for completions, so keep it on PATH.

Config (~/.config/blumkin/)

Create ~/.config/blumkin/config.toml (mode 0600). Prefer named profiles in one file (see blumkin profiles list --json and --profile):

default_profile = "work"

[profiles.work]
client_id = "<entra-public-client-id>"
tenant_id = "<your-entra-tenant>"
default_tz = "<IANA timezone, e.g. America/New_York>"
provider = "microsoft"
tags = ["@work", "work", "microsoft", "m365"]

[profiles.personal]
provider = "google"
default_tz = "<IANA timezone>"
google_oauth_client_file = "~/path/to/google-oauth-desktop-client.json"
tags = ["@personal", "personal", "google", "gmail"]

Legacy flat keys (no [profiles.*]) still load as one implicit profile named default, with token files in the config dir root.

Set tenant_id, default_tz, and provider in the profile table (there are no org-specific code defaults). provider defaults to microsoft when omitted.

Interactive browser auth is public-client only (client_id; plus tenant_id for Microsoft). Do not set a client secret for these flows.

Microsoft token cache files (under profiles/<name>/, or config dir root for legacy):

  • msal_token_cache.json
  • auth_record.json

Google Workspace (provider = "google")

Full walkthrough: docs/google-setup.md (Console project, APIs, consent screen / test users, Desktop client JSON, named profile, login, smoke, troubleshooting).

Short form — point the profile at your Google Cloud Desktop OAuth client JSON (the Console download). That file holds client_id / client_secret; do not put the secret in toml or environment variables. Download that JSON when you create the client — the secret is shown once and Google will not let you re-download it later (recovery means Reset secret / a new client; see docs/google-setup.md §A.4):

[profiles.personal]
provider = "google"
default_tz = "..."
google_oauth_client_file = "~/path/to/google-oauth-desktop-client.json"
tags = ["@personal", "personal", "google", "gmail"]

blumkin auth login records the signed-in address as email = "..." in that profile the first time (display only - it is never used to pick a profile, and never rewritten afterwards). blumkin profiles list shows it, so two profiles are tellable apart at a glance; blumkin doctor warns if the profile is later signed in as a different account.

Optional: set client_id in toml as well; when omitted it is read from the JSON. Keep the client JSON mode 0600 and outside the repo.

Supported Google verbs: auth, calendar today / view / freebusy / suggest / create / accept / cancel / update (update attaches a Meet link), mail inbox / list / get / folders / attachments (list + download), and mail writes draft / update-draft / delete-draft / send-draft / reply / forward, and people resolve (own contacts plus the Workspace directory; a consumer account just uses contacts), and chat find / last / send / edit / delete / attachments (a 1:1 is a Chat space; Drive-backed attachments are listed but not downloadable). Everything else fails closed with a clear error. mail folders lists Gmail labels that act as folders. Mail writes use the gmail.compose scope — re-run blumkin auth login once after upgrading, or those calls exit 4 (missing_scope).

Token file (written by blumkin auth login): profiles/<name>/google_token.json.

Select a profile with --profile / BLUMKIN_PROFILE (name or unique tag). Use BLUMKIN_CONFIG_DIR only to select a config directory. Never commit these files. Optional graph_timeout_seconds in toml also bounds Google HTTP / token-refresh calls (same knob as Microsoft Graph).

Tests

uv run pytest -m 'not live'          # CI-equivalent (mocks / offline)
BLUMKIN_LIVE=1 uv run pytest -m live # live Graph reads + silent refresh

Live tests need ~/.config/blumkin/ by default (override with BLUMKIN_CONFIG_DIR): config.toml, token cache, auth record, and a usable refresh token. Never commit those files.

Docs

License

MIT — see LICENSE.

Download files

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

Source Distribution

blumkin-0.2.0.tar.gz (332.0 kB view details)

Uploaded Source

Built Distribution

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

blumkin-0.2.0-py3-none-any.whl (139.0 kB view details)

Uploaded Python 3

File details

Details for the file blumkin-0.2.0.tar.gz.

File metadata

  • Download URL: blumkin-0.2.0.tar.gz
  • Upload date:
  • Size: 332.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for blumkin-0.2.0.tar.gz
Algorithm Hash digest
SHA256 6df3715f066f468018e145a98d7e35b20028e97d40a1d49a7ee98e97b20c587f
MD5 8a0893fdbfebaad7a998087014fa86e4
BLAKE2b-256 143dd10b32e219b3d2b0f1d93ea9e3d3ec3a1a042a787f501daf0e5e2473eb4f

See more details on using hashes here.

Provenance

The following attestation bundles were made for blumkin-0.2.0.tar.gz:

Publisher: release-please.yml on the-hcma/blumkin

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

File details

Details for the file blumkin-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: blumkin-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 139.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for blumkin-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 153a31923c5c3f681ae62c64d5b8e1dd5a477a384ed50c7ca0a110584a18e0a1
MD5 97b2b71cb590f01c9cbe547c0cc80bac
BLAKE2b-256 535b1bd49d40415d2318bb122feaa572aacccfa6d60845e255999552967c4ec1

See more details on using hashes here.

Provenance

The following attestation bundles were made for blumkin-0.2.0-py3-none-any.whl:

Publisher: release-please.yml on the-hcma/blumkin

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

Release history Release notifications | RSS feed

1.2.1

2 files

1.2.0

2 files

1.1.2

2 files

1.1.1

2 files

1.1.0

2 files

1.0.0

2 files

0.7.0

2 files

0.6.0

2 files

0.5.0

2 files

0.4.0

2 files

0.3.0

2 files

0.2.1

2 files

This release

0.2.0 This release

2 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