Skip to main content
Glama

gifos-meet-mcp: GifOS meetings for Grok Bot

gifos-meet-mcp is an MCP server that lets Grok Bot (or any MCP client) create GifOS meetings with everything an invite needs, put a note-taking bot in them, follow the transcript live and speak through the bot.

It runs on your own computer (self-run only; there is no hosted MCP URL). It starts a headless Chromium running GifOS, installs the Meeting Bot app from the GifOS app store, and drives it. Meetings stay peer to peer between the people in them. Transcripts stay on your computer. No GifOS account, no API key, no model.

The shared parts (the bot, transcripts, Kokoro, links and invite details) are gifos-mcp-core, pinned to an exact commit. Its sibling for broadcasts is gifos-broadcast-mcp.

Requires GifOS 0.9.23b or newer, the release that ships the Meeting Bot store app (control contract version 2). Until it is live on gifos.app, point GIFOS_URL at a GifOS 0.9.23b site.

How it works

Grok Bot ──MCP (stdio)──▶ gifos-meet-mcp ──▶ headless Chromium (one profile in ~/.gifos-mcp)
   (the brain)                                └─ GifOS desktop
                                                   ├─ Meeting Bot (window.MeetingBot v2): joins, captions, speaks
                                                   └─ Offline Captions (Whisper): speech to text
  • Grok Bot is the brain. The server has no language model. On every join Meet Bot is handed respond_to_command and speak, both off (and never the old conversation_voice, llm, tts, or stt fields). Turning the microphone on and transcribing does not make the bot answer. talk:true does: it turns those two switches on so the bot answers a line addressed to it, and it hands you that line. wait_for_speech blocks until one arrives, and a talk notification carries the same line. You can still say a line of your own. With talk left off, the bot does not answer.

  • Scheduling without joining. create_meeting mints a link and returns every invite detail (title, start and end with time zone, join link, description, how guests get in, who does what, ready-to-send text). Nothing joins and nothing is sent: Grok Bot sends the invite through the user's own mail or calendar.

  • Fast replies. wait_lines returns the moment someone says something (captions are copied every 300 ms), with to_bot: true on lines addressed to the bot. say speaks a line at once.

  • Speech is Kokoro (kokoro-js 1.2.1), running in this process with its default voice af_heart; say takes an optional voice for one line. Speech to text is GifOS Whisper in the headless browser. The bot writes down each participant who is unmuted, credited by name, and never its own machine's microphone.

Related MCP server: grok-oauth-mcp

Install

You need Node.js 20 or newer and Google Chrome or Microsoft Edge (see The browser below).

npx -y github:nwcnwc/gifos-meet-mcp

npx with a github: address downloads the package through git. Install git first.

or from a clone:

git clone https://github.com/nwcnwc/gifos-meet-mcp.git && cd gifos-meet-mcp
npm install --ignore-scripts
node bin/gifos-meet-mcp.js            # stdio
node bin/gifos-meet-mcp.js --http     # or streamable HTTP on http://127.0.0.1:19520/mcp

Install scripts are not needed and should be off. This package and gifos-mcp-core have none. Three dependencies of kokoro-js do: onnxruntime-node would download CUDA libraries from GitHub on Linux x64, sharp checks for a system libvips, protobufjs checks its version. The CPU build of ONNX Runtime and sharp's prebuilt binary ship inside the packages, so --ignore-scripts loses nothing. The plugin's .mcp.json sets npm_config_ignore_scripts=true and ONNXRUNTIME_NODE_INSTALL_CUDA=skip.

The browser. The server drives the browser already on your computer: GIFOS_CHROME if set, else Google Chrome, else Microsoft Edge, else a Chromium that npx playwright install chromium installed earlier. It never downloads or installs a browser. With none of these it stops and says what to install.

Grok Bot setup

As a plugin, this repository has .grok-plugin/plugin.json, .mcp.json and skills/gifos-meet/SKILL.md. By hand, add a local (stdio) MCP server:

{
  "mcpServers": {
    "gifos-meet": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "git+https://github.com/nwcnwc/gifos-meet-mcp.git#40574d39bd0e556374dbe4c6b11f3d88b2786f06"],
      "env": { "npm_config_ignore_scripts": "true", "ONNXRUNTIME_NODE_INSTALL_CUDA": "skip", "GIFOS_URL": "https://gifos.app" }
    }
  }
}

That pin is the same commit as .mcp.json. npx github: needs git.

The server warms up as soon as Grok Bot starts it (about 10 seconds, plus first-run downloads), so the first join does not wait. It must be running at meeting time for a scheduled join: run it on an always-on machine.

--http [port] listens on 127.0.0.1 only, checks the Host header, and requires Authorization: Bearer <token> when GIFOS_MCP_HTTP_TOKEN is set.

Endpoints, downloads and credentials

What

Where

When

Size

GifOS site

GIFOS_URL, default https://gifos.app

every start

—

GifOS relay

GifOS's default relay, or GIFOS_RELAY

while in a meeting (it only introduces peers)

—

Meeting Bot and Offline Captions apps

the GifOS store on GIFOS_URL (signed)

first start

small

