scrybe 1.3.2

Local-first meeting recording, transcription, and notes for macOS.
scrybe-1.3.2 is not a library.
Visit the last successful build: scrybe-0.1.0

scrybe

Crates.io License: Apache-2.0

Local-first meeting transcription and notes. No bot, no account, no vendor cloud by default.

scrybe is an open-source meeting transcription tool built around one constraint: the meeting artifacts belong on the user's machine as ordinary files. It captures audio locally, transcribes it with either local Whisper or a user-configured OpenAI-compatible provider, generates Markdown notes, and writes everything under ~/scrybe/.

Current release: v1.3.2.

What Works Today

The supported user path today is macOS:

  • scrybe init writes the default local macOS profile on macOS.
  • scrybe init --profile default writes the hermetic synthetic profile used by CI and cross-platform smoke tests.
  • scrybe record creates a session folder with source-separated audio.opus, centered playback.opus, transcript.md, notes.md, and meta.toml.
  • --source synthetic runs the hermetic smoke path used by CI.
  • --source mic records Core Audio's default microphone resolved once at session start; --input-device <uid> or [record].input_device pins an exact macOS Core Audio device UID.
  • scrybe devices lists macOS input-device UIDs and identifies the current default.
  • --source mic+system records microphone plus macOS system audio through ScreenCaptureKit when built with mic-capture,system-capture-mac on macOS 13+. It requires the broader Screen & System Audio Recording permission.
  • --whisper-model <PATH> enables local whisper.cpp transcription when built with whisper-local.
  • --llm openai-compat enables real notes through Ollama, vLLM, OpenAI, Groq, Together, or any compatible /chat/completions endpoint when built with llm-openai-compat.
  • scrybe list, scrybe show <id>, scrybe doctor, scrybe repair <session>, scrybe notes <session>, and scrybe bench are available in the CLI.
  • scrybe bench stt --corpus <MANIFEST> --whisper-model <FILE> --sherpa-model <DIR> compares both local providers on a checksum-validated English paired corpus when built with whisper-local,stt-sherpa and an explicitly provisioned native runtime. Manual acquisition and measurement scope. Whisper remains the default; the historical multilingual corpus is Whisper-only.

Linux, Windows, and Android crates are present in the workspace as adapter surfaces and scaffolds. They are not the polished end-user install path yet. The project keeps those adapters in-tree so the trait contracts, config, tests, and packaging work stay cross-platform from the start.

Install

Install the full macOS application from crates.io:

cargo install scrybe --locked
scrybe doctor

This builds Scrybe locally with microphone capture, ScreenCaptureKit system audio, Whisper, Opus, and OpenAI-compatible notes enabled. It requires Rust 1.95 and Xcode Command Line Tools.

For a faster prebuilt installation:

curl --proto '=https' --tlsv1.2 -LsSf \
  https://github.com/Mathews-Tom/scrybe/releases/latest/download/scrybe-installer.sh | sh
scrybe doctor

The GitHub installer downloads the matching macOS tarball, verifies the release checksum manifest, and installs scrybe on PATH. Both installation paths provide the same production capabilities. Manual tarball installation, release verification, and source builds are documented in INSTALL.md.

First Local Recording Setup

mkdir -p ~/Library/Application\ Support/dev.scrybe.scrybe/models
curl -L -o ~/Library/Application\ Support/dev.scrybe.scrybe/models/ggml-small.en.bin \
  https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-small.en.bin

ollama pull gemma4:latest
scrybe init

On macOS, bare scrybe init writes the local recording profile:

  • [record].source = "mic+system"
  • [record].input_device = "<Core Audio UID from scrybe devices>" (pins the meeting microphone instead of following later OS default changes)
  • [record].llm = "openai-compat"
  • [record].system_backend = "sck" (ScreenCaptureKit; use "tap" only for the macOS 14.4+ legacy Core Audio Tap recovery path)
  • [stt].model = "small.en" and [stt].language = "en"
  • [llm].model = "gemma4:latest"

The macOS platform data path is ~/Library/Application Support/dev.scrybe.scrybe/. Other platforms resolve the model path through their native data directory convention. Pass --profile default for the synthetic smoke-test profile, or override local model choices with --whisper-model <PATH> and --llm-model <MODEL>.

If a config file already exists, scrybe init refuses to overwrite it; pass --force only when you intentionally want to replace the existing config with fresh profile defaults.

Record:

scrybe record "client-call"
# Press Ctrl-C to stop.
scrybe list
scrybe show <session-id>

The ergonomic scrybe record TITLE resolves capture source, system-audio backend, Whisper model, and LLM kind from your config and platform probes. ScreenCaptureKit runs directly from the invoking terminal; the legacy tap backend auto-launches through the .app bundle so its Audio Capture TCC grant binds correctly. Use scrybe rec --title TITLE --source … --system-backend … --whisper-model … --llm … when you need explicit flag control (CI, debugging, alternate hardware setups).

