Skip to main content

Sync email threads from IMAP to Markdown, draft replies, manage collaborators

Project description

Corky logo

Corky

Alpha software. Expect breaking changes between minor versions. See VERSIONS.md for migration notes.

Full documentation: https://btakita.github.io/corky

Sync email threads from IMAP to Markdown. Draft replies with AI assistance. Share scoped threads with collaborators via git.

Corky syncs threads from any IMAP provider (Gmail, Protonmail Bridge, self-hosted) into mail/conversations/ — one file per thread, regardless of source. A thread that arrives via both Gmail and Protonmail merges into one file. Labels, accounts, and contacts are metadata, not directory structure.

Install

pip install corky        # or: pipx install corky

Or via shell installer:

curl -sSf https://raw.githubusercontent.com/btakita/corky/main/install.sh | sh

Or from source: cargo install --path .

Quick start

corky init --user you@gmail.com
# Edit mail/.corky.toml with credentials
corky sync

See the getting started guide for full setup instructions.

When corky needs browser OAuth, it binds the local callback listener before opening the browser. Google-backed flows default to 127.0.0.1:8484, honor CORKY_OAUTH_CALLBACK_PORT for a one-session override, and only fall back to another loopback port when you explicitly set CORKY_OAUTH_ALLOW_EPHEMERAL_PORT=1 for a client that supports wildcard loopback redirects. Browser-auth prompts also raise a best-effort desktop notification via notify-desktop on Linux, osascript on macOS, and PowerShell NotifyIcon on Windows. If [gsc] service-account auth is configured, that Search Console token is only cached in-process and is scoped by the resolved account/config fingerprint, so changing mailbox roots or configs does not reuse the wrong SA token.

Key features

  • Flat conversations — one Markdown file per thread, all sources merged
  • Sandboxed sharing — label-based routing gives collaborators only the threads you choose
  • AI-native — files, CLI, and git work the same for humans and agents
  • Multi-account — Gmail, Protonmail Bridge, generic IMAP, all in one directory
  • Social posting — draft and publish to LinkedIn and YouTube via OAuth
  • Google Workspace — Gmail send with attachments, Docs/Sheets read-write, Chat, Tasks
  • Scheduling — schedule email and social drafts for timed publishing
  • Topics — organize conversations with shared topic context across mailboxes
  • Transcription — whisper-rs audio transcription with speaker diarization via pyannote-rs
  • Watch daemon — poll IMAP and Gmail API accounts, sync shared mailboxes, notify on new messages, and run scheduled publishing with corky watch. Ctrl+C cleanly interrupts both sync paths

Usage

corky sync                      # Incremental IMAP sync
corky sync refetch THREAD_ID    # Re-fetch a single Gmail thread
corky unanswered                # Threads awaiting a reply
corky draft push FILE           # Save as email draft (thread_id in YAML for threading)
corky draft send FILE           # Send via Gmail API (supports --attachment FILE)
corky mailbox add NAME --label LABEL  # Share threads
corky contact push [google]     # Push contacts to Google Contacts (People API)
corky contact sync              # Sync contact CLAUDE.md between root and mailboxes
corky contact delete RES_NAME   # Delete contact from Google Contacts
corky filter push               # Push Gmail filters from .corky.toml
corky filter push --dry-run     # Preview filter changes
corky filter pull               # Show current Gmail filters
corky auth --email you@gmail.com --scope sync  # Pre-authenticate Gmail API sync
corky auth --account my-gmail --email you@gmail.com --scope send  # Pre-authenticate Gmail compose
corky filter auth               # Authenticate for Gmail filter API
corky linkedin draft              # Create LinkedIn draft
corky linkedin publish FILE      # Publish to LinkedIn
corky linkedin comment FILE TEXT # Comment on a published post
corky youtube comment FILE TEXT      # Comment on a published video
corky youtube playlist add PL VID   # Add video to playlist
corky youtube playlist create TITLE # Create a playlist
corky youtube playlist list         # List your playlists
corky doc upload FILE --account a@gmail.com  # Google Drive upload (account-targeted OAuth)
corky doc sheet SHEET_URL                   # Read Google Sheet as markdown table
corky doc sheet-write SHEET_URL RANGE CSV  # Write CSV to Google Sheet range
corky sheets pull SHEET_URL TAB CSV        # Sync a Google Sheet tab to local CSV
corky sheets push SHEET_URL TAB CSV        # Clear/create tab, then sync local CSV
corky chat send SPACE_ID "message"          # Send Google Chat message
corky tasks list                            # List pending Google Tasks
corky tasks add "Task title" --due 2026-04-20  # Add a task
corky tasks done TASK_ID                    # Mark task complete
corky schedule run              # Publish due scheduled items
corky topics list               # Show configured topics
corky watch                     # Poll, sync, and publish scheduled
corky transcribe FILE            # Transcribe audio to text
corky transcribe FILE --diarize  # With speaker diarization
corky --help                    # All commands

