Skip to main content
Glama
oddrationale

groupme-mcp-server

by oddrationale

groupme-mcp-server

CI codecov OpenSSF Scorecard PyPI Python License: MIT Ruff

An MCP server for GroupMe, built with FastMCP.

It is a set of agentic tools, not an endpoint wrapper: instead of mirroring the GroupMe API v3 route-for-route, each tool does one job an assistant actually needs — merging groups and DMs into a single inbox, paginating history with cursors, searching client-side because GroupMe has no search endpoint, and reporting honestly when a result is truncated.

Status: early. Read, search/highlights, and the core write tools (sending messages, likes) are implemented; image upload is not yet.

Tools

Tool

What it does

list_conversations

Merge groups and DMs into one recency-sorted list with last-message previews.

read_messages

Read one group or DM conversation, oldest first, with a next_before_id cursor.

get_conversation_context

One group's metadata, member list, and recent messages in a single call.

search_messages

Search a conversation's history client-side (GroupMe has no search API), with honest scan accounting.

get_highlights

A group's top-liked messages for a day/week/month plus a member summary.

send_message

Post to a group or DM, optionally as a reply or with a GroupMe-hosted image.

react_to_message

Like or unlike one message (ids from read_messages detailed format).

The read tools accept response_format: "concise" (default, human-readable) or "detailed" (full ids and metadata).

Related MCP server: Instagram DMs MCP

Connecting to the hosted server

The server is deployed on Prefect Horizon at:

https://groupme.fastmcp.app/mcp

The deployment is protected by Horizon's built-in auth: clients sign in via OAuth, and only users the deployment owner has authorized can connect — unauthenticated requests are rejected. Note that this is a single-tenant deployment (see Security): every authorized client acts as the one GroupMe account whose token is configured on the server.

Running locally

The package runs as a stdio MCP server. Get a GroupMe access token from https://dev.groupme.com (sign in and copy your access token), then:

GROUPME_ACCESS_TOKEN=... uvx groupme-mcp-server

Or configure an MCP client to launch it:

{
  "mcpServers": {
    "groupme": {
      "command": "uvx",
      "args": ["groupme-mcp-server"],
      "env": {
        "GROUPME_ACCESS_TOKEN": "your-token-from-dev.groupme.com"
      }
    }
  }
}

Configuration

Everything is configured through environment variables (GROUPME_* may also come from a local .env file — see .env.example).

Variable

Default

Description

GROUPME_ACCESS_TOKEN

(unset)

GroupMe API token from https://dev.groupme.com. Optional at startup; required when a tool calls the API.

GROUPME_LOG_LEVEL

INFO

Verbosity of the server's own loggers: DEBUG, INFO, WARNING, ERROR, or CRITICAL.

GROUPME_API_BASE_URL

https://api.groupme.com/v3

GroupMe REST API base URL (override mainly for testing).

GROUPME_IMAGE_API_BASE_URL

https://image.groupme.com

GroupMe image-upload service base URL. Reserved: unused until image upload is implemented.

OTEL_EXPORTER_OTLP_ENDPOINT

(unset)

OTLP/HTTP collector endpoint. Setting it turns tracing on.

OTEL_EXPORTER_OTLP_HEADERS

(unset)

Extra headers for the OTLP exporter (e.g. authorization=Bearer%20...).

OTEL_SERVICE_NAME

groupme-mcp-server

The service.name resource attribute on exported spans.

OTEL_SDK_DISABLED

(unset)

Set to true/1 to keep tracing off even when an endpoint is set.

FASTMCP_LOG_LEVEL

INFO

Verbosity of FastMCP's own fastmcp.* loggers.

Security

  • Single-tenant by design. The server holds exactly one GroupMe token and every tool acts as that token's owner — reading their conversations, posting as them, liking as them. Anyone allowed to connect (locally, or through Horizon's auth on the hosted deployment) gets that full identity; there is no per-client GroupMe account mapping.

  • The token never crosses the MCP boundary. Clients never send or receive it: the token lives server-side, goes to GroupMe only as the X-Access-Token request header (never in URLs), is excluded from tool output and error messages, and is registered for redaction if OTel header capture is enabled.

  • Hosted-deployment caveat. On Horizon, tool requests and responses pass through Prefect's infrastructure and may appear in its request/payload logs. Message content read or written through the hosted server is visible to whoever operates the deployment; run the server locally if that is not acceptable.