Select a microphone explicitly:

scrybe devices
scrybe rec --title "client-call" --source mic --input-device <uid>

The terminal prints each accepted transcript chunk while recording, then reports transcript flush, audio encoding, notes generation, and metadata-writing progress after the first Ctrl-C or SIGTERM. A second signal aborts finalization immediately. Run scrybe repair <session-folder> to recover unfinished audio or reconstruct missing metadata, then scrybe notes <session-folder> to regenerate missing notes.

For cloud or hosted-compatible LLMs, configure [llm] with a base URL, model, and an environment-variable name for the API key. Secrets stay in the environment, not in config.toml.

Storage Model

Every session is a directory:

~/scrybe/
└── 2026-05-02-1430-acme-discovery-01HXY7K9RZ/
    ├── audio.opus
    ├── playback.opus
    ├── transcript.md
    ├── notes.md
    ├── meta.toml
    ├── pid.lock
    ├── transcript.partial.jsonl
    └── .stignore

The filesystem is the database. meta.toml, notes.md, audio.opus, and playback.opus use atomic replace. transcript.md is append-only. Audio is treated as the source of truth so failed or improved transcription can be regenerated later.

For --source mic+system, audio.opus preserves the source master with the user's microphone on the left channel and system audio on the right. playback.opus contains the same meeting as a centered stereo listening mix, preventing either speaker from playing in only one ear. The exact source layout remains recorded in meta.toml under [audio].layout as stereo:mic-l,system-r; downstream transcription and archival tools must use audio.opus, not the convenience playback mix. Mono sessions produce only audio.opus.

Architecture

scrybe is a Rust workspace with a small core and platform adapters:

Package Role
scrybe Published application and scrybe binary (scrybe-cli/)
scrybe-meeting-core Published session, storage, config, provider, hook, diarization, and pipeline library
scrybe-meeting-capture-mac Published macOS microphone and system-audio adapter
scrybe-meeting-capture-mic Published microphone adapter via cpal
scrybe-capture-linux Private PipeWire/Pulse adapter surface
scrybe-capture-win Private WASAPI adapter surface
scrybe-android Private Android FFI adapter surface

The important public seams are:

  • AudioCapture for platform audio.
  • ContextProvider for meeting metadata.
  • SttProvider and LlmProvider for transcription and notes backends.
  • Diarizer for speaker attribution.
  • Hook for post-session actions.

The Tier-1 stability contract is documented in docs/system-design.md. In short: AudioCapture, MeetingContext, LifecycleEvent, ConsentAttestation, the meta.toml schema, storage invariants, and the Apache-2.0 license are frozen for the v1 series.

Privacy and Network Posture

  • The published application includes OpenAI-compatible provider support, but no network provider runs unless selected in configuration.
  • API keys are read from named environment variables.
  • There is no account system, sync service, telemetry, hosted backend, or bot that joins calls.
  • Courtesy notification is part of the recording flow and is recorded in meta.toml.
  • scrybe mcp (feature agent-access, off by default) is a read-only local-agent surface over ~/scrybe/: it exposes list_recent_meetings, search_meetings, get_meeting, get_meeting_notes, and get_meeting_transcript as MCP tools over stdio JSON-RPC. There is no write, delete, or mutate capability anywhere in the module, and no network listener — stdio only, reachable only by spawning it as a child process. The server refuses to start unless [agent_access].enabled = true is set explicitly in config.toml.

Run the egress audit locally:

cargo build -p scrybe --release --no-default-features
python3 scripts/check-egress-baseline.py

Current Limitations

  • macOS is the only polished binary distribution target today.
  • --source mic+system defaults to ScreenCaptureKit on macOS 13+ and requires Screen & System Audio Recording. This privacy permission covers screen recording in addition to system audio; deny it if that scope is unacceptable.
  • The macOS 14.4+ Core Audio Tap backend remains available as [record].system_backend = "tap" for recovery. It requires the narrower Audio Capture permission and a signed .app bundle. A failed or silent Tap switches once to ScreenCaptureKit after a 1.5 s startup window, so a quiet desktop can switch before external audio begins.
  • Tray and global-hotkey shell support exists behind cli-shell; the headless record path remains the reliable path.
  • crates.io installation supports the polished macOS application. Linux and Windows recording remain parked until hardware-qualified release paths exist.
  • Native macOS notarization and Windows Authenticode signing are out of scope for the v1 line. Release artifacts are verified with checksums and cosign provenance instead.

Development

Required toolchain is pinned by the repository:

cargo fmt --all --check
cargo clippy --workspace --all-targets --no-default-features -- -D warnings
cargo check --workspace --all-targets --no-default-features
cargo test --workspace --all-targets --no-default-features

Additional gates used by CI include cargo audit, cargo deny check, coverage, LoC budget, egress audit, release planning, and advisory reproducibility checks.

Project docs:

License

Apache-2.0. See LICENSE.