Transcription & speaker diarization

Transcribe audio files with optional speaker diarization. Supports WAV, MP3, FLAC, OGG, M4A, AMR, and more.

# Basic transcription
corky transcribe call.amr -o transcript.md

# With speaker diarization (interactive labeling)
corky transcribe call.amr --diarize -o transcript.md

# With pre-assigned speaker names
corky transcribe call.amr --diarize --speakers "Alice,Bob" -o transcript.md

Diarization uses pyannote-rs (ONNX Runtime) to detect and label speakers. When run without --speakers, corky shows text excerpts per speaker and prompts you to assign names interactively. ONNX models auto-download on first use — no gated HuggingFace access required.

Feature flags: Transcription (CPU) is enabled by default. GPU acceleration is auto-detected — make install and install.sh detect NVIDIA CUDA (Linux) or Apple Metal (macOS) and build with the appropriate GPU backend, falling back to CPU-only if the GPU build fails. For manual control: cargo install --path . --features transcribe-cuda (Linux) or --features transcribe-metal (macOS). Diarization is enabled by default. Video formats (mov, mkv, webm, etc.) are transcribed via ffmpeg; audio formats use symphonia with ffmpeg fallback.

This feature was designed collaboratively using agent-doc interactive document sessions.

Telegram import

Import Telegram Desktop JSON exports into corky conversations:

corky sync telegram-import ~/Downloads/telegram-export/result.json
corky sync telegram-import ~/Downloads/telegram-export/           # directory of exports
corky sync telegram-import result.json --label personal --account tg-personal

Export from Telegram Desktop: Settings > Advanced > Export Telegram data > JSON format.

Slack import

Import Slack workspace export ZIPs:

corky slack import ~/Downloads/my-workspace-export.zip
corky slack import export.zip --label work --account slack-work

Export from Slack: Workspace admin > Settings > Import/Export Data > Export.

See the command reference for details.

Gmail API sync

Sync Gmail accounts without IMAP or app passwords using the Gmail REST API with OAuth2.

1. Configure .corky.toml:

Corky ships with built-in GCP OAuth credentials, so no Google Cloud Console setup is needed for most users. Just configure your account:

# [gmail] section is optional — built-in credentials are used by default
# To use your own OAuth app, uncomment and configure:
# [gmail]
# client_id_cmd = "pass corky/gmail/client_id"       # or inline: client_id = "..."
# client_secret_cmd = "pass corky/gmail/client_secret" # or inline: client_secret = "..."

[accounts.my-gmail]
provider = "gmail-api"
user = "you@gmail.com"
labels = ["INBOX"]
sync_days = 30           # optional, default 3650

2. First sync:

corky sync account my-gmail

This opens your browser for OAuth authorization. Authorize with the correct Google account. The token is cached at ~/.config/corky/tokens.json for future syncs; corky now writes that shared token store with a lock + atomic replace so concurrent auth flows do not clobber unrelated entries.

You can also authenticate before running sync: corky auth --email you@gmail.com --scope sync stores the Gmail read-only token under the same gmail:<email> key used by gmail-api sync. For Gmail API draft/send, use corky auth --account my-gmail --email you@gmail.com --scope send so the compose token is stored under gmail:<account>:send.

corky draft send uses a separate gmail.compose token under gmail:<account>:send, so attachment sends and Gmail API draft sends do not overwrite the read-only sync token. If Gmail returns 401 on the send path, corky clears that cached send token and asks you to re-run corky draft send, which triggers compose-scope re-auth.

The IMAP/Gmail sync cursor file (mail/.sync-state.json) uses the same lock + atomic-write pattern, with merge-on-save so contact sync and message sync preserve each other's unrelated sections. Search Console's optional [gsc] service-account fallback is separate from that shared token store: it is cached only in-process and keyed by the resolved account/config fingerprint before corky reuses it.

Threading: Synced conversations include a **Message-ID** metadata line per message. Draft YAML supports a thread_id field (Gmail thread ID) so replies thread correctly via the Gmail API.