Report vulnerabilities through private vulnerability reporting, not public issues — see SECURITY.md.

Observability

  • Logs are structured single lines on stderr (stdout would corrupt the stdio transport), each carrying the current OTel trace_id/span_id when a span is active. GROUPME_LOG_LEVEL controls the server's own loggers.

  • Traces are opt-in: when OTEL_EXPORTER_OTLP_ENDPOINT is set (and OTEL_SDK_DISABLED is not truthy), the server installs an OTLP/HTTP span exporter. FastMCP emits a span for every tools/call, and outbound GroupMe HTTP requests get client spans via instrumented httpx2 transports — without an endpoint everything no-ops.

Development

Requires uv and Python 3.13+.

git clone https://github.com/oddrationale/groupme-mcp-server.git
cd groupme-mcp-server
uv sync --all-groups
uv run lefthook install     # install the git hooks

Common tasks:

Command

What it does

uv run ruff format .

Format.

uv run ruff check --fix .

Lint and autofix.

uv run ty check

Type check.

uv run pytest

Run tests. Fails below 100% coverage.

uv run pytest --no-cov -k name

Run a subset without the coverage gate.

uv run pytest -m integration --no-cov

Opt-in live/e2e suites (see tests/integration/).

uv run fastmcp inspect src/groupme_mcp_server/server.py:mcp

See what Horizon sees.

Coverage is enforced at 100% (branch coverage included). If a line is genuinely untestable, exclude it deliberately with # pragma: no cover and say why in the PR — do not lower the threshold.

Deployment

The hosted server is deployed on Prefect Horizon, which builds directly from this repository via its GitHub App.

  • Entrypoint: src/groupme_mcp_server/server.py:mcp

  • Dependencies: installed with uv sync --frozen --no-dev, so uv.lock must be committed and current or the build fails

  • Environment variables: registered in the Horizon UI (GROUPME_ACCESS_TOKEN at minimum)

  • Auth: Horizon's built-in OAuth — clients must present a bearer token

The production target tracks main and deploys only after CI passes; every pull request gets its own preview deployment. There is no deploy step in GitHub Actions — CI gates quality and security, Horizon does the shipping.

Contributing

See CONTRIBUTING.md.

License

MIT © Dariel Dato-on

Available Tools

7 tools
get_conversation_contextGet Conversation ContextA
Read-onlyIdempotent

Get one group's metadata, member list, and recent messages in one call.

Use this to orient yourself in a group before reading further or replying: it bundles what would otherwise take several calls. For direct-message chats or for paging deeper into history, use read_messages instead.

ParametersJSON Schema
NameRequiredDescriptionDefault
group_idYesThe group's id (from ``list_conversations``).
response_formatNo``"concise"`` (default) for names, nicknames, roles, and relative ages; ``"detailed"`` adds user ids, the share URL, and ISO timestamps.concise
recent_message_countNoHow many recent messages to include (1-100).

Output Schema

ParametersJSON Schema
NameRequiredDescription
nameYes
membersNo
group_idYes
image_urlNo
share_urlNo
updated_atNo
descriptionNo
last_activeNo
member_countNo
message_noteNo
creator_user_idNo
recent_messagesNo

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), so the bar is lower. The description still adds real behavioral context: it bundles three kinds of data that 'would otherwise take several calls' and is scoped to group conversations only, not DMs. It does not mention pagination or result limits, but recent_message_count's 1-100 bound is in the schema.

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

Conciseness5/5

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

Three short sentences, no filler. The primary capability is front-loaded and the routing guidance follows immediately after. Every sentence earns its place.

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

Completeness5/5

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

An output schema exists, so return values need not be explained, and the description still summarizes what comes back (metadata, members, recent messages). Combined with 100% schema coverage and full annotation coverage, an agent has everything needed to select and invoke this tool correctly.

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

Parameters3/5

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

Schema description coverage is 100% and each parameter is documented in the schema, including the concise/detailed enum semantics and the 1-100 message bound. The description adds no parameter-level detail beyond what the schema already provides, so the baseline 3 applies.

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

