eddy is one tool with a part per meeting service. A part lists and
fetches. eddy does everything after that the same way for every
service, and stops before anything reads a transcript.
eddy's parts share everything but the service
Three parts, wispr, webex and teams. Each part's own code lists its service's meetings since its cursor and fetches each transcript: Wispr Flow's MCP endpoint, Webex's transcripts API, and Microsoft Graph's meeting transcripts. Each fetched transcript then passes through the code every part shares: it reads the meeting's title, start, length and attendees, skips a meeting too short to matter, keys the meeting as meeting slash service slash id, and writes the transcript as served plus a plain copy with one line per turn. The three captures come out the same shape; only the service in the key differs.
One part per service
a part's own code lists and fetches; the rest is shared
SERVICE
THE PART
Wispr Flow
MCP endpoint over HTTP
wispr
1 list meetings since the cursor
2 fetch each transcript
Webex
transcripts API
webex
1 list meetings since the cursor
2 fetch each transcript
Microsoft Teams
Graph meeting transcripts
teams
1 list meetings since the cursor
2 fetch each transcript
SHARED BY EVERY PART
details
skip
key
raw
design review · 48 min · 4 people
48 min · long enough · kept
meeting/wispr /7f3c2a
transcript.json + transcript.txt
one capture, the same shape
vendor call · 31 min · 3 people
31 min · long enough · kept
meeting/webex /3d77a1
transcript.vtt + transcript.txt
one capture, the same shape
planning · 55 min · 6 people
55 min · long enough · kept
meeting/teams /9b1e04
transcript.vtt + transcript.txt
one capture, the same shape
1
Each part lists and fetches
from its own service.
2
The shared code checks, keys
and writes every meeting.
3
Every part's capture comes
out the same shape.
eddy's parts share everything but the service
Three parts, wispr, webex and teams. Each part's own code lists its service's meetings since its cursor and fetches each transcript: Wispr Flow's MCP endpoint, Webex's transcripts API, and Microsoft Graph's meeting transcripts. Each fetched transcript then passes through the code every part shares: it reads the meeting's title, start, length and attendees, skips a meeting too short to matter, keys the meeting as meeting slash service slash id, and writes the transcript as served plus a plain copy with one line per turn. The three captures come out the same shape; only the service in the key differs.
One part per service
a part's own code lists and fetches
THE PART'S OWN CODE
wispr
Wispr Flow
list
fetch
webex
Webex
list
fetch
teams
Teams
list
fetch
SHARED BY EVERY PART
details
title · start · length · attendees
skip
a meeting too short to matter
key
meeting/<service>/<meeting id>
raw
as served, plus one line per turn
EACH CAPTURE
meeting/wispr /7f3c2a
design review · 48 min · 4 people
48 min · long enough · kept
transcript.json + transcript.txt
meeting/webex /3d77a1
vendor call · 31 min · 3 people
31 min · long enough · kept
transcript.vtt + transcript.txt
meeting/teams /9b1e04
planning · 55 min · 6 people
55 min · long enough · kept
transcript.vtt + transcript.txt
1
Each part lists and fetches from its service.
2
The shared code checks, keys and writes it.
3
Every capture comes out the same shape.
A part’s own code is listing and fetching from its service: it lists
the meetings recorded since its cursor and fetches each transcript.
wispr does this as an MCP client of Wispr Flow’s endpoint, with a
sign-in of its own, and starts no Claude session to list meetings.
The parts share everything else:
the key’s shape , meeting/<service>/<meeting id>;
the meeting’s details : its title, start, length and attendees;
the raw layout : the transcript as served, plus a plain copy with
one line per turn;
the skip : a meeting too short to hold anything is left out.
So a new service costs a lister and a fetcher, and every part’s
captures read alike.
What a meeting becomes: two raw files on the host and one capture line
The transcript as the service served it: timed segments, each with a speaker and a few words. eddy writes it whole as transcript.json, then joins each speaker's consecutive segments into a plain copy, transcript.txt, with one line per turn: Ana, so the export ships Friday; Raj, legal needs a week first; Ana, then the 24th; Mei, I'll tell the customer. Then one capture line describes the meeting: its key meeting slash wispr slash 7f3c2a, source meeting, event_at when the meeting started, its title, the two raw files, and no excerpt, since a reader reads it. The two files stay on the host and never enter git; millpond writes the line into the inbox.
What a meeting becomes
one line for the inbox, and two files that stay on this host
AS SERVED · transcript.json
00:12
Ana
so the export
00:14
Ana
ships Friday
00:15
Raj
legal needs
00:17
Raj
a week first
00:19
Ana
then the 24th
00:21
Mei
I'll tell
00:22
Mei
the customer
timed segments, as the service sent them
ONE LINE PER TURN · transcript.txt
Ana:
Raj:
Ana:
Mei:
so the export
ships Friday
legal needs
a week first
then the 24th
I'll tell
the customer
speakers as served; a reader names the rest
THE CAPTURE LINE · to millpond
{"capture": {
key
meeting/wispr /7f3c2a
source
meeting
event_at
2026-10-16T14:00:00Z
title
design review
raw
transcript.json
transcript.txt
excerpt
none: a reader reads it
when the meeting started
}}
stays on this host, in its raw bank · never enters git
millpond writes it into the inbox
1
eddy writes the transcript
as the service served it,
2
and a plain copy with
one line per turn.
3
One small line describes
the meeting for the inbox.
4
The files stay on this host.
Only the line enters git.
What a meeting becomes: two raw files on the host and one capture line
The transcript as the service served it: timed segments, each with a speaker and a few words. eddy writes it whole as transcript.json, then joins each speaker's consecutive segments into a plain copy, transcript.txt, with one line per turn: Ana, so the export ships Friday; Raj, legal needs a week first; Ana, then the 24th; Mei, I'll tell the customer. Then one capture line describes the meeting: its key meeting slash wispr slash 7f3c2a, source meeting, event_at when the meeting started, its title, the two raw files, and no excerpt, since a reader reads it. The two files stay on the host and never enter git; millpond writes the line into the inbox.
What a meeting becomes
one line for the inbox; two files stay on this host
AS SERVED · transcript.json
00:12
Ana
so the export
00:14
Ana
ships Friday
00:15
Raj
legal needs
00:17
Raj
a week first
00:19
Ana
then the 24th
00:21
Mei
I'll tell
00:22
Mei
the customer
timed segments, as the service sent them
ONE LINE PER TURN · transcript.txt
Ana:
Raj:
Ana:
Mei:
so the export
ships Friday
legal needs
a week first
then the 24th
I'll tell
the customer
speakers as served; a reader names the rest
THE CAPTURE LINE · to millpond
{"capture": {
key
meeting/wispr /7f3c2a
source
meeting
event_at
2026-10-16T14:00:00Z
title
design review
raw
transcript.json
transcript.txt
excerpt
none: a reader reads it
when the meeting started
}}
The two files stay on this host, never in git.
millpond writes the line into the inbox.
1
eddy writes the transcript as served,
2
and a plain copy, one line per turn.
3
One small line describes the meeting.
4
The files stay here. The line enters git.
eddy writes two files for each meeting it keeps. The first is the
transcript exactly as the service served it. The second is a plain
copy that joins each speaker’s consecutive segments into one line per
turn, with the speakers the service named. A reader working from the
plain copy names any speaker the transcript leaves unnamed.
Beside the files, eddy prints one capture line for the inbox:
key is meeting/<service>/<meeting id>, so the same meeting
gets the same key from every host and every run.
event_at is when the meeting started, never when eddy listed
it, since a signal’s weight counts from the day the meeting happened.
raw names the two files.
No excerpt. A meeting is never its own excerpt; a reader session
reads the transcript and writes its signals.
millpond takes the line, passes over a key it already holds, banks the
two files in the host’s raw bank and writes the capture into the inbox.
A transcript runs to megabytes and holds people’s words, so it stays on
the host and never enters git; only the line does.
Anyone can add a meeting service: a part counts once it passes the meeting checks
Three parts wait to be checked: eddy's own webex part, your plugin's part, and another plugin's part. The meeting checks in the conformance pack test each in turn: its key is meeting slash service slash meeting id; event_at is when the meeting started; the raw files are the transcript as served plus one line per turn; it skips a meeting too short to matter; it carries no excerpt. webex and your part pass and join the plugin index beside eddy's wispr. The other part stamps event_at with the capture time, fails, and is not listed. For the long tail, a generic MCP part lists meetings from any MCP endpoint that serves transcripts, and millpond's folder drop takes any file dropped in a folder as one capture.
Anyone can add a service
a part counts once it passes the meeting checks
PARTS
THE MEETING CHECKS · CONFORMANCE PACK
key is meeting/<service>/<meeting id>
event_at is when the meeting started
raw: as served, plus one line per turn
skips a meeting too short to matter
carries no excerpt
THE PLUGIN INDEX
wispr
eddy's
webex
eddy's
your-service
yours
listed beside eddy's own
webex
your-service
another-part
NOT LISTED
webex
eddy's · recorded responses
your-service
your plugin
another-part
another plugin
event_at was the capture time
THE LONG TAIL
generic MCP part
lists meetings from any MCP endpoint that serves transcripts
folder drop · millpond's
a file dropped in a folder is one capture: folder/<name>/<sha256>
1
eddy's own parts pass
on recorded responses.
2
Your plugin counts once
it passes the same checks.
3
A part that fails a check
is not listed.
4
A generic MCP part and the
folder drop take the rest.
Anyone can add a meeting service: a part counts once it passes the meeting checks
Three parts wait to be checked: eddy's own webex part, your plugin's part, and another plugin's part. The meeting checks in the conformance pack test each in turn: its key is meeting slash service slash meeting id; event_at is when the meeting started; the raw files are the transcript as served plus one line per turn; it skips a meeting too short to matter; it carries no excerpt. webex and your part pass and join the plugin index beside eddy's wispr. The other part stamps event_at with the capture time, fails, and is not listed. For the long tail, a generic MCP part lists meetings from any MCP endpoint that serves transcripts, and millpond's folder drop takes any file dropped in a folder as one capture.
Anyone can add a service
a part counts once it passes the meeting checks
PARTS
THE MEETING CHECKS
key is meeting/<service>/<meeting id>
event_at is when the meeting started
raw: as served, plus one line per turn
skips a meeting too short to matter
carries no excerpt
THE PLUGIN INDEX
wispr
eddy's
webex
eddy's
your-service
yours
webex
your-service
another-part
NOT LISTED
webex
eddy's
your-service
your plugin
another-part
another
event_at was the capture time
THE LONG TAIL
generic MCP part
any MCP endpoint that serves transcripts
folder drop · millpond's
a dropped file is one capture
1
eddy's own parts pass on recorded responses.
2
Your plugin counts once it passes too.
3
A part that fails a check is not listed.
4
A generic MCP part and the folder drop
take the rest.
A part counts as a meeting part when it passes the meeting checks in
the capture contract’s conformance pack. The checks hold a part to the
shape every part shares: the key, event_at as the meeting’s start,
both raw files, the skip, and no excerpt.
eddy’s own parts cover the services most partitions record on.
eddy tests each one by replaying recorded responses, so the checks
run without the service.
A plugin of your own lists your service’s meetings. It joins the
plugin index beside eddy’s once it passes the same checks.
The long tail goes to two catch-alls. A generic MCP part lists
meetings from any MCP endpoint that serves transcripts. millpond’s
folder drop takes a file dropped in a watched folder as one capture,
keyed by the file’s content, so a file dropped twice is one capture.