Whisper model

through the Offline Captions app

first transcription

about 77 MB

Kokoro weights

https://huggingface.co/onnx-community/Kokoro-82M-v1.0-ONNX at revision 1939ad2a8e416c0acfeecc08a694d14ef25f2231, or the mirror in GIFOS_KOKORO_URL

first start, kept in GIFOS_MCP_HOME/kokoro

about 92 MB; each file is checked against its pinned SHA-256

npm packages

the npm registry and GitHub (gifos-mcp-core)

install

—

Credentials. The only secret this server holds is the bot's own name and password, which open Meeting Bot's admin meeting. They are generated once into GIFOS_MCP_HOME/bot.json (mode 0600), or come from GIFOS_BOT_NAME/GIFOS_BOT_PASSWORD. A host password passed to create_meeting is used for that call only; a room password passed to schedule_meeting or join_meeting is stored in schedule.json (mode 0600) so a restart can rejoin, and is never returned. The server reads no other secret, sends no telemetry, and never sends email or calendar invites.

How the bot looks. The operator chooses the bot's name and picture: GIFOS_BOT_NAME and GIFOS_BOT_PICTURE in the server's env, or the set_bot_profile tool, which Grok Bot can call. The picture is read from a file on this computer and kept in GIFOS_MCP_HOME/bot-picture.json (mode 0600); it is sent to rooms like any person's picture and nowhere else.

Environment variables

Variable

Default

What it does

GIFOS_URL

https://gifos.app

The GifOS site. It must be 0.9.23b or newer.

GIFOS_RELAY

GifOS default

