Agent bridge
Give the coding agent you already have a seat at the table.
MidMeeting can hand the live meeting straight to an agent CLI running on your own machine instead of an API key. Settings, Copilot provider, Agent bridge. The app then listens on a local connection, and any agent that can run a shell can attach, hear the room, answer what you highlight, and play the agents you armed, with everything it already knows about your repos, your notes and your tools. No key to buy, nothing leaves the machine unless your agent itself calls out.
Step 1. Open MidMeeting once.
The app installs midmeeting-bridge for you the first time it launches, and keeps the binary in step with every update after that. Nothing to download by hand, nothing to keep at the right version yourself.
| Platform | Installed to | On your PATH |
|---|---|---|
| Linux | ~/.local/share/MidMeeting/bin | symlinked from ~/.local/bin |
| macOS | ~/Library/Application Support/MidMeeting/bin | symlinked from ~/.local/bin |
| Windows | %LOCALAPPDATA%\MidMeeting\bin | added to the user PATH |
If a terminal does not find midmeeting-bridge, open a new one, since a PATH change only reaches terminals started after MidMeeting ran. Still nothing? Settings, Copilot, Agent bridge shows the exact command path.
Manual install (fallback)
The app does this for you on first launch. Use one of these only if a terminal still cannot see the command.
$ curl -fsSL https://midmeeting.com/bridge.sh | sh
It detects your platform, downloads the right binary, and puts it on your PATH as midmeeting-bridge.
On Windows, run this in PowerShell instead:
$ irm https://midmeeting.com/bridge.ps1 | iex
Or download it directly:
Or by hand: put the binary on your PATH as midmeeting-bridge and make it executable.
$ mv midmeeting-bridge-linux-x86_64 ~/.local/bin/midmeeting-bridge
$ chmod +x ~/.local/bin/midmeeting-bridge
Linux x86_64, macOS 14.4 and later on Apple Silicon, and Windows x86_64. Intel Macs are not supported yet.
Platform notes:
Linux and macOS
A Unix domain socket, default $XDG_RUNTIME_DIR/midmeeting/bridge.sock, falling back to /tmp/midmeeting/bridge.sock. macOS normally has no XDG_RUNTIME_DIR, so the path there is /tmp/midmeeting/bridge.sock.
Windows
TCP on loopback, default 127.0.0.1:47621, protected by a random token. MidMeeting writes the address, token and its process id to %LOCALAPPDATA%\midmeeting\bridge.json while the bridge is on, and deletes the file when it stops. Only loopback is ever bound, so the Windows Firewall never prompts. A wrong token makes every midmeeting-bridge subcommand exit 1 with a handshake failed error.
Custom address
Any platform can use TCP instead: enter 127.0.0.1:PORT in Settings, Copilot provider, Agent bridge, Address. On Linux and macOS the state file then moves to $XDG_RUNTIME_DIR/midmeeting/bridge.json (or /tmp/midmeeting/bridge.json).
WSL
WSL2's default NAT mode cannot reach a loopback port on Windows. Turn on mirrored networking (networkingMode=mirrored in %USERPROFILE%\.wslconfig, Windows 11 22H2 or later, then wsl --shutdown) and localhost works from inside WSL; the token file is then readable at /mnt/c/Users/<you>/AppData/Local/midmeeting/bridge.json. Claude Code and Codex also run natively on Windows in PowerShell, where this step is not needed.
Step 2. Install the skill.
A skill is a short markdown file that teaches your agent how to attach to the bridge, when to write a note, and when to stay quiet. All four agent CLIs below read the same SKILL.md format.
One command installs it into every agent CLI it finds on your machine:
$ npx skills add matpb/midmeeting-web --skill midmeeting -g
Target one agent with -a claude-code, -a codex, -a cursor or -a grok. Update later with npx skills update.
Claude Code
~/.claude/skills/midmeeting/SKILL.md
$ mkdir -p ~/.claude/skills/midmeeting && curl -fsSL https://midmeeting.com/skills/midmeeting/SKILL.md -o ~/.claude/skills/midmeeting/SKILL.md
Codex CLI
~/.codex/skills/midmeeting/SKILL.md (also read from ~/.agents/skills/)
$ mkdir -p ~/.codex/skills/midmeeting && curl -fsSL https://midmeeting.com/skills/midmeeting/SKILL.md -o ~/.codex/skills/midmeeting/SKILL.md
Cursor CLI
~/.cursor/skills/midmeeting/SKILL.md
$ mkdir -p ~/.cursor/skills/midmeeting && curl -fsSL https://midmeeting.com/skills/midmeeting/SKILL.md -o ~/.cursor/skills/midmeeting/SKILL.md
Grok Build
~/.grok/skills/midmeeting/SKILL.md (Grok also reads ~/.claude/skills)
$ mkdir -p ~/.grok/skills/midmeeting && curl -fsSL https://midmeeting.com/skills/midmeeting/SKILL.md -o ~/.grok/skills/midmeeting/SKILL.md
Once it is installed, type /midmeeting in the agent, or just say "listen to my meeting."
The full file, to read or copy by hand:
---
name: midmeeting
description: Use on "/midmeeting", "listen to my meeting", "join the meeting", "watch MidMeeting", "attach to the bridge": attaches this session to the MidMeeting desktop app's agent bridge, streams the live transcript in, answers questions asked in the app, and plays the advisors the user armed. Not for summarising a finished transcript and not for transcribing a file.
---
# MidMeeting agent bridge
MidMeeting is a local meeting recorder with a live transcript. When its copilot is set to
Agent bridge, the app hands the transcript to an agent running on the same computer instead
of a cloud key. This skill makes this session that agent. It works the same on Windows,
macOS and Linux through one command, `midmeeting-bridge`, which the app installs.
## The one rule that matters: silence
Everything you write in this chat becomes a notification on the user's screen while they
are in a call. So:
- A `tail` or `segment` line with nothing to act on produces no visible output at all. No
"no action needed", no "still listening", no summary of what was just said, no emoji,
no one-word acknowledgement.
- Answers to asks and agent turns go through `midmeeting-bridge`, never mirrored into the
chat. The app shows them.
- Write in the chat only when the user speaks to you here, when the meeting ends, or when
the bridge itself breaks and the app cannot say so.
- When in doubt, say nothing. A quiet agent is doing its job.
## Attach
1. `midmeeting-bridge status`. Exit 0 prints `connected <endpoint>`. Anything else means
MidMeeting is not running with Agent bridge selected: say so once, then stop. If the
command is missing, the path is shown in the app under Settings, Copilot, Agent bridge,
and midmeeting.com/agents explains the install.
2. Start `midmeeting-bridge tail` as a persistent background process with whatever this
agent uses for long-running monitors. Never block on it in the foreground. Read every
JSON line as it arrives:
- `{"type":"tail","lines":[{"track","text","from_ms","to_ms"}]}`: the provisional
current line, replaced on every push, within a second of a pause and at least every
5 s while someone talks. It repeats earlier words of the same line.
- `{"type":"segment","track","text","from_ms","to_ms"}`: a finalised line, sent once,
about 25 s after it was spoken.
- `{"type":"ask","id","selection":{"text"},"question"}`: the user highlighted text in
the app and asked a question.
- `{"type":"agent","id","agent","name","system","user"}`: one armed advisor's turn.
`system` is its role and rules, `user` is the transcript window.
3. Say "Listening" once, then apply the silence rule.
Track labels: `you` is the user's microphone, `them` is the computer's audio, normally the
other side of the call. Several people sharing the user's room all land on `you`, so a
track is a side of the call, not a person.
## Respond
- An `ask` is always answered, quickly, grounded in the transcript seen so far. Verify a
factual claim with your tools first when you can.
`midmeeting-bridge answer <id> "<answer>"`
A question starting with `Over the whole meeting:` is a wrap-up preset: `selection.text`
is the full transcript, and the answer may run long (a summary, action items, or a
complete HTML document when asked for one). Long answers go through a file or stdin:
`midmeeting-bridge answer <id> @/path/to/file` or `midmeeting-bridge answer <id> -`.
- An `agent` line is you playing that advisor by its `system` prompt, not by your own
taste. PASS is the default: `midmeeting-bridge answer <id> PASS`. Most turns deserve no
note. Reply with a card only when a sharp colleague in the room would interrupt: a wrong
number, a risk nobody named, a contradiction with something said earlier.
`midmeeting-bridge answer <id> '{"kind":"idea","text":"<40 words or fewer>","why":"<20 words>"}'`
with `kind` one of `claim_check`, `risk`, `question`, `idea`, `correction`. The app
still spaces cards by the advisor's chattiness; a dropped reply just clears its
thinking state. A poke from the Jump in button arrives the same way and is expected to
produce a card.
- Reply to every `ask` and `agent` id within about a minute. The app forgets a request
after 180 s.
- `tail` and `segment` lines are context, never answered.
- One agent per meeting. The bridge sends every line to every attached client, so two
attached agents both answer everything.
## Detach
When the user says the meeting is over, or the bridge goes away, stop the `tail` process
and do not leave it running. Then, if you have a memory, save a short record of the
meeting: what was decided, what you answered, what is still open. Keep it to a few lines.
## Gotchas
- The tail dies silently when the app restarts. If replies stop landing, run `status` and
start `tail` again.
- The tail cadence is a floor, not a promise. A delayed line is not a dropped connection.
- Each line you receive costs a model turn. Do not filter for more lines, and do not poll.
- From WSL, point the command at the Windows state file:
`midmeeting-bridge --state /mnt/c/Users/<you>/AppData/Local/midmeeting/bridge.json status`
(needs mirrored networking, see midmeeting.com/agents).
Step 3. Turn it on in MidMeeting.
Settings, Copilot provider.
Choose Agent bridge instead of an API key or a local model.
Start a meeting.
MidMeeting opens the bridge and waits for a watcher.
In your agent, type /midmeeting.
It attaches, starts listening, and stays quiet until it has something worth saying.
What your agent receives.
Every line from midmeeting-bridge tail is one JSON object on its own line.
| type | fields | meaning |
|---|---|---|
| ready | transport | the first line, {"type":"ready","transport":"unix"} or {"type":"ready","transport":"tcp"}, sent right after the connection is accepted (after a correct hello on TCP); midmeeting-bridge swallows it, so tail output is unchanged, and status only prints connected once it has seen it |
| tail | lines[].track, text, from_ms, to_ms | the provisional live line, replaced on every push |
| segment | track, text, from_ms, to_ms | a finalised line, sent once, 25s or more after it was spoken |
| ask | id, selection.text, question | the user highlighted text and asked a question |
| agent | id, agent, name, system, user | an armed agent's turn: system is its role prompt, user is the transcript window |
Answer an ask with midmeeting-bridge answer <id> <text>. Reply to an agent turn the same way, or with PASS, its default. Volunteer an unprompted card with midmeeting-bridge card <agent-id> <kind> "<text>". Track you is your mic, them is everyone else.
Limits.
Intel Macs are not supported yet. Linux x86_64, Apple Silicon and Windows x86_64 all work.
One agent per meeting. The bridge sends every line to every watcher, so two attached agents would both answer every question.
The tail cadence is a floor. Provisional lines update within a second of a pause and at least every 5 seconds while someone talks. Finalised segments land 25s or more after they were spoken.