Notes:

  • If your OAuth app is in testing mode, add the Gmail account as a test user in the Cloud Console
  • login_hint pre-selects the configured email in the consent screen
  • Google access tokens are short-lived by design; Corky stores refresh tokens and refreshes access tokens automatically when the original authorization is still valid
  • Post-auth verification ensures the token matches the configured account
  • Incremental sync uses Gmail's historyId for efficient polling after initial sync
  • Messages deleted between listing and fetch (404) are skipped gracefully — sync continues with remaining messages

Connector / Codex-friendly JSON surfaces:

corky doctor gmail --json
corky sync refetch THREAD_ID --json
corky draft push drafts/reply.md --json
corky draft push drafts/reply.md --send --json
corky draft send drafts/reply.md --attachment /tmp/file.pdf --json

These commands keep the normal human-readable output by default. --json emits stable machine-readable summaries for auth state, single-thread refetches, draft creation, and sends.

Development

cp .corky.toml.example mail/.corky.toml
make check    # clippy + test
make release  # build + symlink to .bin/corky

See building and conventions.

AI agent instructions

Project instructions live in AGENTS.md (symlinked as CLAUDE.md). Personal overrides go in CLAUDE.local.md / AGENTS.local.md (gitignored).

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

corky-0.28.2.tar.gz (424.1 kB view details)

Uploaded Source

Built Distributions

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

corky-0.28.2-py3-none-win_amd64.whl (11.6 MB view details)

Uploaded Python 3Windows x86-64

corky-0.28.2-py3-none-manylinux_2_39_x86_64.whl (16.0 MB view details)

Uploaded Python 3manylinux: glibc 2.39+ x86-64

corky-0.28.2-py3-none-macosx_11_0_arm64.whl (10.9 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

corky-0.28.2-py3-none-macosx_10_15_x86_64.whl (12.5 MB view details)

Uploaded Python 3macOS 10.15+ x86-64

File details

Details for the file corky-0.28.2.tar.gz.

File metadata

  • Download URL: corky-0.28.2.tar.gz
  • Upload date:
  • Size: 424.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.12.6

File hashes

Hashes for corky-0.28.2.tar.gz
Algorithm Hash digest
SHA256 6174f65286e400fd9ac3f4c89d65d28138b32244ae5851ae977523ecb2ed6f1e
MD5 86b73fe98422e2be832570ae59ef64df
BLAKE2b-256 a3e80cac2d76914de0b9ef442a627e4813a9e9dc12d14c1e1bd1fd888729063a

See more details on using hashes here.

File details

Details for the file corky-0.28.2-py3-none-win_amd64.whl.

File metadata

  • Download URL: corky-0.28.2-py3-none-win_amd64.whl
  • Upload date:
  • Size: 11.6 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.12.6

File hashes

Hashes for corky-0.28.2-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 c90c2e63e362c7d6928829947e6c019d9f3e9f1467291ed90e8832469bb5e2c9
MD5 6bfab28c41ce63628e515a8937d2d0a9
BLAKE2b-256 b6ef85238b31acbb889e14ba467028af53027f302421578e740c890575a56183

See more details on using hashes here.

File details

Details for the file corky-0.28.2-py3-none-manylinux_2_39_x86_64.whl.

File metadata

File hashes

Hashes for corky-0.28.2-py3-none-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 1a3e3ee08f188b460a49ee2161be6d7bd762ad3c6e65ee1244964b2dd210c7a3
MD5 6b180115abcd720e6406a048dba9a082
BLAKE2b-256 c901dff2a540053ef8dea87ec48f5d16fe93df6c8e471bd24fdbb7af0b95dfb2

See more details on using hashes here.

File details

Details for the file corky-0.28.2-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for corky-0.28.2-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0ab1cefb309be4592554163ca02069298ef31abad858be1197dec66f33ce7b44
MD5 68598d3b0e72c7f2bfc9b71838f476ab
BLAKE2b-256 d89cc612ebdb875a207956330768f33e5cd3056499bd8e0e71ace41b3cbc1889

See more details on using hashes here.

File details

Details for the file corky-0.28.2-py3-none-macosx_10_15_x86_64.whl.

File metadata

File hashes

Hashes for corky-0.28.2-py3-none-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 8b6edfc8cf9b8ad5a3f7ebb03deb8addcaf25fafe46f20639110754b0d859a8e
MD5 4cadd931f4a3a4f0c69eb8bcb9ef5a2a
BLAKE2b-256 776a666f9a046716e931b20754f1f09f1c389074ba006c162ee8611e6db0dd60

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