Skip to content

eddy is designed, not built. Its design book holds the design whole.

How it works

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.