Turn meeting recordings into speaker-labelled transcripts and evidence-grounded summaries.
Project description
Meeting Scribe
Turn a local meeting recording into a speaker-labelled transcript and an evidence-grounded Markdown summary.
Meeting Scribe is a command-line tool. It reads a recording from your computer, sends it to the OpenAI API for transcription and summarization, then writes one Markdown report to your computer. It is designed to make review easy: the report includes both the summary and the complete transcript it was based on.
[!IMPORTANT] Review the report before sharing it or acting on it. Transcription, speaker labels, and generated summaries can be incomplete or incorrect.
Requirements
- Python 3.14 or newer
- An OpenAI API key with access and billing for the required API models
ffmpegandffprobeon yourPATHwhen a recording must be split before upload (see Large or long recordings)
The command accepts these recording extensions: .m4a, .mp3, .mp4,
.mpeg, .mpga, .wav, and .webm.
Install
Choose one installation method. uv is a convenient way to run the project
from a checkout; pip and pipx are appropriate once the package is
published to PyPI.
Install with pip
python -m pip install meeting-transcribe
If your platform separates Python 3 from Python, use the Python 3.14-or-newer
interpreter explicitly, for example python3.14 -m pip install meeting-transcribe.
Install with pipx
pipx installs the command in an isolated environment:
pipx install meeting-transcribe
If the command is not found afterwards, run pipx ensurepath, open a new
terminal, and try again.
Run from a checkout with uv
Clone the repository, then let uv create the environment and install the
package:
git clone https://github.com/horatiu-negutoiu/meeting-transcribe.git
cd meeting-transcribe
uv sync
Run the command through uv from that directory:
uv run meeting-scribe --help
Configure your API key
Create a key in the OpenAI platform, then set it only in the environment of the terminal that will run Meeting Scribe:
export OPENAI_API_KEY="your_api_key_here"
On PowerShell:
$env:OPENAI_API_KEY = "your_api_key_here"
Do not put the key in a command-line argument, recording filename, transcript,
or committed configuration file. Meeting Scribe reads only OPENAI_API_KEY;
it does not accept credentials as CLI arguments or write them to its report.
For a persistent setup, use your operating system's secret manager, your shell profile with appropriate file permissions, or a trusted environment manager. See Security for reporting a vulnerability and handling secrets.
Quick start
First, confirm the available options:
meeting-scribe --help
Then process a recording:
meeting-scribe path/to/team-sync.m4a
When running from a checkout with uv, prefix the same command with uv run:
uv run meeting-scribe path/to/team-sync.m4a
On success, the command prints the exact report path:
Created meeting transcript: /path/to/transcription-output-YYYYMMDD-HHMMSS.md
Command options
meeting-scribe [-h] [--output-dir DIR] [--language CODE]
[--no-speakers] [--model MODEL] audio_file
audio_fileis a readable local recording in one of the supported formats.--output-dir DIRwrites the report toDIR; without it, the report is placed beside the recording.--language CODEsets the spoken-language code. The default isen.--no-speakersrequests a transcript without speaker labels.--model MODELoverrides the transcription model. The default isgpt-4o-transcribe-diarize.
For example, to produce a French report without speaker labels in a separate folder:
meeting-scribe meeting.mp3 --language fr --no-speakers --output-dir reports
What the report contains
Each report is a new timestamped Markdown file named
transcription-output-YYYYMMDD-HHMMSS.md. If a file with that name already
exists, Meeting Scribe adds a numeric suffix instead of overwriting it.
The report includes:
- the source filename, creation time, selected transcription and summary models, and whether the recording was split into chunks;
- an evidence-grounded summary with decisions, proposals, action items, open questions, risks, discussion notes, and evidence; and
- the full transcript.
When speaker labels are requested and returned, they are converted to anonymous
labels such as Speaker 1. These labels distinguish voices only; they do not
identify people and can be inconsistent, especially across chunk boundaries.
Large or long recordings
The transcription upload limit is 25 MB. The default diarization model also has
a per-request duration limit. If a recording is too large, or the API rejects
it as too long for diarization, Meeting Scribe re-encodes it into overlapping,
upload-safe .m4a chunks and retries. The overlap helps avoid losing speech at
the boundary.
That fallback requires both ffmpeg and ffprobe to be installed and
available on PATH. Common installation commands include:
# macOS with Homebrew
brew install ffmpeg
# Debian or Ubuntu
sudo apt install ffmpeg
# Windows with winget
winget install Gyan.FFmpeg
After installing, open a new terminal and check both commands:
ffmpeg -version
ffprobe -version
Privacy and data handling
Meeting Scribe is local-first in where it stores files, but processing is not fully local:
- The selected recording is uploaded to the OpenAI API for transcription.
- The transcript is sent to the OpenAI API to generate the summary.
- The final Markdown report is written locally, in the input directory or the
directory selected with
--output-dir. - The tool does not automatically redact recordings or transcripts, delete the source recording, delete the report, or upload the report as a separate artifact.
Only process recordings you are authorized to share and retain. Confirm the applicable consent, confidentiality, retention, and OpenAI account data-use settings for your organization before processing sensitive meetings.
Limitations
- Speaker labels are anonymous voice groupings, not verified identities.
- The default language is English; set
--languageto match the recording. - Audio quality, overlapping speakers, accents, background noise, and mixed languages can reduce transcription accuracy.
- The summary uses only the transcript, but generated output may still omit context or state something incorrectly. Treat it as a draft for human review.
- Splitting a long recording helps meet request limits but may make speaker labels less consistent across chunks.
- An API key, network connection, eligible account, and available models are required for processing.
Troubleshooting
| Problem | What to do |
|---|---|
meeting-scribe: command not found |
Reinstall with the chosen method. For pipx, run pipx ensurepath, open a new terminal, and retry. For a checkout, use uv run meeting-scribe .... |
OPENAI_API_KEY is not set |
Export the key in the terminal that runs the command, then rerun it. Do not pass the key as a command argument. |
audio file does not exist or is not readable |
Verify the path, permissions, and that the file is a regular local file. Quote paths containing spaces. |
unsupported audio format |
Convert the recording to .m4a, .mp3, .mp4, .mpeg, .mpga, .wav, or .webm. |
ffmpeg (including ffprobe) is unavailable |
Install FFmpeg, ensure both commands are on PATH, open a new terminal, and verify with ffmpeg -version and ffprobe -version. |
Could not split the recording with ffmpeg |
Confirm that the recording is readable and contains audio, then try again. The error includes FFmpeg details. |
API request failed or a summary failure |
Check the API key, network connection, account billing/access, and model availability. Rerun after resolving the provider error. Individual requests time out after five minutes rather than hanging indefinitely. |
| No report was created | Resolve the terminal error and rerun. A report is published only after the workflow completes successfully. |
Development
uv sync --extra dev
uv run pytest
uv run meeting-scribe --help
Validate a release artifact
Build release artifacts with uv build. Before publishing, validate their
metadata and README rendering, then test each artifact in a fresh virtual
environment:
rm -rf dist
uv build
uv run --with twine twine check dist/*
uv venv /tmp/meeting-transcribe-wheel-check
uv pip install --python /tmp/meeting-transcribe-wheel-check/bin/python dist/*.whl
/tmp/meeting-transcribe-wheel-check/bin/meeting-scribe --help
uv venv /tmp/meeting-transcribe-sdist-check
sdist_dir=$(mktemp -d)
tar -xzf dist/*.tar.gz -C "$sdist_dir"
cd "$sdist_dir"/meeting_transcribe-*
uv pip install --python /tmp/meeting-transcribe-sdist-check/bin/python '.[dev]'
/tmp/meeting-transcribe-sdist-check/bin/python -m pytest
/tmp/meeting-transcribe-sdist-check/bin/meeting-scribe --help
Publish a release
Continuous integration runs the test suite, builds both distribution artifacts, and validates their package metadata on every push and pull request. The tag-triggered release workflow publishes first to TestPyPI, waits for its index to expose the exact release, performs a clean installation smoke test, then waits for approval before the PyPI upload. Follow the release runbook for the one-time Trusted Publishing setup, release procedure, verification, and remediation steps.
The source distribution is intentionally limited to the source, tests, and package-release files; inspect its file list before publishing if the build configuration changes.
The test suite makes no OpenAI requests. It includes a no-network end-to-end test covering command validation, transcription normalization, summary generation, and atomic Markdown artifact creation with a fake SDK client.
Releases and versioning
The first production PyPI release is 0.1.2; 0.1.0 and 0.1.1 are
TestPyPI-only. Meeting
Scribe follows Semantic
Versioning 2.0.0: releases use
MAJOR.MINOR.PATCH version numbers. Before 1.0.0, minor releases may include
breaking changes; patch releases contain compatible bug fixes only. Starting
with 1.0.0, breaking changes require a major-version increase, compatible
features require a minor-version increase, and compatible bug fixes require a
patch-version increase.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file meeting_transcribe-0.1.2.tar.gz.
File metadata
- Download URL: meeting_transcribe-0.1.2.tar.gz
- Upload date:
- Size: 22.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
53c290aeb1ed7f13497becd8efe943839064537adfbdf6511eda9a2e7e930af2
|
|
| MD5 |
6896f4e5d36edb84ff2387ced65bee0f
|
|
| BLAKE2b-256 |
7e242602e277e8f03e24ddaaab6844227745c64943ae417dfbf6c9065fa331bc
|
Provenance
The following attestation bundles were made for meeting_transcribe-0.1.2.tar.gz:
Publisher:
publish.yml on horatiu-negutoiu/meeting-transcribe
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
meeting_transcribe-0.1.2.tar.gz -
Subject digest:
53c290aeb1ed7f13497becd8efe943839064537adfbdf6511eda9a2e7e930af2 - Sigstore transparency entry: 2263033068
- Sigstore integration time:
-
Permalink:
horatiu-negutoiu/meeting-transcribe@2cf113bf0c4a056182d7ccacc758877d97a02d28 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/horatiu-negutoiu
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2cf113bf0c4a056182d7ccacc758877d97a02d28 -
Trigger Event:
push
-
Statement type:
File details
Details for the file meeting_transcribe-0.1.2-py3-none-any.whl.
File metadata
- Download URL: meeting_transcribe-0.1.2-py3-none-any.whl
- Upload date:
- Size: 17.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e5c51799aab900ce753bc3ae530f553939dc2ce5aca0fbce12a548542ec613dc
|
|
| MD5 |
640cd62d3f80304b6dd5c07d044191d8
|
|
| BLAKE2b-256 |
2f11eea284e1ba4b0b5755b20b6e6214d045edf41619fed811f2c5605cb04590
|
Provenance
The following attestation bundles were made for meeting_transcribe-0.1.2-py3-none-any.whl:
Publisher:
publish.yml on horatiu-negutoiu/meeting-transcribe
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
meeting_transcribe-0.1.2-py3-none-any.whl -
Subject digest:
e5c51799aab900ce753bc3ae530f553939dc2ce5aca0fbce12a548542ec613dc - Sigstore transparency entry: 2263033356
- Sigstore integration time:
-
Permalink:
horatiu-negutoiu/meeting-transcribe@2cf113bf0c4a056182d7ccacc758877d97a02d28 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/horatiu-negutoiu
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2cf113bf0c4a056182d7ccacc758877d97a02d28 -
Trigger Event:
push
-
Statement type: