Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

whosaid

PYPI · WHOSAID

Local speaker-attributed transcription and meeting search for Apple Silicon. Audio stays on the Mac.

Available components

64 Trust /100

Last scanned (12 hours ago)

Scores higher than 64% of PyPI servers

Category Education and Research

Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →

Supply Chain Security50
  • Malware scan not yet available for this package.Unverified
  • No known CVEs affecting this package version or its production dependencies.Pass
  • Runs hatchling.build at install time, a recognised build step with no custom scripting around it. View diagnostics → Pass
  • 2 of 72 dependencies flagged as unhealthy. View diagnostics → Partial
Provenance & Transparency97
  • Source repository is publicly reachable at the declared URL. View diagnostics → Pass
  • Cryptographically verified build provenance (signed, bound to sblattj/whosaid). View diagnostics → Pass
  • Clear OSI-approved license (MIT).Pass
  • Actively maintained (last published 1 days ago).Pass
  • Disclosure check failed: no security disclosure policy was found in the source repository. See how to fix → Fail
Schema Quality & AI Usability72
  • 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
  • AI-judged instruction clarity (good).Pass
  • Context-footprint check failed: tool/resource definitions use about 4432 tokens (~211/item across 21 items; 17 tools + 4 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management10
  • Stability observed for 3 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage67
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 0% of tool parameters carry a description.Fail
Tool Safety100
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • We read all 17 captured tool definition(s), and no name or description among them implies an irreversible operation.Pass
  • An AI judge read all 19 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a current MCP spec version (2026-07-28).Pass
Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 22 Oct 26 +1
    • Stability: unverified → 0.07 ▲ functional
    • Package version: 1.14.0 → 1.15.0 functional
  • 20 Oct 26 63

    First indexed and scored.

Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 23 Oct 2026 · Analysed pypi/whosaid@1.15.0

Provenance Verified

A signed build attestation was found and verified, binding this exact artifact to the source repository it claims to come from.

Result Verified
Ecosystem pypi
Reason Verified
Discovered via Registry attestation endpoint
Source repo sblattj/whosaid
Certificate issuer https://token.actions.githubusercontent.com
Certificate SAN https://github.com/sblattj/whosaid/.github/workflows/publish.yml@refs/tags/v1.15.0
Rekor log index 3370930405
Predicate type PyPI publish attestation https://docs.pypi.org/attestations/publish/v1
Subject digest sha256:76f88b983513c96a581a7e6986d94f499f4889d32d51aead286708540b56457b

Background: How many MCP packages publish verified provenance →

Install scripts 1 script
Hook Tier Command
build_backend allowlisted hatchling.build

Background: Why install scripts are a supply-chain risk →

Dependencies 72 packages
Packages resolved 72
Stale 1
No linked repository 1
Tree resolution Complete

Background: SBOMs and build attestations, explained →

MCP tools · 17 exposed · ~3,370 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
whosaid_context ~159

Read the verbatim transcript turns around ONE moment of ONE meeting: `meeting` is the workspace folder name from a search hit, `at` its timestamp (HH:MM:SS or MM:SS), `before`/`after` the window in seconds (default 60 s before, 120 s after). Call this after whosaid_search instead of loading a whole transcript: it is the cheap way to confirm what was actually said and by whom. Read-only. Keywords: context, surrounding turns, what was said before, exact quote, verify a hit.

NameTypeReqDescription
afterinteger––
atstringyes–
beforeinteger––
meetingstringyes–
workspace–––

No output schema declared.

No examples provided.

whosaid_doctor ~92

Read-only readiness check: Apple-Silicon/arch + macOS, ffmpeg and uv, Whisper and diarization model-cache state, enrolled voices, and the mic/audio device list. Run this FIRST when a transcribe fails — each missing prerequisite prints the exact fix (usually `whosaid setup`). Keywords: health check, prerequisites, diagnose, models cached, setup status, is it ready.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

whosaid_enroll_from_file ~146

Enroll a named voice from an EXISTING audio clip (≥15 s of one person speaking, reasonably clean) so future transcripts auto-label them — converts and writes voices/<Name>.wav. This does NOT record from the mic: for mic enrollment use the interactive `whosaid enroll` CLI (it needs a terminal and Microphone permission). Fails clearly if the clip is too short or silent. Keywords: enroll voice, add speaker, register voice, voiceprint, teach a new voice from a file.

NameTypeReqDescription
audiostringyes–
namestringyes–
ss–––
t–––
to–––

No output schema declared.

No examples provided.

whosaid_item ~79

One action item by id (AI-NNN) with its full history: every meeting it came up in, the timestamped turns where it was discussed, commitments and status changes, related PRs. Use whosaid_context on those timestamps for the verbatim discussion. Read-only.

NameTypeReqDescription
idstringyes–
workspace–––

No output schema declared.

No examples provided.

whosaid_items ~117

List action items from the workspace's entity graph, filtered by `owner`, `requester`, `status` or `type`. Each item carries its id (AI-NNN), text, owner, status, the meetings it was raised in and any commitments. Built by `whosaid index`; read-only. Keywords: action items, todos, commitments, who owes what, open items, follow-ups.

NameTypeReqDescription
owner–––
requester–––
status–––
type–––
workspace–––

No output schema declared.

No examples provided.

whosaid_list_speakers ~109

List the voices whosaid can already auto-name: enrolled clips in `voices/` plus voiceprints saved in the local speaker registry (~/.config/whosaid/speakers.json). Read-only. Call this before whosaid_relabel so you reuse an existing name instead of creating a duplicate. Each registry entry carries its role tag (self/boss/…) when set. Keywords: known speakers, enrolled voices, registry, recognized voices, who can it identify.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

whosaid_meetings ~247

List the meetings in the workspace as the graph knows them: folder, date, duration, attendees (speaker labels), action-item count, and kind (source origin: "teams-chat" for a Microsoft Teams chat folder, "outlook-mail" for an Outlook mail thread, "audio" for a recorded meeting; pass kind to filter). The folder names are what whosaid_search hits carry, what whosaid_context takes, and what the whosaid://workspace/meeting/{folder}/... resources use. Newest first. Filter with kind, since/until (YYYY-MM-DD, inclusive, on the meeting date) and query (case-insensitive substring of folder or source name), then page with offset (skip N) and limit (top N); compact=true keeps only folder, kind, created and minutes. A call with neither limit nor offset returns the newest 50 plus total/omitted and a paging hint. Read-only.

NameTypeReqDescription
compactboolean––
kind–––
limit–––
offsetinteger––
query–––
since–––
until–––
workspace–––

No output schema declared.

No examples provided.

whosaid_person ~109

Per-person commitments view (GitHub issue #13): what `name` owns, what they asked others for, deadlines they gave, and the meetings they were in. Omit `name` to list every known person with counts. Names are speaker labels exactly as they appear in the transcripts (see whosaid_speakers). Read-only. Keywords: my action items, what does X owe, commitments by person, who promised what.

NameTypeReqDescription
name–––
workspace–––

No output schema declared.

No examples provided.

whosaid_prs ~94

List pull-request mentions found in the transcripts: PR numbers or links, who mentioned them, in which meeting and when. Read-only. Keywords: PR, pull request, code review, merged, deployed. Page with offset/limit; a call with neither returns the first 50 plus total/omitted and a paging hint.

NameTypeReqDescription
limit–––
offsetinteger––
workspace–––

No output schema declared.

No examples provided.

whosaid_relabel ~445

Put real names on SPEAKER_NN clusters and REMEMBER them: each name is saved to your local speaker registry and auto-applied to EVERY future transcript. Reads the cached <base>.diarization.json sidecar and rewrites <base>.speakers.txt + <base>.speaker-cards.txt in place — no re-transcription, no re-diarization. Run whosaid_transcribe first, read its speaker cards to tell who is who, then map clusters to names. Pass auto=true (with an empty assignments map) to instead re-apply registry matching + the absorb pass over the cached sidecar, which folds phantom cluster splits into their real speaker. With auto=true, pass fold_unknown=true to repair anonymous phantom clusters in a cached sidecar. auto=true also matches the enrollment clips in voices/ and drops auto-assigned names whose registry entry and clip are gone; pass forget=['Name'] (with auto=true) to clear a name from this meeting's clusters first (it can come back if still enrolled and matching). Optionally pass `roles` ({Name: role} — self/boss/peer/report/external) to role-tag speakers in the registry, cards, and transcripts. Pass no_save=true for a transcript-only label: sidecar + outputs are renamed but the registry is untouched (composes with auto=true); note adds a provenance string stored with each local label; force=true overrides the guard that refuses replacing a registry print whose similarity to the cluster is below match_threshold; blend=true averages the cluster into the existing registry print instead of replacing it (same guard), to strengthen a voiceprint from a new recording. Keywords: rename speaker, label speaker, assign name, identify voice, who is SPEAKER_00, correct labels.

NameTypeReqDescription
assignmentsobjectyes–
autoboolean––
basestringyes–
blendboolean––
fold_unknownboolean––
forceboolean––
forget–––
match_threshold–––
no_saveboolean––
note–––
outdir–––
roles–––

No output schema declared.

No examples provided.

whosaid_reprocess ~424

Re-diarize meetings in a workspace whose speaker sidecars predate the v1.10 diarizer fixes (wraps `whosaid reprocess`). DEFAULT IS A DRY RUN (dry_run=true): it prints the scan report and the plan and changes nothing; pass dry_run=false to apply. When applied it rewrites each meeting's speaker-labeled transcript and diarization sidecar from the existing Whisper <base>.json, so ASR is NOT re-run, carries over transcript-only (no_save) labels, regenerates per-meeting action items and commitments (skip with no_items=true), then re-runs the workspace roll-up so corpus item ids and hand edits survive. Every touched meeting is first backed up to <workspace>/_reprocess-backups/<meeting>/<UTC timestamp>/. With no `meetings` and all_meetings=false it takes only the meetings the detector flags; all_meetings=true takes every meeting; `meetings` is a list of folder names. speakers/min_speakers/max_speakers/engine/hook override the diarization settings. expected_speakers is a list of known voice names (the roster, sent as one comma list) that anchors diarization to those enrolled voices. match_threshold (above 0, at most 1) is the cosine a known voice must reach to claim a cluster. Not read-only and slow when applied (minutes per meeting); run the dry run first. Workspace = the `workspace` argument or WHOSAID_WORKSPACE. Keywords: reprocess, re-diarize, redo speakers, fix speaker labels, old meetings, backfill.

NameTypeReqDescription
all_meetingsboolean––
dry_runboolean––
engine–––
expected_speakers–––
hook–––
match_threshold–––
max_speakers–––
meetings–––
min_speakers–––
no_itemsboolean––
speakers–––
workspace–––

No output schema declared.

No examples provided.

whosaid_samples ~213

Export ONE short representative WAV clip per SPEAKER_NN cluster, cut from the ORIGINAL recording, so a human can quickly LISTEN and confirm an identity before trusting an auto-label or enrolling that voice — replaces cutting clips by hand with ffmpeg. Picks each cluster's longest diarized segment, clamped to `seconds` (default 8), and writes <base>.samples/<SPEAKER_NN>[-<Name>].wav (mono 16kHz). Needs the sidecar's 'source' metadata (present since GitHub issue #1 parts 2-3); an older sidecar without it must be re-transcribed, or use the `whosaid samples --audio FILE` CLI flag directly. Keywords: sample clip, listen to speaker, verify identity, confirm voice, spot check, per-speaker snippet, sanity check a label.

NameTypeReqDescription
basestringyes–
outdir–––
per_speakerinteger––
secondsnumber––

No output schema declared.

No examples provided.

whosaid_search ~225

Search every speaker-labeled transcript in a meeting workspace and get back the matching TURNS (meeting folder, timestamp, speaker, text, score), not whole files. mode: exact (SQLite FTS5 full text; quoted phrases and prefix* work), meaning (local Ollama embeddings; falls back to exact when the index has none), hybrid (both, the default). Filter by `speaker` label or `meeting` folder; `k` caps the hits (1-100). Then call whosaid_context on a hit to read the verbatim minute around it. Read-only: the index is built by `whosaid index <ws>` from the CLI, never here. Workspace = the `workspace` argument or WHOSAID_WORKSPACE. Keywords: search transcripts, who said, find a quote, when did we discuss, meeting search, full text, semantic search.

NameTypeReqDescription
kinteger––
meeting–––
modestring––
querystringyes–
speaker–––
workspace–––

No output schema declared.

No examples provided.

whosaid_speakers ~106

List every speaker label in the search index with turn counts and the meetings they appear in. Use the exact labels as the `speaker` filter of whosaid_search or the `name` of whosaid_person. Busiest first; page with offset/limit; a call with neither returns the top 50 plus total/omitted and a paging hint. Read-only.

NameTypeReqDescription
limit–––
offsetinteger––
workspace–––

No output schema declared.

No examples provided.

whosaid_transcribe ~354

Transcribe an audio file and label each turn with WHO said it — 100% locally on the Apple-Silicon GPU (no cloud, no API keys). Writes <base>.txt, <base>.speakers.txt (speaker-labeled), <base>.speaker-cards.txt and a <base>.diarization.json sidecar next to the input (or `outdir`). The FIRST run downloads ~1.5 GB of models. Speakers you haven't named come back as SPEAKER_00/01…; the result includes the speaker cards — read them, then call whosaid_relabel to name them (names then auto-apply to future transcripts). If you already know who was in the room, pass `expected_speakers` (names of voices you have enrolled) — clustering is then anchored to their voiceprints, absentees are dropped, and nobody has to guess a count. Any speaker role tags (self/boss/…) come back under `roles`. If diarization fails the result is ok=false, partial=true with `diarization_error`; the plain transcript is still written. Keywords: transcribe, diarize, speaker diarization, who spoke, meeting notes, call recording, whisper, voice attribution, subtitles, srt, vtt.

NameTypeReqDescription
accuracystring––
anchor_threshold–––
audiostringyes–
diarizeboolean––
expected_speakers–––
formatstring––
langstring––
match_threshold–––
max_speakers–––
min_speakers–––
outdir–––
speakers–––

No output schema declared.

No examples provided.

whosaid_worklist ~327

Ranked personal worklist (GitHub issue #13): what `owner` signed up for across every meeting, from the roll-up corpora (dev-commitments CM-NNN plus the action items AI-NNN they own), each item tiered P1/P2/P3 with a numeric score and short why strings. P1 = boss-requested, a blocking/urgency cue, a deadline cue, or seen in 3+ meetings; P2 = seen in 2 meetings, requested by anyone, or a strong cue in the latest meeting; P3 = the rest; negated items are never P1. owner is a speaker label or 'me' (the self-roled speaker, else the whosaid.toml [workspace] owner). Filter and page with tier (P1/P2/P3, case-insensitive) first, then offset (skip N), then limit (top N); compact=true keeps only id, source, text, tier, score and why per item; a call with neither limit nor offset returns the top 50 items plus total/omitted and a paging hint (GitHub issue #30). Deterministic, no LLM, same view as _WORKLIST-<Owner>.md. Read-only. Keywords: my worklist, what did I promise, what did I sign up for, my priorities, ranked commitments.

NameTypeReqDescription
compactboolean––
limit–––
offsetinteger––
ownerstring––
tier–––
workspace–––

No output schema declared.

No examples provided.

whosaid_workspace_status ~124

Read-only health check for a meeting workspace: whether the search index (_search.db) exists and what it holds (meetings, turns, embeddings), whether the rendered _WIKI.md, _ACTION-ITEMS.md and _INDEX.md exist, how many meeting folders there are, and the configured owner and group names from whosaid.toml. Run this first when a search returns nothing: it tells you whether `whosaid index <ws>` has been run. Keywords: workspace status, is it indexed, index health.

NameTypeReqDescription
workspace–––

No output schema declared.

No examples provided.

Install

How do I install the whosaid MCP server?

whosaid runs locally as a PyPI package, launched with uvx whosaid. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

pypi · whosaid

# add to Claude Code
claude mcp add sblattj-whosaid -- uvx whosaid
Common questions

What is the whosaid MCP server?

whosaid is an MCP server listed in the public MCP registry as io.github.sblattj/whosaid. Local speaker-attributed transcription and meeting search for Apple Silicon. Audio stays on the Mac. This page covers its PyPI package (whosaid).

Is the whosaid MCP server safe to use?

whosaid scores 64 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 23 October 2026. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the whosaid MCP server expose?

whosaid exposes 17 tools: whosaid_transcribe, whosaid_relabel, whosaid_list_speakers, whosaid_doctor, whosaid_enroll_from_file, and 12 more. Their descriptions and schemas cost roughly 3,370 tokens of context every time the server is loaded.

Is the whosaid MCP server still maintained?

whosaid is still listed as active in the MCP registry. We last reached this channel on 23 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

What licence is the whosaid MCP server under?

whosaid declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.