A custom relay (wss://…), added to meeting links.

GIFOS_BOT_NAME

generated

The name people see on the bot's tile (3 to 40 characters). Set alone, it keeps the stored password.

GIFOS_BOT_PASSWORD

generated

The bot's password (the secret half). A bot.json that cannot be read is kept as bot.json.bad-<ms> and a new pair is generated.

GIFOS_BOT_PICTURE

none

Path to the bot's picture: a GIF, PNG, JPEG or WebP file, at most 256 KB. Rooms show it on the bot's tile like anyone's picture.

GIFOS_STT_APP

offline-stt-whisper

The store app for speech to text. none turns transcription off.

GIFOS_MCP_HOME

~/.gifos-mcp

Browser profile, bot credential, meetings.json, schedule.json, transcripts, events.

GIFOS_HEADLESS

1

0 shows the browser windows.

GIFOS_CHROME

Chrome, then Edge

A Chrome or Chromium binary to use instead.

GIFOS_TIMEOUT_MS

120000

How long to wait for GifOS steps such as joining.

GIFOS_MCP_HTTP_TOKEN

none

Bearer token for --http.

GIFOS_MCP_LAZY

0

1 starts the browser on the first tool call.

GIFOS_MCP_DEBUG

0

1 logs the GifOS console to stderr and adds caption state to status.

GIFOS_MCP_SHOTS

none

A folder for screenshots of the bot's screens.

GIFOS_TRANSCRIPT_POLL_MS

300

How often captions are copied from Meet Bot into the lines.

GIFOS_TTS_ENGINE

kokoro

kokoro (in this process) or none.

GIFOS_TTS_VOICE

af_heart

Kokoro's default voice for every line.

GIFOS_TTS_APP

empty

A GifOS store speech app instead of Kokoro in this process.

GIFOS_KOKORO_URL

https://huggingface.co

A mirror with the Hugging Face layout for the Kokoro weights. The pinned revision and hashes still apply.

GIFOS_TTS_URL, GIFOS_STT_URL

empty

HTTP stand-ins for speech and captions (testing). This process calls them; the page does not.

GIFOS_MAX_MEETINGS

4

Seated meetings at once. A join over the cap is refused; a scheduled join waits.

GIFOS_WORKERS

1

Stage B. More than 1 makes this process a supervisor and runs each Meet Bot in its own child process and Chromium. Worker 0 keeps the bot name and profile-bot. Worker n is its own bot, named <name>-wn, with profile-bot-wn. Lines that bot speaks in its room are stored as the bot's spoken lines under that name, not as speech from a person. A meeting stays on the worker that joined it. If a worker stops, its meetings go back to scheduled and the clock rejoins any order still in its window. A meeting with no order (join_meeting with no password, or start_meeting) is rejoined on the next clock tick too, unless end_meeting is called on it first. A room is joined once at a time: a clock tick and a start_meeting for the same room share one join, and end_meeting during that join leaves the seat as soon as it lands; if that leave fails, the meeting is live again on that seat with transcribing: false and raises one meeting.error ("The bot could not leave the room; call end_meeting again."), so a second end_meeting reaches it. A join that lands but whose transcription will not start leaves that room again and fails (the clock tries again on its next tick), so the bot is never seated twice in one room; if that leave fails too, the meeting stays live with transcribing: false and raises one meeting.error, and unmute or end_meeting reaches that seat. A worker that stops answering a heartbeat for 30s is killed and handled the same way, and so is one that has not finished booting (for example a stalled first download of the Kokoro weights, which the restart resumes) within 5 × GIFOS_TIMEOUT_MS; the join waiting on it goes to the next worker. A worker that keeps dying waits 1s, 2s, 4s, up to a minute before each restart, and joins (and the browser warm-up) go to another worker meanwhile; status shows restart_in_ms on that worker. A worker that is running but whose browser will not start is treated the same way: the join that found it out goes to the next worker, joins skip it for 1s, 2s, 4s, up to a minute before it is tried again, and status shows start_retry_in_ms and the start error on its row. A worker process that dies during a join (its browser goes with it) does not fail that join: it goes to the next worker with a free seat, once, so a room that takes down every worker it reaches costs at most two workers a restart. The clock does not join such a room again at once: it raises one meeting.error ("The room crashed the bot; trying again in N min.", with retry_in_ms) and waits 1 minute, then 2, 4, up to 30 between tries while the order is in its window, so the meetings it knocked off get their seats back and keep them. A start_meeting or join_meeting by hand waits on the same clock: on a room in its wait it fails at once ("The room crashed the bot; it can be tried again in N min.") without walking in, and a hand join that takes down every worker it reaches starts that wait too. The wait is kept in crashes.json under GIFOS_MCP_HOME (mode 0600), so a supervisor restarted within it still waits; an unreadable crashes.json is moved aside like schedule.json. While no worker has a free seat, an order due to join waits: it goes to waiting_for_capacity and raises one schedule.waiting event with reason: "worker" ("capacity" when the cap is reached), not an error every clock tick; if no seat frees before its end it is missed for capacity. A call to a worker that is still alive fails after 60s with no answer (a browser start or a join after 5 × GIFOS_TIMEOUT_MS); a join that ran out of time keeps its seat until the worker answers it (the bot may still be walking into the room; status shows late_joins on that row), so the worker is not given more rooms than its budget; one that lands after that is left at once, so no seat is held that nobody can reach, and one that fails frees the seat. A join that still has not answered one more join window later is checked against the worker's own Meet Bot room list: a room the supervisor does not hold is left (as above), and the seat is freed, so a join that never answers does not hold a seat until the worker dies. If the leave of a join that landed late fails, the room keeps its seat and is left again every 10s until it works; status shows stray_rooms on that worker's row meanwhile. A leave_meeting or end_meeting whose leave fails or runs out of time keeps the meeting live on its worker (the bot may still be in the room), so calling it again reaches the room; a late leave that lands, or Meet Bot answering that it no longer holds the room, frees the seat. A leave that still has not answered one more call window later is checked against the worker's Meet Bot room list: if the room is gone, the seat is freed; if the bot is still listed there, the seat stays taken. After a late leave landed or that check freed the seat, the next leave_meeting or end_meeting on that meeting ends it. status asks every worker at once and waits at most 3s for each; a worker that does not answer in time shows error on its row while the rest of status comes back. If the supervisor itself dies without shutting down (SIGKILL, out of memory), each worker sees its channel close, closes its Chromium, and exits, so no bot is left in a room that nothing can reach; a worker still booting (for example fetching the Kokoro weights) exits at once too, and so does one told to close while booting, keeping its part file for the next start. Each worker runs with a TMPDIR of its own, gifos-mcp-<tag>-w<n> under the supervisor's (the tag is named by GIFOS_MCP_HOME), emptied before each start and removed when the worker exits or close ends it, so the playwright-artifacts-* folder a worker killed under its Chromium could not remove does not pile up in /tmp; a worker leaving because its supervisor died removes its own. set_voice goes to every running worker at once; a worker that refuses it, misses it, or restarts gets the same settings again before its next join, and a running worker that refused is asked again every 10s until it takes them; meanwhile status shows voice: "pending" on its row.

GIFOS_WORKER_ROOMS

cap / workers, rounded up

Rooms per worker.

Tools

Meeting tools (this server):

Tool

Arguments

Returns

create_meeting

name, start?, end?, timezone?, description?, room_password?, admin_password?, town_hall?, host_name?

{ meeting_id, link, host_runs_room, invite }. Nothing joins, nothing is sent. invite has title, start/end ({iso, timezone, local}), join_url, description, admit, roles, text, calendar. admin_password (the human host's) makes a room they run; it is used for this call only and never stored or returned. The room password is in the invite text, never in the link.

start_meeting

meeting_id, room_password?, talk?

The bot joins now and starts transcribing. Turning the microphone on and transcribing does not make the bot answer. talk:true does.

join_meeting

link, password?, topic?, instructions?, talk?

The bot joins someone else's GifOS meeting now. instructions (optional, plain text, at most 4000 characters) is the owner's goal for this meeting, returned by meeting_status; without it the bot only transcribes. Turning the microphone on and transcribing does not make the bot answer. talk:true does: the bot answers lines addressed to it, and wait_for_speech returns each of those lines. With talk left off, the bot does not answer.

wait_for_speech

meeting_id, timeout_ms?

Blocks until a line addressed to the bot arrives in a meeting joined with talk:true. Turning the microphone on and transcribing does not make the bot answer. talk:true does.

raise_hand, set_mic, set_camera

meeting_id, on

Meet Bot's hand, microphone and camera, or the gap when the app lacks the method. set_mic does not make the bot answer.

Shared tools (from gifos-mcp-core, the same in gifos-broadcast-mcp):

Tool

Arguments

Returns

wait_lines

meeting_id?, since?, timeout_ms? (≤ 30000), kinds?

Returns as soon as there is a line after since, or after timeout_ms. Pass next back as since. Lines addressed to the bot have to_bot: true.

tail_lines, tail_transcript

meeting_id?, since?, kinds?

The lines after since without waiting. Each line is {seq, ts, speaker, text, kind}; kind is speech, chat or spoken.

get_transcript

meeting_id

Plain text, one speaker: words line per caption, live and after the meeting.

say

meeting_id, text, voice?

Meet Bot says the line out loud now (Kokoro).

set_bot_profile

name?, picture_path?, clear_picture?

Sets how the bot looks: the name on its tile and its picture (GIF, PNG, JPEG or WebP, at most 256 KB). Both are kept in GIFOS_MCP_HOME for later starts. The picture applies to rooms joined afterwards. A new name is refused while the bot is in a room (end it first). GIFOS_BOT_NAME and GIFOS_BOT_PICTURE, when set, win again at the next start.

send_chat, share_content

meeting_id, text

A chat line as the bot (up to 2000 characters).

get_meeting_state, snapshot

meeting_id

Who is here; a PNG of the bot's page.

mute, unmute

meeting_id

Stop or restart note-taking.

leave_meeting, end_meeting

meeting_id

Saves the transcript, then the bot leaves. Other people stay.

schedule_meeting

link, room_password, start, end?

Stores the join order, including the room password, in schedule.json (mode 0600, written to a temp file then renamed, so a save cut short keeps the last good file; a file that cannot be read at start is kept as schedule.json.bad-<ms> and not overwritten). The bot joins one minute before start. A join that fails (not a crash, not a full pool) is tried again on every clock tick while the window is open, and raises one meeting.error ("The room could not be entered; trying again.") and one schedule.due for that order, not one per tick; after a join works, the next failure raises one again. Those events, and schedule.waiting, are once per window: an order moved to a new start or end (an order waiting for capacity goes back to upcoming) raises them again in its new window. end defaults to start plus 8 hours. The password is not returned.

list_schedule, update_schedule, cancel_schedule, import_schedule

see the schemas

Join orders. No passwords in results. schedule_meeting, update_schedule and import_schedule take an optional instructions (the owner's goal and questions for that meeting, at most 4000 characters, kept in schedule.json); it comes back in list_schedule, meeting_status and the schedule.due and meeting.joined events. The server never runs it. Recipe: daily check-ins run by the bot.

list_meetings, meeting_status, meetings_report, status, capacity_status

—

State, people, line counts, capacity. No passwords.

tail_events

since?

Connector events, including capacity.near, capacity.reached, and capacity.cleared. They are appended to GIFOS_MCP_HOME/events.jsonl (mode 0600); a torn last line left by a process killed mid-write is skipped and ended at the next start, so later events stay readable and no seq is handed out twice.

The resource gifos://meeting/{id}/transcript is the live transcript as newline-delimited JSON; subscribe for notifications/resources/updated.

Example: a 5 PM meeting

The user says: "Set up a meeting with Alice and Bob at 5 PM, take notes, and send me a summary."

  1. Grok Bot calls create_meeting({ name: "Demo", start: "2026-10-20T17:00", timezone: "America/Los_Angeles", room_password: "<made up>" }) and gets the link and invite.

  2. Grok Bot sends invite.text to Alice and Bob from the user's mail, after the user approves.

  3. Grok Bot calls schedule_meeting({ link, room_password, start }). The bot joins at 16:59.

  4. During the meeting Grok Bot loops on wait_lines for notes. To have the bot answer when someone says its name, pass talk: true on start_meeting or join_meeting and loop on wait_for_speech. Turning the microphone on and transcribing does not make the bot answer. talk:true does. A to_bot question is answered with say when you want words of your own.

  5. Afterwards Grok Bot calls end_meeting, reads get_transcript, writes the summary and, with the user's approval, sends it.

Privacy and security

  • Everything runs locally. The browser, the bot, one shared speech-to-text engine, and the transcripts are all on your machine. Media goes peer to peer between participants. GifOS's relay only helps peers find each other.

  • Consent is visible. A GifOS meeting is always written down, and every participant's header always shows 📝 Transcribing, also when the call is calm. The bot is a tile labelled 🤖 bot for as long as it is in the meeting. mute stops the bot writing the meeting down; end_meeting takes it out.

  • The bot never uses your microphone or camera. It joins with no camera, Meeting Bot never transcribes its own machine's microphone, and its browser is fed a silent fake microphone anyway.

  • Only one secret. The bot name and password derive Meeting Bot's secret admin meeting, which can command the bot from another device (Meeting Bot's CONTROL mode). Keep GIFOS_MCP_HOME/bot.json private (it is mode 0600), or pass the pair through environment variables. Anyone with the pair can command the bot.

  • Meeting links are capabilities. Anyone with a link can join that meeting, so share links only with the people you invite.

  • Transcripts are stored in GIFOS_MCP_HOME/meetings.json (mode 0600) so they survive restarts. Delete the file to forget them. It is written to a temp file then renamed, so a save cut short keeps the last good file; a file that cannot be read at start is kept as meetings.json.bad-<ms> (mode 0600, logged) and not overwritten. Delete any *.bad-* file too (a bot.json.bad-* holds an old bot password). A join whose save fails (disk nearly full) still holds its seat and reads its captions; the failure is logged and the next save writes it. The same holds for schedule.json: a clock tick whose save fails still seats, waits and ends its orders, logs the failure once until a save works, and the next save writes their phases. An end_meeting (or a clock leave) whose saves fail still reports the leave, raises meeting.left, and keeps the meeting ended and its order left_early or ended in memory, so no tick seats the bot again. A join_meeting with a password whose schedule.json save fails still reports the join and raises meeting.joined; its order (with the room password) is kept live in memory and the next save writes it. A mute, unmute or get_transcript whose meetings.json save fails still answers with what the bot did (muted, listening, the transcript); memory keeps it and the next save writes it. A transcript line whose append to transcripts/<id>.jsonl fails keeps every caption line of that snapshot (and its line.* event), send_chat and say still report what Meet Bot sent, and the kept lines are written in order at the next append that works. A file whose last line was torn is ended before the next line.

  • No model, no key. There is no language model in this server and no model URL or API key is read. The assistant that calls the tools writes every word the bot says, except a meeting joined with talk: true: that hands Meet Bot respond_to_command and speak, both on, so it answers a line addressed to it. MeetingBot.setVoice receives { respond_to_command: false, speak: false } on every join first, and never the old conversation_voice, llm, tts, or stt fields. Turning the microphone on and transcribing does not make the bot answer. talk:true does. With talk left off, the bot does not answer.

  • No outgoing messages. The server never sends email, calendar invites or anything else. Grok Bot does that through your own connectors, and you approve each send. Follow-up after the meeting is Grok Bot's job.

  • HTTP mode binds to 127.0.0.1, checks the Host header (DNS-rebinding protection), and can require a bearer token.

Troubleshooting

Symptom

Fix

The GifOS store at … has no "meeting-bot" app

That GifOS is older than 0.9.23b. Set GIFOS_URL to a 0.9.23b or newer site.

Meeting Bot did not start: A bot with this name and password is already running…

Another server (or a Meeting Bot window) uses the same name and password. Give this one its own GIFOS_MCP_HOME or GIFOS_BOT_NAME/GIFOS_BOT_PASSWORD.

get_transcript stays at (no transcript lines yet)

Somebody has to speak with their mic on. The first transcription downloads the Whisper model (about 77 MB).

Kokoro: … does not match its pinned SHA-256

A download was cut or a mirror served other bytes. The file was removed; start again.

No Chrome or Edge on this computer

Install Google Chrome, or run npx playwright install chromium once, or set GIFOS_CHROME. The server never downloads a browser.

A scheduled join did not happen

The server was not running, or the machine was asleep.

Anything else

GIFOS_HEADLESS=0 shows the browser; GIFOS_MCP_SHOTS=/tmp/shots saves screenshots.

The e2e runner (test/e2e/run.js) serves a local site unless GIFOS_URL or E2E_GIFOS_URL is already set; then it uses that site and does not start its own.

Testing instructions for marketplace reviewers

1. Unit tests (no network, no browser except one local page, about a minute).

git clone https://github.com/nwcnwc/gifos-meet-mcp.git && cd gifos-meet-mcp
npm install --ignore-scripts
npm test

They run every tool over a real MCP client/server pair with a fake bot, the --http transport through the real binary, the worker supervisor, and the real Meeting Bot app bundle in a local page, which checks that the bot answers nothing on its own and speaks exactly the line say gives it.

2. Try it live (needs GifOS 0.9.23b or newer). Add the server to Grok Bot, then ask "Create a GifOS meeting called Demo and start it." Open the link in a browser, turn your mic on and say something. Ask "What did I just say?" (Grok Bot uses wait_lines or get_transcript), then "Say hello in the meeting." and "End the meeting."

3. Full end-to-end test against a local GifOS (what the maintainers run).

git clone --branch release/0.9.23 --single-branch https://github.com/nwcnwc/gifos-app.git ../gifos-app
git clone https://github.com/nwcnwc/gifos-apps-source.git ../gifos-apps-source
GIFOS_APP_DIR=../gifos-app MEETING_BOT_SRC=../gifos-apps-source/meeting-bot \
E2E_STT=synthetic npm run test:e2e

Leave E2E_RELAY unset. The test uses the GifOS site's own relay, and a client on this computer can use the live relay.

It serves the GifOS checkout on 127.0.0.1:19510, spawns this server over stdio, creates a meeting, lets the bot join, has a second headless browser ("Alice") speak, and checks the transcript, wait_lines, say, chat, mute, end and the quiet bot. E2E_STT=whisper with E2E_SPEECH_WAV uses the real Whisper model.

License

Copyright (c) 2026 Crowd Concepts, Inc. All rights reserved. See LICENSE. GifOS, Meeting Bot and Kokoro are separate projects with their own licenses.

Available Tools

10 tools
create_meetingCreate a GifOS meetingA

Creates a new GifOS meeting link. Nothing joins yet: share the link (for example in a calendar invite the user approves), then call start_meeting at meeting time. start_time is stored as given, for your own scheduling; this server does not schedule anything.

ParametersJSON Schema
NameRequiredDescriptionDefault
topicYesWhat the meeting is about, e.g. "Demo meeting".
start_timeNoWhen it should start, e.g. "2026-10-15T17:00:00-07:00". Informational only.

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden and it does useful work: it discloses that no one joins on creation, that start_time is stored verbatim and never triggers scheduling, and that the output is a shareable link. It does not mention auth/permission requirements or limits, but the non-obvious semantics are covered well.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core action and then the sequencing caveat and the scheduling caveat. Every sentence carries distinct information; nothing repeats the title or schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter creation tool with no annotations and no output schema, the description covers what is produced (a link), how it is consumed, and the next tool in the flow. There is no meaningful gap an agent would need filled to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description goes beyond the schema's terse "Informational only" for start_time by spelling out the consequence: it is stored as given for the agent's own scheduling and the server never schedules. That added implication is real value over the field text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ("Creates a new GifOS meeting link") and immediately clarifies the non-obvious distinction from a meeting actually running ("Nothing joins yet"), which separates it from siblings like start_meeting and join_meeting. An agent can pick this tool without reading any other schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly prescribes the workflow: create the link, share it (e.g. in a calendar invite the user approves), then call start_meeting at meeting time. It also states what this tool does NOT do (schedule anything), which is a clear exclusion rather than implied usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

end_meetingEnd the meeting for the botA

Saves the transcript, then the bot leaves. Other participants can stay; GifOS meetings have no owner who can close them for everyone.

ParametersJSON Schema
NameRequiredDescriptionDefault
meeting_idYesThe meeting_id returned by create_meeting or join_meeting.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does reasonably well: it discloses two concrete side effects (transcript is saved before exit; the bot leaves while others stay). It omits the safety profile an agent might want — whether the call is idempotent, what happens on an already-ended or invalid meeting, and whether it requires the bot to be in the meeting.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, no filler. The primary effect (transcript saved, bot leaves) is front-loaded and the clarifying scope constraint follows immediately.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter, no-output-schema tool the description covers what the agent needs to know about the action and its blast radius. It falls just short on failure/edge-case behavior (already-ended meetings, invalid or other-user meeting_id) and on whether the saved transcript can be retrieved afterwards via get_transcript.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

One required parameter at 100% schema description coverage, and the schema already explains meeting_id's provenance (create_meeting or join_meeting). The description adds nothing about the parameter, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (end the meeting by saving the transcript and having the bot leave) and immediately scopes it: only the bot exits, other participants remain. It also preempts a wrong mental model ("no owner who can close them for everyone"), which separates it from start_meeting/join_meeting and from any generic 'close meeting' assumption.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated: an agent can infer this is the way to remove the bot from an active meeting it has joined. There is no explicit when-to-use vs when-not-to-use guidance and no named alternative (e.g., what to do instead if you want to keep the bot but stop recording). Minimum viable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_transcriptGet the meeting transcriptA

Returns the transcript as plain text, one "speaker: words" line per caption. Works while the meeting is live and after end_meeting.

ParametersJSON Schema
NameRequiredDescriptionDefault
meeting_idYesThe meeting_id returned by create_meeting or join_meeting.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description discloses output format (plain text, speaker-prefixed lines) and availability (live and post-meeting). However, it omits permissions, error behavior, rate limits, and whether the transcript is complete or partial. Some behavioral context is provided, but the full burden is not met.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the return format and followed by availability. No filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple single-parameter read tool with no output schema and no annotations, the description covers the essential call context: what is returned, its format, and when it can be used. It could mention invalid meeting_id handling or transcript completeness, but those are minor gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, and the single required parameter meeting_id is fully documented in the schema. The description does not add parameter-level meaning, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Returns') and resource ('the transcript') and defines the output format as plain text with 'speaker: words' lines. No sibling tool provides transcripts, so it is inherently distinguishable; it also references end_meeting to clarify temporal scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clearly states the tool works both while the meeting is live and after end_meeting, giving the agent temporal context for when it can be called. It does not enumerate when-not or alternative approaches, but no sibling tool offers transcript retrieval, so the context is sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

join_meetingJoin an existing GifOS meeting by linkA

The Meeting Bot joins a GifOS meeting someone else created (a /run.html#v=… or /meet/… link) and starts transcribing. Returns a meeting_id for the other tools.

ParametersJSON Schema
NameRequiredDescriptionDefault
linkYesThe GifOS meeting link.
topicNo
passwordNoThe meeting password, if the meeting has one.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full disclosure burden. It usefully reveals two non-obvious behaviors: a bot joins on your behalf and transcription begins, and a meeting_id is returned for downstream calls. It does not state auth requirements, whether the join blocks or is async, or what happens on a bad/expired link.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences: the action and its precondition come first, the return value second. No filler, no restatement of the tool name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Since there is no output schema, the description usefully compensates by explaining that a meeting_id is returned. For a low-complexity 3-parameter action the remaining gap (error/edge behavior, password prerequisites) is minor but real.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 67% (topic has no description), and the description adds no field-level guidance. However, it does supplement the link parameter by naming the accepted formats (/run.html#v=…, /meet/…), which the schema's bare 'The GifOS meeting link.' does not convey.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('joins a GifOS meeting... and starts transcribing') and explicitly scopes it to meetings 'someone else created', which cleanly separates it from sibling create_meeting/start_meeting. The 'bots joins' framing also identifies the actor.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'someone else created' gives a clear condition for using this tool versus hosting your own meeting, and the link formats given imply what input to supply. It stops short of naming the alternative sibling tools (create_meeting/start_meeting) as explicit exclusions, so it is not a full when/when-not statement.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_meetingsList meetingsA

Meetings this server created or joined, newest first, with their state (scheduled, live, ended).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It usefully discloses ordering ('newest first') and the state vocabulary ('scheduled, live, ended'), which is genuine behavioral context about the payload. It says nothing about pagination, result limits, auth requirements, or whether the list is scoped to the caller.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with no filler; scope, ordering, and state are front-loaded in one pass. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter read tool with no output schema, the description covers the essentials: what is listed, in what order, and the state values returned. The main remaining gap is unbounded-result behavior (pagination or truncation), which matters for a list tool but is a single omission.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate and the baseline of 4 applies. No parameter claims are made that could mislead.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb+resource ('Meetings') and pins down scope ('this server created or joined'), ordering ('newest first'), and the returned state field. It reads as a noun phrase rather than an action statement, and it never names a sibling, but no other tool in the set enumerates meetings, so an agent can still place it.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: an agent can infer this is the enumeration tool, and the scope qualifier ('this server created or joined') hints at when results apply. There is no explicit when-to-use, no exclusion, and no routing against adjacent tools such as 'status' or 'get_transcript'.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

muteMute the bot (stop listening)A

Stops the bot transcribing this meeting; the transcribing chip goes away. The bot never sends audio, so this is the only kind of mute it has.

ParametersJSON Schema
NameRequiredDescriptionDefault
meeting_idYesThe meeting_id returned by create_meeting or join_meeting.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does meaningful work: it discloses the primary effect (transcription stops), a side effect (the transcribing chip disappears), and a non-obvious behavioral fact that the bot never sends audio. It omits reversibility and permission requirements, but the core behavior is clear.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with the core effect front-loaded and zero filler. The second sentence resolves a genuine ambiguity about whether other mute variants exist, so every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter, annotation-free tool with no output schema, the description is nearly sufficient: the effect and scope are covered, and the 'no audio' clarification prevents misreading. Only the reversibility/permission story is left to inference via the unmute sibling.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

A single required parameter with 100% schema description coverage, so the schema already documents meeting_id fully. The description adds no syntax or scoping detail about the parameter, making the baseline 3 correct.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific action and its effect on the resource: it stops the bot transcribing this meeting. That distinguishes it from read/status siblings, but it never names the obvious counterpart 'unmute', so the differentiation is left implicit rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated – an agent can infer this is an in-meeting action keyed by meeting_id that halts transcription. It adds a mild clarification ('this is the only kind of mute it has') but gives no explicit when-to-use/when-not guidance or pointer to unmute for reversal.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

share_contentShare text or a link into the meetingA

Posts text (an agenda, a link, a summary) into the meeting chat as the bot. Screen sharing is not available: the bot has no screen or camera.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYesWhat to post into the meeting chat (up to 2000 characters).
meeting_idYesThe meeting_id returned by create_meeting or join_meeting.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden but discloses two useful traits: the post appears as the bot, and screen sharing/camera is not available. It omits whether the bot must already be in the meeting, whether the meeting must be active, and any permission or rate-limit behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with no filler; the primary action is front-loaded and the capability caveat follows immediately. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter write tool with full schema coverage and no output schema, the description covers the essential action and the one surprising constraint (no screen sharing). Nothing critical to correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters are already documented (including the 2000-character cap and where meeting_id comes from). The description only loosely reinforces this by naming example content types, adding little beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Posts text ... into the meeting chat as the bot') with concrete examples of the payload (agenda, link, summary). It also disambiguates from an adjacent capability by stating that screen sharing is unavailable, so an agent can tell it apart from other meeting actions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use it by listing typical payloads (agenda, link, summary), but it never names alternatives or states prerequisites such as needing to have joined the meeting first. Usage is inferable rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

start_meetingStart a meeting (the bot joins and transcribes)B

The headless Meeting Bot joins the meeting created with create_meeting and starts transcribing. Participants see a 🤖 bot badge and a transcribing chip.

ParametersJSON Schema
NameRequiredDescriptionDefault
meeting_idYesThe meeting_id returned by create_meeting or join_meeting.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It usefully discloses the visible side effects (participants see a robot badge and a transcribing chip) and that the bot is headless, but says nothing about idempotency, permissions, failure modes, or what happens on a meeting already in progress.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with the action front-loaded and the prerequisite/observable effects following. No filler; the UI-detail sentence earns its place by describing visible behavior.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so return values need not be explained, but as a state-changing start operation with no annotations the description should say more about re-invocation behavior, error conditions, or required permissions. Adequate but with a clear gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single meeting_id parameter is fully documented in the schema, including its origin. The description adds no parameter-level detail beyond what the schema already states, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a concrete action: the headless Meeting Bot joins the meeting and begins transcribing. It implicitly distinguishes itself from create_meeting by naming it as the prerequisite and from join_meeting by specifying that a bot (not a user) joins, though it never names join_meeting directly as the alternative.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The prerequisite is clear — the meeting must already exist via create_meeting. However, there is no explicit guidance on when to choose this over join_meeting, nor what happens if the bot is already in the meeting or the meeting has ended; usage is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

statusConnector statusA

Is the headless GifOS browser up, which GifOS it uses, and which meetings the bot is in right now.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It implicitly signals a side-effect-free read (framed as questions about current state) and enumerates what is inspected, which is useful. It says nothing about auth requirements, behavior when the browser is down, or cost/latency, so meaningful gaps remain.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with no filler, front-loading the primary question (is the browser up) before the secondary detail (which GifOS, which meetings). Every clause conveys a distinct field of information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Because there is no output schema, the description must convey return content, and it does so by enumerating the three values returned. For a zero-parameter read-only diagnostic this is close to sufficient; only edge behavior (e.g., what is returned when the browser is down) is unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate; the baseline for a parameterless tool applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names three concrete things the tool reports: GifOS browser liveness, which GifOS is in use, and which meetings the bot currently occupies. That is a specific, checkable answer rather than a restatement of the name 'status'. It does not, however, explicitly separate itself from the sibling list_meetings, which also surfaces meeting membership.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'right now' implies a live snapshot and therefore a polling/diagnostic use case, but the description never states when to call this versus list_meetings or any prerequisite. Usage is inferable rather than stated, which matches the 'implied usage' level.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unmuteUnmute the bot (listen again)B

Turns transcription back on for this meeting.

ParametersJSON Schema
NameRequiredDescriptionDefault
meeting_idYesThe meeting_id returned by create_meeting or join_meeting.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden; it does clarify the semantic effect (transcription resumes), which goes beyond the bare name 'unmute'. It says nothing about permissions, idempotency, whether other participants are affected, or what happens if the bot was never muted.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler. It is proportionate to a one-parameter toggle and wastes nothing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple toggle with one fully documented parameter and no output schema, the definition is largely sufficient. It falls short only on operational context such as whether the meeting must be in progress or whether unmuting is reversible.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single parameter is fully documented there, including its provenance (returned by create_meeting or join_meeting). The phrase 'for this meeting' only restates the schema, adding no new syntax or format detail, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a concrete action and target: re-enabling transcription for a meeting. Combined with the name 'unmute' and its sibling 'mute', an agent can identify this as the inverse toggle without opening the schema. It does not, however, explicitly name the sibling it pairs with.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no exclusion rules, and no mention of the 'mute' counterpart or any prerequisite (e.g. meeting must be active). The agent must infer usage entirely from the name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 10 tool updatesv0.1.0
    • First observedcreate_meeting
    • First observedend_meeting
    • First observedget_transcript
    • First observedjoin_meeting
    • First observedlist_meetings
    • First observedmute
    • First observedshare_content
    • First observedstart_meeting
    • First observedstatus
    • First observedunmute

TDQS

A3.9/5.0

Scored across 10 tools

Disambiguation5/5

Each tool targets a distinct action, and the descriptions actively disambiguate the subtle create_meeting vs start_meeting vs join_meeting distinction (create only makes a link, start joins your own, join handles someone else's). mute/unmute and share_content/get_transcript are obviously separable. No two tools appear to do the same thing.

Naming Consistency4/5

The set is dominated by a clean snake_case verb_noun pattern (list_meetings, create_meeting, start_meeting, join_meeting, share_content, get_transcript, end_meeting). The single-word tools mute, unmute, and status are minor deviations from that pattern but remain clear and readable.

Tool Count5/5

Ten tools is well within the ideal range and each one covers a real stage of the meeting-bot lifecycle. Nothing feels padded or redundant; the surface is tightly scoped to the server's purpose.

Completeness4/5

The lifecycle is largely covered: create, start, join, list, mute/unmute, share, retrieve transcript, end, and status. Minor gaps remain (e.g. no tool to fetch or delete a single meeting, and no way to remove/inspect an ended meeting beyond the transcript), but core workflows are usable end to end.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Open-source meeting bot API with MCP server. Search, retrieve, and analyze meeting transcripts from Google Meet, Zoom, and Microsoft Teams directly from your AI tools.
    1 npm
    2,892
    Apache 2.0
  • F
    license
    Not graded
    quality
    D
    maintenance
    Automates Grok web interface to provide chat, web search, and conversation management via MCP, supporting multiple accounts and local/remote deployment.
    -