loomiomcp
An MCP server for Loomio that lets an AI client read and write discussions, polls, comments and memberships, and analyse member participation.
Read discussions and polls: fetch one by id/key, or list a group's discussions/polls with status filters and pagination.
Read thread activity: fetch a discussion's event stream (comments, poll creation, votes, outcomes, reactions).
Read groups and members: list visible groups; list group memberships with roles/join state and emails for admins.
Create content: start discussions, create many poll types (proposal, poll, count, score, ranked_choice, meeting, dot_vote), and post comments.
Manage memberships: invite members by email; optionally remove absent members (dangerous, admin-only).
Analyse participation: aggregate one user's activity across groups by kind, group and month, with sample events.
Full catalog extras: search content, get thread markdown/items, participation reports, connection checks, update/delete discussions, polls and comments, and b3 instance-operator tools (deactivate/reactivate/get/list users) when configured.
Constraints: operations run as the configured Loomio API-key user; write/admin tools may be disabled in read-only mode; b3 tools are single-tenant only.
loomiomcp
Model Context Protocol server for Loomio. Lets Claude (Desktop, Code, or web Projects via Custom Connector) read and write Loomio discussions, polls, comments and group memberships — and analyse member participation — in plain English. Targets Loomio's b2 API — the canonical surface documented at /help/api2 and the namespace where the controllers live in the open-source repo — as shipped in Loomio 3.8.
Tool catalog
Every read is one upstream call unless the table says otherwise. Every
collection returns Loomio's exact total and a scope note naming
what was filtered, capped or not visible. The server also ships a
ten-line routing guide as MCP instructions, so a client knows which
tool answers which kind of question before it reads a single
description. The whole catalogue a client downloads at session start
(instructions + tools/list for the 24 full-mode tools) is about
36 KB, roughly 9 000 tokens (node scripts/catalog-size.mjs after
npm run build); the long-form guidance per tool — inputs, outputs,
cost, caveats, exact error texts — is in HOWTO.md.
Reads (always registered)
Tool | Purpose | Upstream calls |
| Key status, the account the key belongs to, its groups ( | the health probe (1 authenticated + 1 public GET); its groups body is reused |
| The connector user's member groups (pending invitations included) with the user's own | 1 ( |
| One group's full record — privacy, | 1 |
| A group's discussions, newest activity first, each joined with its thread counters ( | 1 |
| One discussion with the full body (as stored; | 1 (2 with |
| A group's polls, newest first, as SLIM rows: identity, schedule, | 1 |
| One poll with | 1 |
| Every thread the user can see across all groups, newest activity first — the cheapest "what is new" call. | 1 ( |
| One thread's structured items (comments, polls, votes, outcomes, edits) with slimmed side-loads; comment bodies, vote reasons and outcome statements come as plain text by default ( | 1 with |
| The whole thread rendered to Markdown by Loomio — front matter, body, comments, polls with results tables (Loomio applies vote visibility itself), outcomes. Best single call for a summary. | 1 with |
| Full-text search across everything visible; | 1 |
| Loomio's participation report for a group set: each user's threads, comments, polls, votes cast vs issued vs missed, outcomes, reactions, | 1 for the whole group set |
| One user's counts across groups (month-grained window) with | N + 1 for N groups (4 in flight) |
| A group's roster: ids, names, usernames, | 1 ( |
Writes (registered unless LOOMIO_MCP_READONLY=1)
Tool | Purpose | Upstream calls |
| Start a thread. Nested | 1 |
| Edit title, body (replaced), privacy, comment / reaction / concurrent-poll settings, or add recipients. | 1 |
| Soft-discard: Loomio blanks the thread and keeps the records; an admin can restore. | 1 |
| Any Loomio 3.8 poll type — | 1 (2 with |
| Edit an open poll: title, details, closing time (the next full hour ends voting within the hour), options to ADD (Loomio's PATCH replaces the set and deletes unlisted options with their votes, so the connector reads the current names first and sends the union), | 1 (2 with |
| Soft-discard a poll. | 1 |
| Comment on a thread ( | 1 (2 with a short key) |
| Replace a comment's body. | 1 |
| Soft-discard a comment. | 1 |
| Invite by email; with | 1 |
Instance-operator tools (b3; registered when LOOMIO_B3_API_KEY is set and not read-only)
Tool | Purpose | Upstream calls |
| Deactivate an account instance-wide (Loomio runs it asynchronously). | 1 |
| Reactivate an account and restore the memberships the deactivation revoked. | 1 |
| One account by id or linked external identity — email included. | 1 |
| Every account on the instance — emails included, unpaginated. | 1 |
The b3 secret authenticates the server, not a user: it is validated
against ENV['B3_API_KEY'] on the Loomio instance and sees every
account. get_user and list_users are therefore for single-tenant
deployments only (one organisation per Loomio instance); on a shared
instance leave LOOMIO_B3_API_KEY unset.
Deliberately not exposed
b3 update / destroy / redact users. Irreversible (destroy and redact delete or scrub personal data for good) and Loomio records no actor identity for b3 calls, so nobody could later tell which agent session did it. Deactivate / reactivate cover the operational need and are reversible.
b3 chatbots / webhooks. Group-admin configuration whose serializer returns the webhook URL and secret; nothing an AI caller needs, and a leak surface if it were readable.
The participation report's
baseandcountriessections. Instance-wide totals and per-country breakdowns; not answerable per group the way theuserssection is, and not what members see.
Related MCP server: capsulemcp
Efficiency
Loomio 3.8 exposes aggregates its earlier releases lacked; this connector uses them so every read costs as few upstream calls and bytes as the API allows.
Question | Before (0.0.11) | Now (0.0.12) |
"Which groups can you see?" |
| 1 call on the native |
"How active was user X?" |
| N + 1 calls for N groups on Loomio's participation report + one author search |
"Who is most engaged in these groups?" | Not answerable without reconstructing from polls × memberships |
|
"Read / summarise this thread" |
|
|
"What is new anywhere?" |
|
|
"Find the thread about …" | Not available |
|
Payload size is handled the same way:
Side-load profiles. Lists send
exclude_types=group parent membership reaction translation(thetopicsroot — where the thread counters live — is kept and joined client-side); shows keep the group for its name and privacy;list_threadssends compact minustag; rosters, search and thread items by baretopic_idusecompact=1, while thread items for a thread whose record is already in hand also excludediscussion(no second copy of the opening post).tagis never excluded where topic rows are read: Loomio gates the rows'tagsFIELD on it, not just the side-loaded root. Writes never carry these parameters.Slimming. Users become
{id, name, username}(+emailonly on the b3 tools); groups keep identity, privacy and counters; reactions, attachment and link-preview metadata are dropped unless asked for;list_pollsrows leave the per-voterresults[]toget_poll.Body caps with explicit flags.
description_max_chars(lists, default 1500) andbody_max_chars(thread items, default 4000) cap a record's text and mark it*_truncated: truewith the original*_chars;0omits the field (*_omitted: true),-1returns everything. An HTML body longer than its cap is first stripped of tag attributes (Loomio storestarget/relon every link and anidon every heading — 17 % of a capped plain body, over half of a link-dense one;hrefandaltstay) so the capped characters carry content.max_total_chars(thread items, default 120000) budgets the whole reply and hands backnext_offset.max_charsonget_thread_markdown(default 60000) caps the whole document from the END with top-leveltruncatedandchars;-1returns it whole and0is refused.get_*return full text.Compact JSON to the model. Tool results are serialised without indentation (measured 10–37 % smaller than pretty-printed over the 3.8.1 fixtures);
LOOMIO_MCP_PRETTY_JSON=1restores indentation for a human reading a stdio session.Exact totals. Every collection surfaces Loomio's
meta.totalastotal, so "how many" never needs a second page.
Example questions
"Check the Loomio connection and tell me which groups you can see." →
check_connection"What is new in Loomio since yesterday?" →
list_threads"Summarise the discussion about the budget." →
search_content, thenget_thread_markdown"Who are the coordinators of the Finance group?" →
list_groups,list_memberships"Rank the members of these three groups by participation this year." →
get_participation_report"How active has Ada Example been since March?" →
get_user_activity"What was decided in the last five closed proposals?" →
list_pollswithstatus: closed"Post a status update in the release thread." →
create_comment(writable mode)
HOWTO.md has longer walk-throughs.
Quick start (stdio, local)
LOOMIO_API_KEY=… npx loomiomcpAdd it to your Claude Desktop / Claude Code config the same way you would any stdio MCP server.
Remote (HTTP)
See DEPLOY.md for Cloud Run. The HTTP server also exposes an
unauthenticated GET /health that reports whether Loomio still
accepts the connector's API key — 200 {"status":"ok","key_status":"valid",…}
or 503 with key_status rejected / unreachable. Point an uptime
check at it with content match "key_status":"valid" (DEPLOY.md has the
recommended setup); a rotated key is otherwise invisible until someone
notices every call failing. The check_connection tool reports the
same verdict to the AI caller.
Auth
Loomio authenticates by API key sent in an HTTP bearer header:
Authorization: Bearer <API_KEY>The connector injects it server-side; it never reaches the MCP client.
Copy the key from the user's API access page in Loomio
(/profile/api_access).
The key is not permanent. Loomio regenerates a user's API key
whenever that user's password changes (and Loomio 3.3.1, August 2026,
rotated every user's key once). When that happens every call answers
403 {"error":"You are not authorized to access this page."}; the
connector recognises that body, says "key rejected — probably rotated"
with the remediation, and (HTTP) turns /health red. Fetch the current
key from the API access page and update LOOMIO_API_KEY. No API can
read another user's key.
Keys passed in the query string (?api_key=…) are rejected — Loomio
removed that scheme in July 2026 because URLs are retained in browser
history, proxy logs, and monitoring systems. A request carrying its key
that way is treated as unauthenticated and 403s.
The optional b3 admin namespace uses the same bearer header with a
different secret (validated against ENV['B3_API_KEY'] on the Loomio
server, >16 chars). Only relevant if you operate a Loomio instance.
What the connector's user can see
Every read runs as the user whose API key is configured. Loomio ≥ 3.8
lets any authenticated user read publicly visible groups' public
threads, so get_group, list_discussions, list_polls,
list_threads and search_content reach beyond the user's member
groups — but list_groups (Loomio's current_user.groups) and the
participation report do not, and list_memberships answers a
non-member with an empty list. Instance is_admin widens nothing.
Poll results follow Loomio's own rule for that user: an open
until_vote poll the user has not voted in has its counts stripped
(results_visible: false, results_hidden_reason: "until_vote"), the
same rule hides vote reasons in search_content hits
(snippet_hidden_reason), and anonymous polls never reveal who voted
what.
Loomio compatibility
Tested against Loomio 3.8.1 (TESTED_LOOMIO_VERSION in
src/version.ts). Loomio publishes no API compatibility or deprecation
policy and ships tags often, so the connector reads the instance's
version from the public GET /api/v1/boot/version at startup and logs a
one-time loomio.version_drift warning when the major.minor differs;
check_connection repeats the warning in its notes. Every outbound
request carries User-Agent: loomiomcp/<version> — if your Loomio sits
behind a CDN/WAF, allow that user-agent (the connector recognises a WAF
403 and says so instead of blaming the key).
Read-only mode
Set LOOMIO_MCP_READONLY=1 to register only the 14 read tools. All
write tools (create_*, update_*, delete_*, manage_*) and the b3
tools are skipped at server-init time, and the client (loomioPost /
loomioPatch / loomioDelete) refuses a write before any request is
made even if one were reached. This is the mode the Cloud Run
deployment runs in.
Docs map
File | When to read |
"I want to use this locally with Claude Desktop / Code today" | |
"I want to run this as a remote HTTP/OAuth endpoint" | |
"I want example prompts and use cases" | |
"I want to understand the load-bearing choices" | |
"I'm hitting a weird Loomio behaviour, or want the line-by-line endpoint reference" | |
"I'm doing a security review or rotating secrets" | |
"I want to know what each tool costs upstream, and the observability queries" | |
"I want to add a tool or send a PR" | |
"What changed?" |
License
Apache-2.0
Available Tools
24 toolscheck_connectionARead-onlyIdempotent
Call FIRST when unsure whether the connector works or what it can see: 1 health probe, no input. Returns key_status ('valid' | 'rejected' | 'unreachable'), the key's user, its groups[] with member_state, readonly, b3_enabled and notes[].
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint, openWorldHint, idempotentHint, destructiveHint false), the description details the exact return values: key_status enum, the key's user, groups[] with member_state, readonly, b3_enabled, and notes[]. This adds substantial behavioral context, especially since there is no output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, densely informative sentence. It front-loads the primary usage instruction ('Call FIRST when unsure...') and then succinctly lists return fields, with no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple, no-input health probe, the description provides complete context: when to use it, what it returns, and the key statuses. With annotations covering safety and idempotency, and no output schema, nothing essential is missing for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4. The description confirms 'no input', which is consistent with the empty schema, but naturally there are no parameters to explain further.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('health probe') and resource ('the connector', 'the key'), and clarifies it checks whether the connector works or what it can see. It is clearly distinguishable from all sibling tools, which deal with polls, discussions, comments, and content.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says to call it FIRST when unsure whether the connector works or what it can see, giving clear situational guidance. However, it lacks explicit when-not-to-use guidance or mention of alternatives, though none are really needed for a unique diagnostic.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_commentA
Post a comment in a thread: 1 call (2 when discussion_id is a short key). Required body (+ body_format: 'html' for HTML; Loomio stores an omitted format as Markdown) and a target: discussion_id for a top-level comment, or parent_id + parent_type ('Comment' for a threaded reply; 'Poll' / 'Stance' / 'Outcome'). A new thread: create_discussion.
| Name | Required | Description | Default |
|---|---|---|---|
| body | Yes | ||
| parent_id | No | Comment, Poll, Stance or Outcome id to reply to (needs parent_type). | |
| body_format | No | Default 'md'; 'html' when `body` is HTML. | |
| parent_type | No | Type of parent_id; required with it. | |
| discussion_id | No | Discussion id or short key (+1 call) for a top-level comment; or use parent_id. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnly false, destructive false, openWorld true), and the description adds non-derivable operational context: call cost (1 call, 2 when discussion_id is a short key) and the server-side default that an omitted body_format is stored as Markdown. It does not warn about duplicate posts (idempotentHint=false), which is the main remaining gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the action, then packs target rules into one dense sentence with no filler. The telegraphic shorthand ('2 when...', '+1 call') is efficient but slightly compressed relative to plain prose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 5-parameter mutation tool with no output schema, the description covers purpose, both target paths, the format default, and the sibling alternative. Only the idempotency/duplicate-posting behavior and any required permissions are unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 80% schema coverage the baseline is 3, but the description adds value beyond the schema by mapping parent_type values to intent ('Comment' for a threaded reply; 'Poll'/'Stance'/'Outcome') and by cross-referencing the dependency between parent_id and parent_type in prose.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ('Post a comment in a thread') and immediately scopes it against siblings by naming create_discussion for new threads. The target variants (top-level vs threaded reply) further pin down what this tool does that create_poll/update_comment do not.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states which parameter combination selects which behavior: discussion_id for a top-level comment, parent_id + parent_type for a reply, and create_discussion for a brand-new thread. An agent can route correctly without opening any schema.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_discussionA
Start a discussion in a group: 1 call. Required title, group_id; optional description (+ description_format: 'html' for HTML), private (omit for the group's default), tags, recipients. Returns id, key, url, topic_id. Check list_discussions for duplicates first; to add to a thread use create_comment.
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | ||
| title | Yes | ||
| private | No | true = members only, false = public. Default: the group's setting. | |
| group_id | Yes | ||
| description | No | ||
| recipient_emails | No | Emails to notify; non-members become guests. | |
| notify_recipients | No | false = add recipients without emailing them. | |
| recipient_message | No | Text for the notification. | |
| description_format | No | Default 'md'; 'html' when `description` is HTML. | |
| recipient_audience | No | 'group' = notify the whole group. | |
| recipient_user_ids | No | User ids to notify. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare non-read-only, non-idempotent, non-destructive, open-world, so the safety profile is covered. The description adds real value beyond that by listing the returned fields (id, key, url, topic_id) despite there being no output schema, and by noting the '1 call' cost and that omitting private falls back to the group default. It does not explicitly state that recipients are emailed by default (notify_recipients semantics), which the schema carries instead.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense paragraph that front-loads the action, then parameters, then return values, then routing. Every clause carries information; nothing is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 11-parameter mutation tool with no output schema, the description supplies the return fields and the required/optional split, which fills the biggest gap. It is slightly thin on the recipient-notification behavior and permissions/auth needs, but nothing essential for a correct call is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 64% and the description groups parameters into required (title, group_id) and optional, and clarifies description_format usage and the private default. However, most of that repeats defaults already in the schema, and it says only 'recipients' for the four recipient-related parameters (emails, ids, audience, message, notify flag), leaving the notification surface to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Start a discussion in a group') and immediately scopes it against siblings by naming create_comment as the tool for threading and list_discussions for dedupe. An agent can distinguish this from create_poll or create_comment without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells the agent to check list_discussions for duplicates first and to use create_comment to add to an existing thread. That is a clear when-to-use precondition plus named alternatives, which is exactly what routing guidance should look like.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_pollA
Create a poll: 1 call (2 with discussion_id). Required title, poll_type, options (NO default options; only 'question' takes none) and group_id (standalone) or discussion_id / topic_id (inside a thread). closing_at (ISO-8601, future) is effectively REQUIRED: without it Loomio saves the poll UNOPENED and the result carries opened: false and a warning. An opening poll is announced because notify_on_open defaults to TRUE; pass notify_on_open: false for a quiet create.
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | Tags for a standalone poll's thread. | |
| title | Yes | ||
| details | No | ||
| options | No | Option names in order. REQUIRED except 'question'; ranked_choice/stv need 2+. | |
| group_id | No | Group of a STANDALONE poll (else only cross-checked). | |
| topic_id | No | Thread id (`topic_id` on any thread row); no extra call. | |
| anonymous | No | Permanent. Needs closing_at; not for count, question, meeting. | |
| max_score | No | score: max per option (default 5); meeting: 2. | |
| min_score | No | score: min per option (default 0). | |
| poll_type | Yes | 'question' has no options; 'meeting' options are ISO-8601 times; 'stv' takes stv_seats. | |
| stv_seats | No | stv: seats to fill. | |
| closing_at | No | ISO-8601, future. Effectively REQUIRED: omitted = unopened draft. | |
| hide_results | No | Default 'off'; anonymous polls force 'until_closed'. | |
| discussion_id | No | Discussion to attach to (id or key; +1 call). Prefer topic_id. | |
| reason_prompt | No | Prompt above the reason box. | |
| details_format | No | Default 'md'; 'html' when `details` is HTML. | |
| notify_on_open | No | Announce (`poll_announced`) on opening; Loomio's default is TRUE. | |
| dots_per_person | No | dot_vote: points per voter (default 8). | |
| shuffle_options | No | Randomise option order per voter. | |
| meeting_duration | No | meeting: slot minutes. No default through the API. | |
| recipient_emails | No | Emails to invite; non-members become guests. | |
| can_respond_maybe | No | meeting: allow 'maybe'. API default is false. | |
| notify_recipients | No | Email/push the named recipients; SEPARATE from notify_on_open. | |
| recipient_message | No | Text for the notification. | |
| recipient_audience | No | 'group' = every member (needs announce permission). | |
| recipient_user_ids | No | User ids to invite / notify. | |
| specified_voters_only | No | Only the named recipients may vote. | |
| maximum_stance_choices | No | Max options per voter (poll: 1; raise for multi-choice). | |
| minimum_stance_choices | No | Min options per voter (ranked_choice: ranks, default 3). | |
| notify_on_closing_soon | No | 24h closing reminder; API default is 'nobody'. | |
| show_none_of_the_above | No | Offer 'none of the above' (poll, ranked_choice). | |
| stance_reason_required | No | Default 'optional'; anonymous polls force 'disabled'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety profile, but the description adds critical behaviors beyond them: call count, that omitting closing_at produces an unopened poll with opened:false and a warning, and that notify_on_open defaults to TRUE requiring explicit false for a quiet create. These are meaningful operational disclosures.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four dense sentences front-load the creation summary and required parameters with no filler, using inline code for parameter names. Appropriately sized for a 32-parameter tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich schema and annotations, the description covers the critical creation-time behavioral traps (unopened draft, default announcement) and call-count implications. No output schema exists, but the description mentions key result fields, making it complete for an agent's needs.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 94%, so baseline is 3. The description adds operational meaning for requiredness of options/closing_at and the quiet-create toggle, plus the call-count impact of discussion_id, though much of the parameter guidance duplicates existing schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Create') and resource ('poll'), distinguishes standalone vs thread call counts, and names the required fields. Sibling tools are other poll operations (get/update/delete/list), so the creation intent is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear context for when poll creation applies, including standalone vs inside-thread routes and the effectively-required closing_at condition. It does not explicitly name alternatives or when-not-to-use scenarios, so it falls short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_commentADestructiveIdempotent
Discard a comment by numeric id: 1 call. Loomio's SOFT delete: the body is blanked and the comment leaves the thread view, but nothing is permanently erased (restorable in Loomio). For a wording fix prefer update_comment.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and idempotentHint=true, but the description adds crucial nuance the annotations cannot: this is a Loomio SOFT delete, the body is blanked, the comment leaves the thread view, and the change is restorable. That materially changes how an agent should reason about irreversibility.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the action, then the soft-delete semantics, then the alternative. No filler; each clause carries distinct information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, but annotations cover the safety profile and the description covers the rest: action, target, reversibility, and the sibling alternative. An agent has everything needed to call this correctly and to avoid it when updating text instead.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and there is one parameter. The description identifies `id` as a numeric comment identifier, which matches the schema's integer type and clarifies the target entity, but adds no format, range, or lookup detail beyond that. With one trivially typed param, this is adequate but not compensatory.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Discard a comment by numeric `id`') and differentiates from the sibling update_comment as well as the broader delete_* family. An agent can identify the operation without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent: 'For a wording fix prefer update_comment' names the alternative and the condition that selects it. Usage is thereby bounded rather than left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_discussionADestructiveIdempotent
Discard a discussion by id_or_key: 1 call. Loomio's SOFT delete: it leaves every list and its text is blanked, but nothing is permanently erased (a group admin can restore it). For a text mistake prefer update_discussion.
| Name | Required | Description | Default |
|---|---|---|---|
| id_or_key | Yes | Discussion id or short key. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say destructive/idempotent/not-read-only; the description goes well beyond them by disclosing that this is a SOFT delete, that the discussion leaves every list, that its text is blanked, that nothing is permanently erased, and that a group admin can restore it. That reversibility and side-effect detail is exactly what an agent needs before invoking a destructive tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with the verb and target, then the soft-delete semantics, then the alternative. No filler; every clause carries operational information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter destructive tool with no output schema, the description covers effect (blanked text, removed from lists), reversibility (admin restore), and the sibling alternative. Nothing an agent needs in order to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single parameter is documented there ('Discussion id or short key'), so the schema already carries the semantics. The description references `id_or_key` but adds no format or lookup detail, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Discard') and resource ('a discussion') plus the identifier used to target it. It also distinguishes itself from a sibling ('prefer update_discussion' for text mistakes), so an agent can separate delete from update without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the alternative (update_discussion) and the condition selecting it (a text mistake), which is real routing guidance. It lacks broader when-not guidance (e.g., delete vs. archive/lock, or confirm-before-delete norms), so it stops short of fully explicit when/when-not coverage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_pollADestructiveIdempotent
Discard a poll by id_or_key: 1 call. Loomio's SOFT delete: the poll and its votes leave the thread view, but nothing is permanently erased (a group admin can restore it). To end voting set closing_at to the next full hour with update_poll; no immediate close exists.
| Name | Required | Description | Default |
|---|---|---|---|
| id_or_key | Yes | Poll id or short key. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, so the safety profile is known. The description adds real value by qualifying that destruction: it is a SOFT delete, items leave the thread view but are recoverable by a group admin. It does not explain the response body, but the destructive-scope nuance is the important missing piece and it is supplied.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly packed sentences: the action and its soft-delete consequence come first, then the alternative routing. The '1 call' fragment is the only mildly extraneous element.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and none is needed for a delete. The description covers what is removed, what is recoverable, by whom, and how to achieve the adjacent goal (closing a poll), which is everything an agent needs before invoking it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single parameter is already documented as 'Poll id or short key.' The description only names id_or_key without adding format, accepted-key, or lookup semantics, so it does not exceed the schema baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Discard a poll') plus the identifying parameter, and immediately clarifies the scope of the operation. An agent can distinguish this from delete_comment, delete_discussion, and update_poll without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent away from this tool for a common mis-use case: ending voting is done via update_poll with closing_at, and it notes 'no immediate close exists'. That is a concrete when-not-to-use plus the named alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_discussionARead-onlyIdempotent
One discussion by numeric id or short key: 1 call (2 with include_items). Returns the full body, topic_id, counters, url; include_items: true embeds list_thread_items as thread_items (items_limit; next_offset says when to page on). Prose: get_thread_markdown; a group's threads: list_discussions.
| Name | Required | Description | Default |
|---|---|---|---|
| id_or_key | Yes | Discussion id or short key. | |
| strip_html | No | Plain text instead of HTML; default false. | |
| items_limit | No | With include_items: items to embed (default 200, max 1000). | |
| include_items | No | Also embed the thread's items as `thread_items` (+1 call). | |
| items_body_max_chars | No | With include_items: chars per body (default 4000; 0 omits, -1 full). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so safety is covered; the description adds genuinely new behavioral context: the call-count budget, the exact return shape (body, topic_id, counters, url), and how embedding items interacts with pagination (next_offset). Only auth/permission expectations and rate limits are left unstated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Extremely dense but front-loaded: the identifying statement comes first, followed by output shape, optional expansion, and routing. Every clause (call counts, next_offset, sibling pointers) carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden of describing returns and does so (body, topic_id, counters, url, embedded thread_items, next_offset). It also covers the include_items toggle's cost and paging implication, leaving nothing an agent needs missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all five parameters are already documented there, including strip_html and items_body_max_chars. The description only re-ties items_limit to include_items (which the schema already states), so it adds little beyond the schema baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('One discussion by numeric id or short key') and immediately distinguishes itself from siblings list_discussions and get_thread_markdown. An agent can tell it apart from list_discussions/lookup tools without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent: use get_thread_markdown for prose, list_discussions for a group's threads, and this tool for a single discussion (plus the include_items variant). It also flags the cost tradeoff (1 call vs 2 with include_items) that drives the choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_groupARead-onlyIdempotent
One group by numeric id, short key or URL handle: 1 call; works for public groups the user has not joined. Returns the full record (members_can_* flags included, billing subscription dropped) plus member, membership, parent, url. 403 'Not authorized to show Group.' = hidden from this user; unknown = 404.
| Name | Required | Description | Default |
|---|---|---|---|
| id_or_key_or_handle | Yes | Group numeric id, short key or URL handle. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial behavior beyond the annotations: cost (1 call), visibility rules for unjoined public groups, the exact field set returned (members_can_* included, billing subscription dropped, plus member/membership/parent/url), and error semantics (403 = hidden from user, 404 = unknown). This is exactly the destructive/edge-case context the readOnly/idempotent hints don't cover.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences, front-loaded with the identifier forms, then scope, then return shape, then error codes. No filler; every clause carries load-bearing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description fully covers the return payload and the error taxonomy, plus the non-member visibility nuance. Nothing an agent needs to call and interpret the result is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the description's 'numeric id, short key or URL handle' essentially restates the schema's parameter description. No additional syntax or format detail is added, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource (a single group) and the accepted identifier forms (numeric id, short key, URL handle), making it clearly distinguishable from the sibling list_groups ('One group' vs a list). An agent can select it correctly without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear usage context that it 'works for public groups the user has not joined,' which tells the agent this is usable even without membership. It does not explicitly name list_groups as the alternative for multiple groups, so it stops short of full when/when-not routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_participation_reportARead-onlyIdempotent
Rank the members of a group set: 1 call returns Loomio's own report, a row per user sorted by total desc. Scope by group_ids (1-50, counted together) or group_scope: 'my'; top limit rows (default 50, max 500), zero-activity users dropped unless include_inactive. Anonymous polls are excluded; a vote counts in the month its counted stance row was created.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Rows after sorting by total desc (1-500). Default 50. | |
| end_month | No | Last month, YYYY-MM. Default: the current month. | |
| group_ids | No | Group ids counted together (1-50); required unless group_scope 'my'. | |
| group_scope | No | 'custom' (default) = given group_ids; 'my' = the user's groups. | |
| start_month | No | First month, YYYY-MM. Default: 11 months before end_month. | |
| delegates_only | No | Only users with an active delegate role. Default false. | |
| include_inactive | No | Also list users with total 0 (ever-members). Default false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnly, idempotent, non-destructive), so the description adds genuinely useful behavior beyond them: anonymous polls excluded, zero-activity users dropped unless include_inactive, and the non-obvious counting rule that a vote counts in the month its counted stance row was created. These are real disclosure wins for a reporting tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences pack the ranking behavior, scoping options, and counting caveat up front with essentially no filler. The semicolon-chained clauses are information-dense rather than wasteful, though slightly cramped.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description carries return-shape burden: it tells the agent it gets one row per user with a `total` value sorted descending, which is the key information. Full column set is not enumerated, but for a 7-param report this is close to sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all 7 parameters including ranges and defaults. The description largely restates them ('default 50, max 500', group_ids 1-50) and only marginally adds the 'counted together' relationship, so baseline 3 is warranted.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('rank the members of a group set') and clarifies it returns Loomio's own report, one row per user sorted by `total` desc. It is unambiguous, though it does not explicitly name a sibling such as get_user_activity to differentiate the two activity-style tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains how to scope the report ('group_ids' counted together or 'group_scope: my'), which implies usage, but never states when to choose this tool over alternatives like get_user_activity or get_group. Inclusion rules (include_inactive, zero-activity dropped) give some operational guidance but no true when-to-use framing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_pollARead-onlyIdempotent
One poll by numeric id or short key: 1 call. Returns poll (full details, topic_id), poll_options[], current_outcome, my_stance, url; votes as items: list_thread_items with its topic_id. Results gate: results_visible / results_hidden_reason say whether tallies are present; absent counts mean HIDDEN, never zero.
| Name | Required | Description | Default |
|---|---|---|---|
| id_or_key | Yes | Poll id or short key. | |
| strip_html | No | Plain text instead of HTML; default false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly/openWorld/idempotent/non-destructive), and the description adds behavior annotations cannot: the results-gating fields and the critical gotcha that 'absent counts mean HIDDEN, never zero.' This is exactly the kind of disclosure that prevents misinterpretation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then return shape, then sibling routing, then the gating caveat — dense and waste-free. The return-field enumeration is verbose but earned given the absence of an output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden and does so fully: it names the key fields, the gating fields, and how to fetch votes. Nothing an agent needs to call and interpret this tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 ('Poll id or short key', 'Plain text instead of HTML; default false'). The description restates the id/key duality but adds no syntax or format detail beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('One poll') and its lookup modes ('by numeric id or short key'), immediately distinguishing it from list_polls, create_poll, and update_poll. An agent knows exactly what it retrieves without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clear context for single-item retrieval and a concrete routing hint for related data ('votes as items: list_thread_items with its topic_id'), which steers the agent to the right sibling for votes. However, it never explicitly contrasts itself with list_polls or states exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_thread_markdownARead-onlyIdempotent
The best single call for 'summarise / read this thread': 1 call by topic_id (2 by discussion_id or poll_id; pass exactly one) returns Loomio's server-rendered Markdown of the thread (markdown, chars, truncated). Structured data: list_thread_items. max_chars cuts from the END, so truncated: true means the newest items were dropped.
| Name | Required | Description | Default |
|---|---|---|---|
| poll_id | No | Poll id or short key of a STANDALONE poll (+1 call). | |
| topic_id | No | Thread id (`topic_id` on any thread row, NOT `id`); no extra call. | |
| max_chars | No | Cap in chars; default 60000, -1 = all. Cuts the END; `truncated` flags it. | |
| discussion_id | No | Discussion id or short key (+1 call); prefer `topic_id`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so the safety burden is lifted. The description still adds non-obvious behavior: the response is server-rendered Markdown with `markdown`/`chars`/`truncated`, and critically that `max_chars` cuts from the END so `truncated: true` drops newest items. It does not cover auth or rate limits, but for a read tool this is well above the annotation-covered bar.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences, front-loaded with the primary use case and no filler. The packed parentheticals ('2 by discussion_id or poll_id; pass exactly one') are information-dense but slightly strain readability, keeping it just short of a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by naming the returned fields and the truncation flag; it also covers all four parameters, the id-selection rule, and the structured-data alternative. An agent has everything needed to call this correctly on the first attempt.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so per-parameter meanings are already documented (baseline 3). The description nevertheless adds a cross-parameter constraint the schema cannot express — 'pass exactly one' of topic_id/discussion_id/poll_id — and reinforces the truncation semantics of max_chars, which is genuine added value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('read/summarise this thread' returning server-rendered Markdown), and explicitly positions itself as 'the best single call' against the sibling list_thread_items for structured data. An agent can distinguish it from get_discussion and list_thread_items without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use ('for summarise / read this thread'), when to prefer another tool ('Structured data: list_thread_items'), the alternative ids with their cost ('+1 call'; 'prefer topic_id'), and the constraint 'pass exactly one'. Nothing about tool selection is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_user_activityARead-onlyIdempotent
One person's participation across groups: 1 call per group + 1. Required user_id (from list_memberships or a participation row) and group_ids. Returns counts, by_group, sample_events (newest items with urls, not a full list). MONTH-GRAINED: since / until widen to whole months; anonymous polls never count; a vote counts in the month its counted stance row was created.
| Name | Required | Description | Default |
|---|---|---|---|
| since | No | ISO-8601 start, rounded down to its month. Default: all history. | |
| until | No | ISO-8601 end (exclusive), rounded out to a whole month. Default: now. | |
| user_id | Yes | Loomio user id. | |
| group_ids | Yes | Group ids (1-50); 1 call each. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this as a safe idempotent read, so the bar is lower, yet the description adds substantial domain behavior: month-graining that widens since/until to whole months, the rule that anonymous polls never count, and the stance-row month attribution rule for votes. It also discloses that sample_events are newest items with urls, not a full list.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then required params, then return shape, then the MONTH-GRAINED rules; every clause carries information. It is dense and heavy on terse fragments, but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a four-parameter read tool with no output schema, the description covers the return fields (counts, by_group, sample_events), the date-windowing semantics, the counting rules, and where inputs are sourced. An agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds meaning beyond the schema by specifying the source of user_id (list_memberships or a participation row) and the month-widening consequence of since/until. The '1 call each' note on group_ids largely restates the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: retrieving one person's participation across groups. The '1 call per group + 1' batching detail is distinctive and helps an agent understand the call pattern. It implies but does not explicitly name the contrast with get_participation_report, so it stops short of full sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It tells the agent where required values come from (user_id from list_memberships or a participation row), which is useful workflow guidance. However, it never says when to prefer this per-user view over the sibling get_participation_report, nor states any exclusions, leaving the when-to-use decision implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_discussionsARead-onlyIdempotent
One group's discussions, newest activity first: 1 call. status defaults to 'open'; description_max_chars (default 1500) caps bodies, description_truncated: true marking a cut; strip_html (default true) gives plain text. Every visible group: list_threads; keywords: search_content. Subgroups are excluded.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Page size, 1-200. Default 50. | |
| offset | No | Page offset. Default 0. | |
| status | No | 'open' (default) = unlocked, 'closed' = locked, 'all'. | |
| group_id | Yes | ||
| strip_html | No | Plain text instead of HTML; default true. | |
| description_max_chars | No | Chars per `description`; default 1500, 0 omits it, -1 = full. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnlyHint, idempotentHint, openWorldHint, and destructiveHint=false, so the safety profile is clear. The description adds behavioral details: default status filtering, pagination hints via '1 call', and default strip_html. However, return format and pagination behavior are only partially addressed. Baseline 3 appropriate given annotations carry the core traits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Efficient and front-loaded: the primary purpose and scoping are stated first, followed by parameter defaults and related tools. No wasted words. Could be tightened further but is well structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a list tool with annotations covering safety and schema covering most parameters, the description provides useful defaults and scoping. However, it does not mention pagination behavior (offset/limit interaction) or return structure, and there is no output schema. Adequate but incomplete for an agent needing to call correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 83%, so most parameters are already described. The description adds behavioral nuance for status default, description_max_chars truncation behavior (with description_truncated flag), and strip_html default, which goes beyond schema. This is slightly above baseline but not rich enough for a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('One group's discussions') and a scope constraint (subgroups excluded). Does not explicitly name the related sibling get_discussion or list_threads, though it does reference list_threads in a different context. Distinguishable from siblings but not maximally so.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names alternatives: 'Every visible group: list_threads' and 'keywords: search_content', giving clear when-to-use context for related tasks. Lacks explicit when-not or differentiation from get_discussion / list_polls. Adequate but not comprehensive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_groupsARead-onlyIdempotent
The connector user's groups, pending invitations included: 1 call, no input. Subgroup parents are appended with member: false. get_group reads one record, even a public group this list omits.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive/openWorld, so safety is covered. The description adds return-shape behavior not in structured fields: pending invitations are included and subgroup parents are emitted with `member: false`. It does not discuss auth requirements or pagination, but adds genuine value beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight clauses, output scope front-loaded, then the call cost, then the sibling contrast. No filler anywhere.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description carries the return-value burden, and it does explain two notable return behaviors. Pagination and ordering are unaddressed, which is a minor remaining gap for a list tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so the baseline is 4; the description confirms 'no input', which matches the empty schema. Nothing further is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource (the connector user's groups) with scope detail (pending invitations included) and explicitly distinguishes itself from the sibling get_group, which 'reads one record'. An agent can pick between list_groups and get_group without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The contrast with get_group ('get_group reads one record, even a public group this list omits') gives clear routing guidance for the list-vs-single-record choice. It does not spell out broader when-not-to-use cases, but the key sibling decision is covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_membershipsARead-onlyIdempotent
A group's members: 1 call. Returns memberships[] (user_email only where the connector's user is a group admin), users[], total. Use it to resolve a name to a user_id and ALWAYS before manage_memberships with remove_absent. A non-member gets an EMPTY list, not 403: never report it as an empty group.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Page size, 1-200. Default 50. | |
| offset | No | Page offset. Default 0. | |
| group_id | Yes | Group id (a non-member gets an empty list, not 403). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive), and the description adds real behavioral nuance beyond them: user_email is only populated when the caller is a group admin, and a non-member receives an empty list rather than 403 — plus an explicit instruction not to misreport that as an empty group. This is exactly the kind of context annotations cannot convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but front-loaded: scope, return shape, then usage rules, then the empty-list caveat. Nearly every clause earns its place, though the return-shape enumeration is tightly packed and slightly cluttered with backticks.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by naming the returned keys (memberships[], users[], total) and the admin-conditional field, plus the critical empty-list edge case. An agent has everything needed to call and interpret this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and the schema already documents limit, offset, and the group_id non-member/empty-list behavior. The description's group_id remark largely restates the schema, adding no new syntax or format detail. Baseline 3 applies when the schema carries the parameter burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource and scope ('A group's members: 1 call') with a clear read verb implied by 'list_memberships'. It is distinguishable from list_groups/get_group, though the differentiation from manage_memberships comes through the usage note rather than the purpose statement itself.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states two use cases: resolving a name to a user_id, and the mandatory pre-step before manage_memberships with remove_absent. Names the sibling tool and the exact condition that requires this call first.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_pollsARead-onlyIdempotent
One group's polls, newest first: 1 call. status defaults to 'active' ('closed', 'all'); description_max_chars caps details; strip_html (default true). Slim rows with poll_options[] and stance_counts when visible (trust results_visible). For member activity use get_participation_report, not this plus list_memberships.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Page size, 1-200. Default 50. | |
| offset | No | Page offset. Default 0. | |
| status | No | 'active' (default) = open, 'closed', 'all'. | |
| group_id | Yes | ||
| strip_html | No | Plain text instead of HTML; default true. | |
| description_max_chars | No | Chars per `details`; default 1500, 0 omits it, -1 = full. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so the bar is lower, and the description adds real behavioral detail beyond them: newest-first ordering, slim rows, conditional presence of poll_options[] and stance_counts gated by results_visible, and the effect of strip_html on details. It still doesn't state pagination behavior or total counts, so not a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense and front-loaded, with the scope/ordering statement first and the routing caveat last. The telegraphic fragment style ('1 call', semicolon-joined clauses) is efficient but slightly cryptic and costs a point on readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by describing the row shape (poll_options[], stance_counts, results_visible) and the `details` field. Combined with schema-documented paging and defaults, an agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 83%, so the baseline is 3. The description adds semantic links the schema doesn't make on its own: that description_max_chars caps `details` specifically, and that strip_html controls whether details come back as HTML.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource with scope and ordering: 'One group's polls, newest first: 1 call.' It is immediately distinguishable from siblings like get_poll (single poll), create_poll, and list_groups.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent away from a tempting wrong path: 'For member activity use get_participation_report, not this plus list_memberships.' That is a clear when-not plus a named alternative, though it covers only this one scenario and says nothing about paging or when to prefer get_poll.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_thread_itemsARead-onlyIdempotent
One thread as structured items: 1 call by topic_id (2 by discussion_id or poll_id; pass exactly one). Returns items[] in thread order plus the comments, polls, stances (votes), outcomes and users they reference. The whole thread is fetched once and sliced here (limit, offset, kinds) under the max_total_chars budget; next_offset says where to continue.
| Name | Required | Description | Default |
|---|---|---|---|
| kinds | No | Item kinds to keep (e.g. new_comment, stance_created); 'other' = unlisted kinds. | |
| limit | No | Items after the kinds filter; default 200, max 1000. | |
| offset | No | Items to skip. Default 0. | |
| poll_id | No | Poll id or short key of a STANDALONE poll (+1 call). | |
| topic_id | No | Thread id (`topic_id` on any thread row, NOT `id`); no extra call. | |
| strip_html | No | Plain text instead of HTML bodies, reasons, outcomes; default true. | |
| discussion_id | No | Discussion id or short key (+1 call); prefer `topic_id`. | |
| body_max_chars | No | Chars per `body`; default 4000, 0 omits it, -1 = full. | |
| max_total_chars | No | Reply budget in chars; default 120000, -1 = none. See next_offset. | |
| include_reactions | No | Also return emoji `reactions`. Default false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so the bar is lower, but the description adds meaningful behavior: the whole thread is fetched once and sliced locally, `next_offset` signals continuation, and results are budgeted by `max_total_chars`. That pagination model is real context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences that front-load the purpose, then cover the call cost, return shape, pagination, and continuation. Slightly packed, but each clause carries information useful for correct invocation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 10-parameter read tool with annotations and no output schema, the description supplies the return shape (`items[]` plus referenced entities), the slicing parameters, and the continuation pointer. That is sufficient for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents each of the 10 parameters in detail (including the '+1 call' cost notes). The description adds only the integrated 'pass exactly one' constraint over the id params, which is marginal beyond what the schema provides; baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb+resource ('One thread as structured items') and clarifies the granularity (items[], not a rendered document), which distinguishes it from get_thread_markdown without naming that sibling explicitly. An agent can tell it returns structured thread data rather than a formatted report.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives concrete routing guidance for the id parameters: use `topic_id` for 1 call vs `discussion_id`/`poll_id` for 2 calls, and 'pass exactly one'. This helps an agent pick the efficient path, though it does not explicitly state when to prefer this tool over get_thread_markdown or list_threads.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_threadsARead-onlyIdempotent
The cheapest 'what is new across everything I can see': 1 call lists every visible thread, newest activity first (topic_id, type, title, group_id, counters, url; no bodies). group_id / type filter client-side within the page (one group: list_discussions / list_polls). No date filter upstream: pass since and page with offset until scope.exhausted.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Keep only Discussion or Poll threads (client-side). | |
| limit | No | Threads per page, default 20, max 100. | |
| since | No | ISO-8601 cutoff on last_activity_at; page until scope.exhausted. | |
| offset | No | Threads to skip. Default 0. | |
| group_id | No | Only this group's threads (client-side; `total` stays instance-wide). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive), yet the description adds real behavioral context: no bodies returned, `group_id`/`type` filtering happens client-side within the page, and `total` stays instance-wide. What it does not fully disclose is what `scope.exhausted` actually contains or how many pages a typical traversal needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the value proposition and return shape, then the caveats; no filler sentences. The parenthetical stacking makes it dense and slightly hard to parse, but nothing is padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden and does so by listing the key fields and noting the absence of bodies. Combined with the paging loop and client-side filter caveats, an agent has enough to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description goes further by explaining that `group_id`/`type` are client-side filters and that `since`/`offset` drive a page-until-exhausted loop. This adds operational meaning (especially that `total` is not scoped to the filter) beyond the per-parameter schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a concrete verb+resource ('lists every visible thread, newest activity first') and enumerates the returned fields, so the agent knows exactly what comes back. It also distinguishes itself from the single-group siblings by naming list_discussions / list_polls as the narrower alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Positions the tool as 'the cheapest what-is-new across everything I can see' and explicitly routes single-group lookups to list_discussions / list_polls. It even prescribes the paging pattern (pass `since`, page with `offset` until `scope.exhausted`), so when and how to use it is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_membershipsADestructive
Invite users to a group by email and optionally REMOVE members not in the list: 1 call; the connector's user must be an admin of THAT group. Default is additive: new addresses are invited, nobody is touched. DANGEROUS: remove_absent: true removes every member whose email is absent, own user included, with no undo: list_memberships first, then confirm the diff with a human.
| Name | Required | Description | Default |
|---|---|---|---|
| emails | Yes | Addresses to ensure are members; new ones are invited. | |
| group_id | Yes | Group id; the connector's user must be its admin. | |
| remove_absent | No | DANGEROUS: also revokes every member absent from `emails`, own user included. Default false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond annotations (which only flag destructive=true, idempotent=false): it names the admin-of-that-group auth requirement, the self-removal hazard ('own user included'), and the irreversibility ('no undo'). This is exactly the safety context an agent needs before a destructive mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and default, then the danger. It is dense but each clause earns its place; the '1 call' phrase is slightly superfluous but minor.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-param destructive mutation with no output schema, the description covers auth requirements, default vs destructive semantics, self-inclusion, irreversibility, and a recommended pre-check workflow. Nothing an agent needs to invoke it safely is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and the schema already documents emails ('ensure are members'), group_id (admin requirement), and remove_absent (dangerous/default false). The description largely restates that, so it earns the baseline 3 rather than adding new parameter meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States specific verbs (invite, remove) and resource (group memberships by email), and explicitly contrasts the additive default against the destructive remove mode. An agent can distinguish it from list_memberships without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells the agent that the default is additive ('nobody is touched') and that remove_absent:true triggers destructive removal, then prescribes a workflow: call list_memberships first and confirm the diff with a human. When-to-use and when-to-be-careful are both stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_contentARead-onlyIdempotent
Keyword search over everything the connector's user can see: 1 call. Pass query (prefix match; !word excludes), author_id alone for 'what did X post', or both. Hard cap: at most 20 results, no paging; capped: true means narrow the search. Stance hits on polls with hidden results are DROPPED from a query search; never use search to probe hidden vote reasons.
| Name | Required | Description | Default |
|---|---|---|---|
| tag | No | Only threads carrying this tag (exact name). | |
| order | No | authored_at_desc (default), authored_at_asc, relevance. | |
| query | No | Full-text query (prefix match; `!word` excludes). | |
| types | No | Record types to include; default all (e.g. ['Outcome']). | |
| group_id | No | Restrict to one group (not its subgroups). | |
| author_id | No | Restrict to one author; alone = their 20 newest items. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, openWorld and non-destructive, so the safety profile is covered. The description adds genuinely useful behavior the annotations do not: a hard 20-result cap with no paging, the `capped: true` signal, and that stance hits on hidden-result polls are dropped from a query search. That said, it stops short of naming the alternative tool for the capped case, so it is additive but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Roughly four dense sentences, all front-loaded, with the two most consequential facts (20-result cap, hidden-stance drop) placed where they cannot be missed. No filler or restatement of the tool name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description carries the return-value burden and does so by explaining the `capped: true` marker. With all six parameters fully documented in the schema and the safety profile in annotations, nothing an agent needs to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description earns an extra point by documenting cross-parameter semantics the schema does not: how query, author_id, and their combination compose ('or both') and how the cap interacts with narrowing the search. It omits tag/types/group_id/order, which the schema already covers.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Keyword search over everything the connector's user can see') with the visibility scope made explicit. It also pins down the search modes (query, author_id, both), so an agent can distinguish it from the list_/get_ siblings without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells when to use each input ('author_id alone for what did X post', or both), and adds a hard when-not: never use search to probe hidden vote reasons. Both the selection condition and the anti-pattern are given, leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_commentADestructiveIdempotent
Edit a comment: 1 call. Required numeric id and body (REPLACES the whole text: read it with list_thread_items first), optional body_format. Only the author, or a thread admin where the group allows it, may edit; the thread must be unlocked.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| body | Yes | New body; REPLACES the whole text. | |
| body_format | No | Omitted = the STORED format stays; send 'html' when the text is HTML. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing that the body REPLACES the entire text (matching destructiveHint=true), the authorization model, and the thread-lock constraint. Annotations flag safety profile; the description fills in the operational consequences an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the verb and '1 call', then packs replace-semantics, params, and auth into one dense passage. Slightly redundant with schema wording on the body-replacement rule, but no wasted sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with no output schema, it covers auth requirements, destructive replace behavior, and prerequisites adequately. Return-value expectations are left implicit, which is acceptable given the tool's simple edit semantics.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 67% and the body/body_format descriptions already appear in the schema, so the description largely repeats structured data ('REPLACES the whole text', 'html' example). It adds identification of the undocumented id as 'numeric' and required, but little else beyond the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Edit a comment') and immediately disambiguates it against the create/delete_comment siblings by describing an in-place edit that REPLACES the whole body. An agent can select it confidently without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear preconditions: author/thread-admin permission, thread must be unlocked, and routes the agent to list_thread_items to read the text before replacing it. No explicit 'use X instead' exclusion, but the context is concrete and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_discussionADestructiveIdempotent
Edit a discussion by id_or_key: 1 call. Pass only what changes: title, description (REPLACES the body: read it first, send the whole text), private, allow_* flags, recipients to add. Cannot move a thread or change its tags; a discarded thread cannot be edited.
| Name | Required | Description | Default |
|---|---|---|---|
| title | No | ||
| private | No | true = members only; must fit `discussion_privacy_options`. | |
| id_or_key | Yes | Discussion id or short key. | |
| description | No | New body; REPLACES the whole description. | |
| allow_comments | No | Whether members may comment. | |
| allow_reactions | No | Whether members may react. | |
| recipient_emails | No | Emails to invite as readers; non-members become guests. | |
| notify_recipients | No | false = add recipients without emailing them. | |
| recipient_message | No | Notification text; records a visible 'edited' item. | |
| description_format | No | Omitted = the STORED format stays; send 'html' when the text is HTML. | |
| recipient_audience | No | 'group' = notify the whole group (needs announce permission). | |
| recipient_user_ids | No | User ids to add as readers and notify. | |
| allow_concurrent_polls | No | Allow several open polls at once. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint and idempotentHint, but the description adds critical specifics beyond them: description fully REPLACES the body (forcing a read-first, send-whole-text workflow), threads cannot be moved, tags cannot be changed, and discarded threads cannot be edited. These negative constraints are exactly the context an agent needs before mutating.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One dense, well-ordered sentence: identification, partial-update rule, the destructive replacement warning, then the impossibility constraints. No filler, and the highest-risk behavior (body replacement) is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 13-parameter mutation tool with no output schema and strong annotation coverage, the description covers the essential behavioral traps. Minor gaps remain around recipient/notify effects and permission requirements, but the core editing contract is complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 92%, so the schema carries most parameter meaning. The description still adds value by grouping the changeable fields ('allow_* flags, recipients to add') and emphasizing the replace-not-merge semantics of description, which the schema only states tersely.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Edit a discussion by id_or_key'), identifies the key parameter, and scopes it as a single call. An agent can distinguish this from create_discussion or update_comment without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Pass only what changes' plus the 'read it first' workflow for description give clear operational context, and the closing sentence lists what the tool cannot do. It stops short of naming a sibling alternative (e.g. update_comment) the way a 5 would, but the usage context is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_pollADestructiveIdempotent
Edit an OPEN poll by id_or_key: 1 call (2 with options). Pass only what changes: title, details (REPLACES the text), closing_at (future; opening a draft announces unless notify_on_open is false), options (names to ADD: merged with the current list, so it never removes an option it saw; not atomic), settings. Cannot change poll_type, anonymous, group or tags; a closed poll answers 403.
| Name | Required | Description | Default |
|---|---|---|---|
| title | No | ||
| details | No | ||
| options | No | Names to ADD (+1 call): merged with the stored names, so it never removes an option it saw. Not atomic. | |
| id_or_key | Yes | Poll id or short key. | |
| max_score | No | score: max per option (default 5); meeting: 2. | |
| min_score | No | score: min per option (default 0). | |
| stv_seats | No | stv: seats to fill. | |
| closing_at | No | ISO-8601, future; omitted = unchanged. To end voting soon pass the next full hour. | |
| hide_results | No | Cannot leave 'until_closed' once set. | |
| reason_prompt | No | Prompt above the reason box. | |
| details_format | No | Default 'md'; 'html' when `details` is HTML. | |
| notify_on_open | No | Announce (`poll_announced`) on opening; Loomio's default is TRUE. | |
| dots_per_person | No | dot_vote: points per voter (default 8). | |
| shuffle_options | No | Randomise option order per voter. | |
| meeting_duration | No | meeting: slot minutes. No default through the API. | |
| recipient_emails | No | Emails to invite; non-members become guests. | |
| can_respond_maybe | No | meeting: allow 'maybe'. API default is false. | |
| notify_recipients | No | Email/push the named recipients; SEPARATE from notify_on_open. | |
| recipient_message | No | Text for the notification. | |
| recipient_audience | No | 'group' = every member (needs announce permission). | |
| recipient_user_ids | No | User ids to invite / notify. | |
| specified_voters_only | No | Only the named recipients may vote. | |
| maximum_stance_choices | No | Max options per voter (poll: 1; raise for multi-choice). | |
| minimum_stance_choices | No | Min options per voter (ranked_choice: ranks, default 3). | |
| notify_on_closing_soon | No | 24h closing reminder; API default is 'nobody'. | |
| show_none_of_the_above | No | Offer 'none of the above' (poll, ranked_choice). | |
| stance_reason_required | No | Default 'optional'; anonymous polls force 'disabled'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: discloses that details REPLACES existing text, options are ADD-only and merged (never removes), the merge is not atomic, opening a draft announces a poll, and a closed poll returns 403. These are exactly the destructive/stateful traits an agent needs and the annotations alone (destructiveHint, idempotentHint) do not convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense paragraph that is front-loaded with the action and the call-count note, then lists the mutability contract and exclusions. Every sentence carries information; only the count of packed clauses keeps it from being maximally clean.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 27-parameter tool with high schema coverage, a safety profile in annotations, and no output schema, the description supplies the missing behavioral context (overwrite, merge, non-atomicity, 403, announce-on-open). Return values needn't be described since no output schema exists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 93% schema coverage the baseline is 3, but the description adds real semantic value: 'Pass only what changes', details overwrite behavior, option merge semantics, and future-only closing_at. It clarifies the update-patch contract that the schema type constraints alone don't express.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Edit) and resource (an OPEN poll) with the identifying parameter (id_or_key), and the constraint that it must be open immediately differentiates it from create_poll/delete_poll siblings. An agent can identify the operation without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear when-to-use conditions (only open polls; closed returns 403) and explicit when-not boundaries (cannot change poll_type, anonymous, group, tags). It doesn't name a sibling alternative by name, but the create/delete/update triad is unambiguous from context.
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.
24 tool updates
v0.0.13- Added
check_connection - Changed
create_comment10 fields changed- removed
Input schema / properties / body / descriptionRemoved value: -"Comment body (required)." - changed
Input schema / properties / body_format / descriptionPrevious value: -"Format of `body`. Defaults to Loomio's group default when omitted."New value: +"Default 'md'; 'html' when `body` is HTML." - added
Input schema / properties / discussion_id / anyOfAdded value: +[ + { + "pattern": "^[A-Za-z0-9_-]+$", + "type": "string" + }, + { + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "type": "integer" + } +] - changed
Input schema / properties / discussion_id / descriptionPrevious value: -"ID of the discussion to comment on."New value: +"Discussion id or short key (+1 call) for a top-level comment; or use parent_id." - removed
Input schema / properties / discussion_id / exclusiveMinimumRemoved value: -0 - removed
Input schema / properties / discussion_id / maximumRemoved value: -9007199254740991 - removed
Input schema / properties / discussion_id / typeRemoved value: -"integer" - added
Input schema / properties / parent_idAdded value: +{ + "description": "Comment, Poll, Stance or Outcome id to reply to (needs parent_type).", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "type": "integer" +} - added
Input schema / properties / parent_typeAdded value: +{ + "description": "Type of parent_id; required with it.", + "enum": [ + "Discussion", + "Comment", + "Poll", + "Stance", + "Outcome" + ], + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "discussion_id", - "body" -]New value: +[ + "body" +]
- Added
create_discussion - Changed
create_poll39 fields changed- changed
Input schema / properties / anonymous / descriptionPrevious value: -"If true, hide voter identities."New value: +"Permanent. Needs closing_at; not for count, question, meeting." - added
Input schema / properties / can_respond_maybeAdded value: +{ + "description": "meeting: allow 'maybe'. API default is false.", + "type": "boolean" +} - changed
Input schema / properties / closing_at / descriptionPrevious value: -"ISO-8601 timestamp at which the poll closes."New value: +"ISO-8601, future. Effectively REQUIRED: omitted = unopened draft." - removed
Input schema / properties / details / descriptionRemoved value: -"Optional poll body / context." - changed
Input schema / properties / details_format / descriptionPrevious value: -"Format of `details`. Defaults to 'md'."New value: +"Default 'md'; 'html' when `details` is HTML." - added
Input schema / properties / discussion_id / anyOfAdded value: +[ + { + "pattern": "^[A-Za-z0-9_-]+$", + "type": "string" + }, + { + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "type": "integer" + } +] - changed
Input schema / properties / discussion_id / descriptionPrevious value: -"Attach the poll to an existing discussion. When set, group_id is taken from the discussion."New value: +"Discussion to attach to (id or key; +1 call). Prefer topic_id." - removed
Input schema / properties / discussion_id / exclusiveMinimumRemoved value: -0 - removed
Input schema / properties / discussion_id / maximumRemoved value: -9007199254740991 - removed
Input schema / properties / discussion_id / typeRemoved value: -"integer" - added
Input schema / properties / dots_per_personAdded value: +{ + "description": "dot_vote: points per voter (default 8).", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "type": "integer" +} - changed
Input schema / properties / group_id / descriptionPrevious value: -"Group the poll belongs to. Required when not attaching to an existing discussion via discussion_id."New value: +"Group of a STANDALONE poll (else only cross-checked)." - changed
Input schema / properties / hide_results / descriptionPrevious value: -"Results visibility policy. Defaults to 'off'."New value: +"Default 'off'; anonymous polls force 'until_closed'." - added
Input schema / properties / max_scoreAdded value: +{ + "description": "score: max per option (default 5); meeting: 2.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +} - added
Input schema / properties / maximum_stance_choicesAdded value: +{ + "description": "Max options per voter (poll: 1; raise for multi-choice).", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "type": "integer" +} - added
Input schema / properties / meeting_durationAdded value: +{ + "description": "meeting: slot minutes. No default through the API.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "type": "integer" +} - added
Input schema / properties / min_scoreAdded value: +{ + "description": "score: min per option (default 0).", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +} - added
Input schema / properties / minimum_stance_choicesAdded value: +{ + "description": "Min options per voter (ranked_choice: ranks, default 3).", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" +} - changed
Input schema / properties / notify_on_closing_soon / descriptionPrevious value: -"Who Loomio notifies as the closing date approaches. Defaults to 'nobody'."New value: +"24h closing reminder; API default is 'nobody'." - changed
Input schema / properties / notify_on_closing_soon / enumPrevious value: -[ - "nobody", - "author", - "voters", - "undecided_voters", - "all_members" -]New value: +[ + "nobody", + "author", + "undecided_voters", + "voters" +] - added
Input schema / properties / notify_on_openAdded value: +{ + "description": "Announce (`poll_announced`) on opening; Loomio's default is TRUE.", + "type": "boolean" +} - changed
Input schema / properties / notify_recipients / descriptionPrevious value: -"If false, suppress the initial notification email. Defaults to false."New value: +"Email/push the named recipients; SEPARATE from notify_on_open." - changed
Input schema / properties / options / descriptionPrevious value: -"Voting options. `proposal` has built-in agree/disagree/abstain options; for poll / count / score / ranked_choice / meeting / dot_vote you MUST supply your own."New value: +"Option names in order. REQUIRED except 'question'; ranked_choice/stv need 2+." - changed
Input schema / properties / poll_type / descriptionPrevious value: -"Poll type. One of: proposal, poll, count, score, ranked_choice, meeting, dot_vote."New value: +"'question' has no options; 'meeting' options are ISO-8601 times; 'stv' takes stv_seats." - changed
Input schema / properties / poll_type / enumPrevious value: -[ - "proposal", - "poll", - "count", - "score", - "ranked_choice", - "meeting", - "dot_vote" -]New value: +[ + "proposal", + "poll", + "count", + "score", + "ranked_choice", + "meeting", + "dot_vote", + "check", + "question", + "stv" +] - added
Input schema / properties / reason_promptAdded value: +{ + "description": "Prompt above the reason box.", + "type": "string" +} - added
Input schema / properties / recipient_audience / descriptionAdded value: +"'group' = every member (needs announce permission)." - added
Input schema / properties / recipient_emails / descriptionAdded value: +"Emails to invite; non-members become guests." - changed
Input schema / properties / recipient_emails / items / patternPrevious value: -"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"New value: +"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$" - added
Input schema / properties / recipient_message / descriptionAdded value: +"Text for the notification." - added
Input schema / properties / recipient_user_ids / descriptionAdded value: +"User ids to invite / notify." - added
Input schema / properties / show_none_of_the_aboveAdded value: +{ + "description": "Offer 'none of the above' (poll, ranked_choice).", + "type": "boolean" +} - changed
Input schema / properties / shuffle_options / descriptionPrevious value: -"If true, shuffle option display order."New value: +"Randomise option order per voter." - changed
Input schema / properties / specified_voters_only / descriptionPrevious value: -"If true, only users in recipient_user_ids / recipient_emails can vote."New value: +"Only the named recipients may vote." - added
Input schema / properties / stance_reason_requiredAdded value: +{ + "description": "Default 'optional'; anonymous polls force 'disabled'.", + "enum": [ + "disabled", + "optional", + "required", + "required_for_disagree_or_block", + "required_for_block" + ], + "type": "string" +} - added
Input schema / properties / stv_seatsAdded value: +{ + "description": "stv: seats to fill.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "type": "integer" +} - added
Input schema / properties / tagsAdded value: +{ + "description": "Tags for a standalone poll's thread.", + "items": { + "minLength": 1, + "type": "string" + }, + "type": "array" +} - removed
Input schema / properties / title / descriptionRemoved value: -"Poll title (required)." - added
Input schema / properties / topic_idAdded value: +{ + "description": "Thread id (`topic_id` on any thread row); no extra call.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "type": "integer" +}
- Added
delete_comment - Added
delete_discussion - Added
delete_poll - Added
get_discussion - Added
get_group - Added
get_participation_report - Added
get_poll - Added
get_thread_markdown - Changed
get_user_activity4 fields changed- changed
Input schema / properties / group_ids / descriptionPrevious value: -"Groups to scan. Required — pass the result of `list_groups` (or a subset of it) to make the cost explicit. ~1 outbound HTTP request per discussion in scope, plus one list_discussions call per group; ~100-300 calls is typical for a wide scan. Capped at 50 groups per call."New value: +"Group ids (1-50); 1 call each." - changed
Input schema / properties / since / descriptionPrevious value: -"ISO-8601 timestamp; ignore events before this time. Rejected if unparseable (so a typo can't silently widen the scan to all history)."New value: +"ISO-8601 start, rounded down to its month. Default: all history." - changed
Input schema / properties / until / descriptionPrevious value: -"ISO-8601 timestamp; ignore events at or after this time. Rejected if unparseable."New value: +"ISO-8601 end (exclusive), rounded out to a whole month. Default: now." - changed
Input schema / properties / user_id / descriptionPrevious value: -"Loomio user id whose activity to summarise."New value: +"Loomio user id."
- Changed
list_discussions6 fields changed- added
Input schema / properties / description_max_charsAdded value: +{ + "description": "Chars per `description`; default 1500, 0 omits it, -1 = full.", + "maximum": 9007199254740991, + "minimum": -1, + "type": "integer" +} - removed
Input schema / properties / group_id / descriptionRemoved value: -"ID of the Loomio group whose discussions to list (required)." - changed
Input schema / properties / limit / descriptionPrevious value: -"Page size. Loomio defaults to 50."New value: +"Page size, 1-200. Default 50." - changed
Input schema / properties / offset / descriptionPrevious value: -"Page offset. Defaults to 0."New value: +"Page offset. Default 0." - changed
Input schema / properties / status / descriptionPrevious value: -"Filter by status. 'open' = unlocked, 'closed' = locked, 'all' = every kept discussion. Loomio defaults to 'open'."New value: +"'open' (default) = unlocked, 'closed' = locked, 'all'." - added
Input schema / properties / strip_htmlAdded value: +{ + "description": "Plain text instead of HTML; default true.", + "type": "boolean" +}
- Changed
list_groups3 fields changed- removed
Input schema / properties / end_idRemoved value: -{ - "description": "Last group_id to probe (inclusive). Defaults to 200. A single call may scan at most 500 ids; use multiple calls for wider ranges.", - "maximum": 10000, - "minimum": 1, - "type": "integer" -} - removed
Input schema / properties / start_idRemoved value: -{ - "description": "First group_id to probe (inclusive). Defaults to 1.", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" -} - removed
Input schema / properties / stop_after_consecutive_missesRemoved value: -{ - "description": "Early-exit heuristic: stop probing after this many consecutive 404/403 misses. Saves wall time on sparse id ranges. Defaults to 50.", - "maximum": 500, - "minimum": 1, - "type": "integer" -}
- Changed
list_memberships3 fields changed- changed
Input schema / properties / group_id / descriptionPrevious value: -"ID of the Loomio group whose memberships to list (required). The connector's bot user must be an admin (coordinator) of the group — Loomio only returns the member list, including email addresses, to group admins. For a non-admin bot this returns a clear 403 explaining the role requirement; names/usernames/ids (not emails) are still reachable via get_user_activity / list_events."New value: +"Group id (a non-member gets an empty list, not 403)." - changed
Input schema / properties / limit / descriptionPrevious value: -"Page size. Loomio defaults to 50."New value: +"Page size, 1-200. Default 50." - changed
Input schema / properties / offset / descriptionPrevious value: -"Page offset. Defaults to 0."New value: +"Page offset. Default 0."
- Changed
list_polls6 fields changed- added
Input schema / properties / description_max_charsAdded value: +{ + "description": "Chars per `details`; default 1500, 0 omits it, -1 = full.", + "maximum": 9007199254740991, + "minimum": -1, + "type": "integer" +} - removed
Input schema / properties / group_id / descriptionRemoved value: -"ID of the Loomio group whose polls to list (required)." - changed
Input schema / properties / limit / descriptionPrevious value: -"Page size. Loomio defaults to 50."New value: +"Page size, 1-200. Default 50." - changed
Input schema / properties / offset / descriptionPrevious value: -"Page offset. Defaults to 0."New value: +"Page offset. Default 0." - changed
Input schema / properties / status / descriptionPrevious value: -"Filter polls by status. Loomio defaults to 'active'."New value: +"'active' (default) = open, 'closed', 'all'." - added
Input schema / properties / strip_htmlAdded value: +{ + "description": "Plain text instead of HTML; default true.", + "type": "boolean" +}
- Added
list_thread_items - Added
list_threads - Changed
manage_memberships4 fields changed- changed
Input schema / properties / emails / descriptionPrevious value: -"Email addresses to ensure are members. Each address that isn't already a member is invited / added."New value: +"Addresses to ensure are members; new ones are invited." - changed
Input schema / properties / emails / items / patternPrevious value: -"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"New value: +"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$" - changed
Input schema / properties / group_id / descriptionPrevious value: -"ID of the Loomio group to modify (required). Caller must be a group admin."New value: +"Group id; the connector's user must be its admin." - changed
Input schema / properties / remove_absent / descriptionPrevious value: -"DANGEROUS. When true, Loomio REMOVES every existing member whose email is NOT in `emails`. Empty-emails (after dedupe) effectively removes the entire group. Default false. Only set true after reading list_memberships and confirming the diff with a human."New value: +"DANGEROUS: also revokes every member absent from `emails`, own user included. Default false."
- Added
search_content - Added
update_comment - Added
update_discussion - Added
update_poll
4 tool updates
v0.0.10- Removed
create_discussion - Removed
get_discussion - Removed
get_poll - Removed
list_events
12 tool updates
v0.0.6- First observed
create_comment - First observed
create_discussion - First observed
create_poll - First observed
get_discussion - First observed
get_poll - First observed
get_user_activity - First observed
list_discussions - First observed
list_events - First observed
list_groups - First observed
list_memberships - First observed
list_polls - First observed
manage_memberships
TDQS
Scored across 24 tools
Most tools target clearly distinct resources and actions, but the thread-reading surface (list_threads, list_discussions, list_polls, list_thread_items, get_thread_markdown, get_discussion, get_poll) has enough overlap that an agent may hesitate. The detailed descriptions largely resolve the ambiguity, but not perfectly.
All tools use consistent snake_case verb_noun naming (create_poll, list_groups, get_discussion, update_poll, delete_comment, etc.) with no mixed conventions or vague verbs.
24 tools is heavy for the domain and falls into the borderline 16-25 range. While each tool covers a real operation, the set could be consolidated, especially around separate list/read tools for threads, discussions, and polls.
CRUD is present for discussions, polls, and comments, but the Loomio decision-making core is incomplete: there is no tool to cast or manage a vote/stance, and group lifecycle operations are missing. Agents cannot fully participate in polls or manage groups end-to-end.
Maintenance
Related MCP Connectors
Connect Claude to Fathom meeting recordings, transcripts, and summaries
- platform7nOAuthtech.p7n
Connect Claude to your Platform7n workspaces — chat, links, and tasks. One-click OAuth.
WHOOP recovery, strain, sleep and workouts in Claude via official WHOOP OAuth. Free, open source.
Create projects, nodes, and tasks in UluP Spaces by conversation with Claude.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceConnects Claude AI to any development project (Django, Next.js, Laravel, etc.) with 15+ universal tools for shell, file, git, logs, Docker, tests, and more.1-
- AlicenseAqualityAmaintenanceCapsule CRM tools for Claude. Local install via npx, org-wide via Custom Connectors. Read-only mode supported.9232 npm5Apache 2.0
- AlicenseNot gradedqualityDmaintenanceConnects Claude Desktop to your Obsidian vault, enabling reading, writing, searching, and organizing notes locally.1MIT
- FlicenseNot gradedqualityBmaintenanceExposes locally-built AI tools to Claude, enabling article summarization, promo generation, and semantic search over an Obsidian vault.-