Purpose5/5

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

States a specific verb and resource (get one group's metadata, member list, recent messages) plus the key scope constraint that it does it 'in one call'. This distinguishes it clearly from read_messages and list_conversations without needing to open either schema.

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

Usage Guidelines5/5

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

Explicitly names the situation to use it ('orient yourself in a group before reading further or replying') and the situations not to ('direct-message chats', 'paging deeper into history'), routing the agent to the named alternative read_messages. When/when-not/alternative are all present.

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

get_highlightsGet HighlightsA
Read-onlyIdempotent

Summarize what mattered in a group: its most-liked recent messages.

Use this to catch up on a busy group without reading everything: it wraps GroupMe's likes leaderboard into the period's top-liked messages (sender, like count, text preview) plus a per-member summary of who was most liked and most represented among them. The member summary covers only the leaderboard's messages, not the group's full history. The leaderboard endpoint is undocumented; if GroupMe has retired it, this tool fails with guidance rather than guessing.

ParametersJSON Schema
NameRequiredDescriptionDefault
periodNoThe leaderboard window: ``"day"``, ``"week"`` (default), or ``"month"``.week
group_idYesThe group's id (from ``list_conversations``).
response_formatNo``"concise"`` (default) for names, previews, and relative ages; ``"detailed"`` adds user ids and ISO timestamps.concise

Output Schema

ParametersJSON Schema
NameRequiredDescription
noteNo
periodYes
group_idYes
top_membersYes
top_messagesYes

TDQS

A4.5/5.0
Behavior5/5

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

Beyond the annotations (readOnly, idempotent, openWorld), the description discloses a real data-scope limitation — the member summary covers only leaderboard messages, not full history — and an error behavior: the undocumented endpoint fails with guidance rather than guessing. These are exactly the traits annotations cannot express.

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

Conciseness5/5

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

Three compact movements — what it does, when to use it, and the caveats — front-loaded with the core purpose and no filler sentences. Every clause adds information.

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

Completeness5/5

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

With an output schema present, return formatting need not be explained, yet the description still previews contents (sender, like count, text preview) and covers the scope limitation and failure mode. Nothing needed 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.

Parameters3/5

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

Schema description coverage is 100% with enums documented for period and response_format, so the schema carries parameter semantics. The description adds little beyond 'the period's top-liked messages,' which merely restates the period parameter.

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

Purpose5/5

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

The description states a specific verb ('summarize') and resource ('what mattered in a group: its most-liked recent messages'), and distinguishes itself from read_messages by framing the tool as catching up 'without reading everything.' An agent can tell what this returns 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.

Usage Guidelines4/5

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

'Use this to catch up on a busy group without reading everything' gives clear context for when to reach for it, and implicitly contrasts with read_messages/search_messages. It stops short of naming an explicit alternative or stating when NOT to use it.

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

list_conversationsList ConversationsA
Read-onlyIdempotent

List the user's GroupMe conversations, most recently active first.

Use this first, whenever you need to find a conversation or the ids the other tools take: it merges groups and direct-message chats into one recency-sorted list with last-message previews and member counts. Every entry carries the group_id or other_user_id that read_messages and get_conversation_context need.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNoWhich conversations to include - ``"groups"``, ``"dms"``, or ``"all"`` (default).all
limitNoMaximum conversations to return (1-100).
response_formatNo``"concise"`` (default) for names, previews, and relative ages; ``"detailed"`` adds descriptions, share URLs, creator ids, and ISO timestamps.concise

Output Schema

ParametersJSON Schema
NameRequiredDescription
noteNo
countYes
conversationsYes

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnly/idempotent/destructive=false, so safety is covered. The description adds genuine behavioral context beyond that: the recency sort order, merged group/DM listing, last-message previews, member counts, and the fact that each entry carries the ids other tools need.

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

Conciseness5/5

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

Two sentences, front-loaded with the core action, then the routing rationale. No filler, no repetition of the title or schema.

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

Completeness4/5

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

With an output schema present and annotations covering the safety profile, the description is nearly complete; it even sketches the return shape. Missing only pagination/truncation behavior given the 1-100 limit parameter, which is a minor gap.

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

Parameters3/5

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

Schema description coverage is 100%, so 'kind', 'limit', and 'response_format' are already fully documented with defaults and enums. The description adds no param-level meaning (e.g., no guidance on which kind to pick), so the baseline 3 applies.

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

Purpose5/5

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

States a specific verb and resource ('List the user's GroupMe conversations') plus the ordering ('most recently active first') and scope ('merges groups and direct-message chats into one recency-sorted list'). An agent can distinguish this from siblings like search_messages or read_messages immediately.

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

Usage Guidelines5/5

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

Explicitly says 'Use this first, whenever you need to find a conversation or the ids the other tools take,' naming the downstream consumers (read_messages, get_conversation_context). This gives a clear when-to-use condition and routes the agent to the correct entry point.

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

react_to_messageReact To MessageA
Idempotent

Like a GroupMe message, or remove your like from one.

Use this to react to a specific message on the authenticated user's behalf — acknowledging something without posting a reply. Both actions are idempotent: liking an already-liked message (or unliking one you never liked) leaves it in the requested state. Ids come from read_messages with response_format="detailed": use its conversation_id (a group id, or a composite direct-chat id like "123+456") and message id.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYes``"like"`` to like it, ``"unlike"`` to remove your like.
message_idYesThe message to react to.
conversation_idYesThe conversation holding the message.

Output Schema

ParametersJSON Schema
NameRequiredDescription
actionYes
message_idYes
confirmationYes
conversation_idYes

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare idempotentHint=true, destructiveHint=false, readOnlyHint=false, openWorldHint=true. The description earns credit by spelling out what idempotency concretely means ('liking an already-liked message ... leaves it in the requested state') and by noting the action is on the authenticated user's behalf. It does not mention rate limits or failure behavior, but the annotation bar is already met.

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

Conciseness4/5

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

Front-loaded with the core action, then the usage context and id-sourcing details. Every sentence carries information; the RST double-backtick artifacts and slight redundancy around message_id are the only minor drag.

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

Completeness5/5

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

An output schema exists, so return values need not be explained. Combined with annotations, the description covers the action semantics, idempotency, auth scope, and how to source the required ids — everything needed to invoke it correctly.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3. The description adds genuine meaning beyond the schema by explaining where the ids originate (read_messages with response_format='detailed') and warning that conversation_id may be a group id or a composite direct-chat id like '123+456'.

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

Purpose5/5

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

The opening sentence gives a specific verb+resource ('Like a GroupMe message, or remove your like from one') and the scope is unambiguous. It is clearly distinguishable from send_message because the follow-up states the purpose is 'acknowledging something without posting a reply.'

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

Usage Guidelines4/5

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

It gives clear positive context ('react to a specific message on the authenticated user's behalf') and implicitly routes away from send_message by noting no reply is posted. It also tells the agent where to obtain ids. It never explicitly names an alternative tool or states a when-not-to-use condition, so it stops short of a 5.

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

read_messagesRead MessagesA
Read-onlyIdempotent

Read messages from one GroupMe conversation, oldest first.

Use this to read or page through the history of a specific group or direct-message chat once you know its id (from list_conversations). Sender names are resolved and attachments are normalized (image URLs, reply/mention summaries). An empty page is a normal answer, not an error: it means the conversation has no messages in the requested range.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum messages to return (1-100). Direct chats may return fewer per page regardless of ``limit``.
since_idNoRead the most recent messages newer than this message id.
before_idNoRead messages older than this message id (use the previous page's ``next_before_id``). At most one of ``before_id`` and ``since_id`` may be given.
conversationYesWhich conversation to read: ``{"kind": "group", "group_id": ...}`` or ``{"kind": "direct", "other_user_id": ...}``.
response_formatNo``"concise"`` (default) for sender names, text, relative ages, and like counts; ``"detailed"`` adds sender ids, conversation ids, and ISO timestamps.concise

Output Schema

ParametersJSON Schema
NameRequiredDescription
noteNo
messagesYes
next_before_idNo

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description adds real value beyond that: sender names are resolved, attachments are normalized into image URLs and reply/mention summaries, and an empty page is explicitly a normal answer rather than an error.

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

Conciseness5/5

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

Three short sentences, front-loaded with the verb and scope, then usage, then normalization and empty-page semantics. Every sentence carries information an agent needs and nothing is repeated from the schema.

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

Completeness5/5

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

An output schema exists, so return values need not be explained. The description covers the remaining agent-facing concerns for this tool: how to obtain the conversation id, how paging works, what normalization to expect, and how to interpret an empty result.

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

Parameters3/5

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

Schema description coverage is 100%, so limit, since_id, before_id, conversation and response_format are already fully documented in the schema, including the mutual exclusivity of before_id and since_id. The description adds no syntax or format detail beyond the schema, so the baseline 3 is correct.

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

Purpose5/5

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

States a specific verb and resource ('Read messages from one GroupMe conversation') plus a scoping detail ('oldest first') that an agent can act on. It also anchors the tool to the list_conversations sibling for obtaining the conversation id, distinguishing it from search_messages and get_conversation_context.

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

Usage Guidelines4/5

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

Gives clear context: use it to read or page through one conversation's history once the id is known from list_conversations, and notes that empty pages are normal. It does not explicitly state when to prefer search_messages or get_highlights instead, so it falls short of a full when/when-not/alternative statement.

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

search_messagesSearch MessagesA
Read-onlyIdempotent

Search one conversation's message history for matching messages.

Use this to find specific messages ("who mentioned pizza?", "what did Ada say last week?") instead of paging manually with read_messages. GroupMe has no search API, so this scans backwards from the newest message, matching query against message text and sender_name against sender names (both case-insensitive substrings), until limit matches are found, the oldest message is reached, or max_messages_scanned messages have been examined. The result reports exactly how far the scan got — check oldest_message_reached and note before concluding something was never said.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoStop after this many matches (1-100).
queryYesText to look for in message text. May be empty only when ``sender_name`` is given (a sender-only search).
sender_nameNoOnly match messages whose sender's display name contains this.
conversationYesWhich conversation to search: ``{"kind": "group", "group_id": ...}`` or ``{"kind": "direct", "other_user_id": ...}`` (ids from ``list_conversations``).
response_formatNo``"concise"`` (default) for sender names, text, relative ages, and like counts; ``"detailed"`` adds sender ids, conversation ids, and ISO timestamps.concise
max_messages_scannedNoStop after examining this many messages (1-5000); a hit cap is reported in ``note``, never silent.

Output Schema

ParametersJSON Schema
NameRequiredDescription
noteNo
countYes
matchesYes
next_before_idNo
messages_scannedYes
oldest_message_reachedYes

TDQS

A4.8/5.0
Behavior5/5

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

Annotations only cover safety (readOnly/idempotent/non-destructive/openWorld); the description adds substantial mechanics the annotations cannot: no native search API, backward scan from newest, case-insensitive substring matching, the three termination conditions, and the caveat to inspect oldest_message_reached and note before concluding a message was never sent. This is exactly the kind of result-interpretation context 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.

Conciseness4/5

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

Front-loaded with purpose, then usage, then mechanics, in three tight paragraphs with no filler. Slightly dense and longer than strictly necessary, but nearly every clause carries operational information.

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

Completeness5/5

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

Covers the full picture for a six-parameter search tool: what it does, when to prefer it, how matching and scanning terminate, and how to read the result fields. An output schema exists, so the description correctly stops short of enumerating return structure while still flagging the fields that change interpretation.

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

Parameters4/5

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

Schema coverage is 100%, so baseline is 3. The description goes beyond it by explaining that query matches message text and sender_name matches sender names, both as case-insensitive substrings, and by framing limit and max_messages_scanned as scan-stopping conditions rather than just numeric bounds.

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

Purpose5/5

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

States a specific verb (search), a bounded resource (one conversation's message history), and the match target, which cleanly separates it from read_messages and get_conversation_context. The scope word 'one conversation' prevents the agent from assuming a global search.

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

Usage Guidelines5/5

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

Explicitly routes the agent: use this to find specific messages instead of paging manually with read_messages, backed by concrete example queries. The when-to-use condition and the alternative it replaces are both named.

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

send_messageSend MessageA

Send a message to a GroupMe group or direct-message chat.

Use this to post as the authenticated user once you know where to send (ids come from list_conversations). Each call sends a new message — calling twice posts twice. To reply to a specific message, pass its id (from read_messages) as reply_to_message_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYesThe message text, at most 1000 characters. May be empty only when ``image_url`` is given.
image_urlNoImage to attach. Only GroupMe image-service URLs (``https://i.groupme.com/...``) are supported for now; other image URLs are rejected with guidance.
conversationYesWhere to send: ``{"kind": "group", "group_id": ...}`` or ``{"kind": "direct", "other_user_id": ...}``.
reply_to_message_idNoId of the message being replied to, attached as a GroupMe reply so clients render it threaded.

Output Schema

ParametersJSON Schema
NameRequiredDescription
kindYes
textYes
sent_atYes
group_idNo
message_idYes
attachmentsNo
other_user_idNo
conversation_idNo

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=false, idempotentHint=false, openWorldHint=true, so the safety profile is covered. The description reinforces non-idempotency in plain language ('calling twice posts twice') and notes it posts 'as the authenticated user', adding auth context, but says nothing about failure modes, rate limits, or the open-world/external nature beyond the annotation.

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

Conciseness5/5

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

Three short sentences/paragraphs, front-loaded with purpose, then prerequisites, then the reply variant. No filler and no repetition of schema details.

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

Completeness5/5

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

An output schema exists, so return values need no explanation. For a non-idempotent send tool, the description covers target-dependent ids, the double-send hazard, and the reply option — everything an agent needs to invoke it correctly.

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

Parameters3/5

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

Schema description coverage is 100%, so all four parameters are already documented, including the conversation oneOf shape and the image_url restriction. The description only restates the reply_to_message_id usage and id provenance, adding little beyond the schema's own text; baseline 3 applies.

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

Purpose5/5

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

States a specific verb ('send') and resource ('a message to a GroupMe group or direct-message chat'), covering both target types. An agent can immediately distinguish it from siblings like read_messages or list_conversations, which are only mentioned as id sources.

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

Usage Guidelines5/5

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

Explicitly says when to use it ('once you know where to send', ids from list_conversations), warns that each call posts a new message, and names the alternative path for replies ('to reply to a specific message, pass its id'). Prerequisite ordering and the reply use-case are both spelled out.

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

Tool Schema Changelog

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

  1. 7 tool updatesv0.2.0
    • First observedget_conversation_context
    • First observedget_highlights
    • First observedlist_conversations
    • First observedreact_to_message
    • First observedread_messages
    • First observedsearch_messages
    • First observedsend_message

TDQS

A4.4/5.0

Scored across 7 tools

Disambiguation4/5

Most tools have clearly distinct purposes: search vs. paging vs. highlights vs. sending vs. reacting. The only mild overlap is read_messages vs. get_conversation_context, since both return recent messages, but the descriptions explicitly differentiate orientation-in-a-group from deep paging.

Naming Consistency5/5

All seven tools follow a consistent snake_case verb_noun pattern (list_conversations, read_messages, get_conversation_context, search_messages, get_highlights, send_message, react_to_message). No style mixing or vague verbs.

Tool Count5/5

Seven tools is well-scoped for a messaging integration, with discovery, reading, searching, summarizing, sending, and reacting each earning a place. Nothing feels redundant or bloated.

Completeness4/5

Covers the core lifecycle: find conversations, read, search, summarize, send, and react. Group or conversation creation, membership management, message deletion, and media sending are absent, but agents can work around these for typical read-and-post flows.

Maintenance

ActivityMaintained
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables AI models to interact with messages from various messaging platforms (Mobile, Mail, WhatsApp, LinkedIn, Slack, Twitter, Telegram, Instagram, Messenger) through a standardized interface.
    3
    16
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to read, send, and manage Instagram direct messages, including viewing conversations, sending DMs to users, reacting to messages, and searching for users by username.
    10
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI assistants to read, search, and send iMessages with features like contact name resolution, session grouping, and attachment listing. It provides intent-aligned tools to efficiently navigate conversation history and manage messages through natural language queries.
    6
    MIT
  • F
    license
    B
    quality
    B
    maintenance
    An MCP server that integrates with the GroupMe API v3 to allow AI assistants to manage groups, messages, members, and bots. It enables comprehensive interaction with the GroupMe platform, including sending direct messages, liking content, and managing user blocks.
    29
    -