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_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.3/5.0
Behavior3/5

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

Annotations already establish readOnlyHint, openWorldHint, idempotentHint, and non-destructive behavior. The description adds the bundling behavior and orientation use case, but it does not disclose additional operational details such as rate limits, data freshness, or response-size implications. With such robust annotations, the description's extra behavioral context is adequate but not extensive.

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 sentences, each earning its place: the first states scope, the second states intended use, the third routes to the alternative. The most important information is front-loaded and there is no wasted wording.

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

Completeness5/5

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

For a tool with only three parameters, an output schema, and strong annotations, the description is complete. It tells the agent what the tool returns, when to use it, and which sibling handles the cases this tool does not.

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 each parameter already documented: group_id identifies the source, response_format explains concise vs detailed, and recent_message_count gives the range and default. The tool description adds no parameter-level meaning beyond the schema, so the baseline of 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?

The description states a specific action and resource: 'Get one group's metadata, member list, and recent messages in one call.' It clearly distinguishes this from siblings by emphasizing the bundled context retrieval, and it is not a tautology.

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?

The description explicitly says when to use it: 'to orient yourself in a group before reading further or replying.' It also names the alternative directly: 'For direct-message chats or for paging deeper into history, use read_messages instead.' This is strong routing guidance.

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

get_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?

Annotations already mark the tool as read-only and idempotent, and the description adds valuable behavioral context: it wraps the likes leaderboard, limits the member summary to leaderboard messages rather than full history, and explicitly discloses that the underlying endpoint is undocumented and may fail with guidance if retired. No contradiction with annotations.

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?

Four focused sentences: the purpose, the use case, a key scope limitation, and a failure-mode warning. Every sentence earns its place, and the most important purpose is front-loaded.

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

Completeness5/5

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

For a read-only summary tool with full schema coverage, strong annotations, and an output schema, the description is complete. It explains what results look like, notes the scope limitation, and warns about the undocumented dependency.

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?

The input schema provides 100% parameter coverage with descriptions for group_id, period, and response_format. The description adds general framing around period-based top-liked messages and output content, but it does not meaningfully extend the schema's parameter-level explanations. Baseline 3 is appropriate.

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

Purpose5/5

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

The opening line states a specific verb and resource: 'Summarize what mattered in a group: its most-liked recent messages.' It clearly differentiates from siblings by focusing on highlights via GroupMe's likes leaderboard rather than reading raw messages or sending messages.

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

Usage Guidelines4/5

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

The description gives clear context for when to use the tool: 'Use this to catch up on a busy group without reading everything.' It implies a contrast with full-message reading tools like read_messages, though it does not explicitly name alternatives or state 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_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.3/5.0
Behavior4/5

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

Beyond the annotations (readOnlyHint, idempotentHint, etc.), the description adds meaningful behavioral detail: recency ordering, merging of groups and DMs, inclusion of 'last-message previews and member counts,' and the presence of the IDs that downstream tools require. This goes beyond simply echoing the read-only safety profile.

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 tight sentences: the first states the core purpose, the second gives direct usage guidance, and the third explains the output's value for sibling tools. Every sentence earns its place with no filler or redundancy.

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?

Given the rich input schema (100% parameter coverage), full annotations, and presence of an output schema, the description is complete for an agent to select and invoke the tool correctly. It explains the tool's role, output characteristics, and how the returned IDs connect to other tools.

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 the schema already documents all three parameters. The description adds contextual color like 'merges groups and direct-message chats' and 'last-message previews and member counts,' but it does not substantially enrich the parameter semantics beyond what the schema already states.

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 opens with a specific action and resource: 'List the user's GroupMe conversations, most recently active first.' It also distinguishes itself from siblings by explaining that it 'merges groups and direct-message chats into one recency-sorted list' and provides the IDs that other tools need.

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

Usage Guidelines4/5

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

The description explicitly states when to use it: 'Use this first, whenever you need to find a conversation or the ids the other tools take.' It references sibling tools that consume its output ('read_messages and get_conversation_context'), though it does not explicitly contrast it with search_messages or other siblings.

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

react_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.8/5.0
Behavior5/5

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

Even though idempotentHint is already present in annotations, the description explains the behavioral consequence concretely: liking an already-liked message or unliking one never liked leaves it in the requested state. It also adds that the action is performed on the authenticated user's behalf and clarifies the meaning of conversation_id values. This goes well beyond the annotation and 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?

The description is compact and front-loaded: it states the action first, then usage context, then idempotence, then ID source. Every sentence earns its place with no filler or redundancy.

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

Completeness5/5

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

For a small, three-parameter mutation tool with an output schema and strong annotations, the description covers what the tool does, how to use it correctly, where the required IDs come from, and its idempotent behavior. Nothing essential for correct invocation is missing.

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

Parameters5/5

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

Schema description coverage is 100%, but the description adds valuable meaning beyond the schema: conversation_id can be a group id or a composite direct-chat id like '123+456', and both IDs come from read_messages with response_format='detailed'. This is critical guidance an agent would not get from the generic schema property descriptions.

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 opens with a precise verb and resource: 'Like a GroupMe message, or remove your like from one.' It clearly states the operation and distinguishes it from sending a reply ('without posting a reply'), making it easy for an agent to know what this tool does relative to send_message.

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 an explicit 'Use this to' clause and frames it for acknowledgement scenarios rather than replying, which differentiates it from the sibling send_message. It also tells the agent exactly where to obtain IDs (read_messages with response_format='detailed'), though it does not explicitly name alternatives or say 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.

read_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.5/5.0
Behavior5/5

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

Beyond the annotations, the description discloses that results are ordered oldest-first, sender names are resolved, attachments are normalized, and an empty page is a normal response rather than an error. These are important behavioral traits an agent would not infer from readOnlyHint, openWorldHint, idempotentHint, or destructiveHint.

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?

Four sentences with each earning its place: the first states the core action, the second gives usage context and a prerequisite, the third summarizes response normalization, and the fourth prevents a common misinterpretation. No filler or redundancy.

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?

Combined with an output schema, the rich input schema, and annotations, the description covers what is needed to select and invoke the tool: scope, ordering, pagination expectations, normal edge-case behavior, and prerequisite data. An agent can confidently call this tool with just the description plus schema.

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 the schema already documents all five parameters in detail, including pagination semantics, the oneOf conversation format, and the response_format enum. The description adds context about oldest-first ordering and paging but does not need to repeat param-level details.

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 clearly states a specific verb and resource: reading messages from one GroupMe conversation, oldest first. It also implicitly distinguishes itself from list_conversations by telling the agent to obtain the conversation id from that sibling tool first, and from send_message by focusing on reading. This is a clear, usable purpose statement.

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

Usage Guidelines4/5

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

The description explicitly tells the agent when to use this tool: to read or page through a specific group or direct-message chat once the id is known from list_conversations. It does not explicitly discuss when not to use it versus search_messages or get_conversation_context, so it stops short of full alternative routing.

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

search_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.9/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true and idempotentHint=true, and the description adds substantial behavioral detail beyond that: it scans backwards, matches case-insensitive substrings, stops under three named conditions, and tells the agent to check oldest_message_reached and note before concluding absence. This is rich, actionable transparency.

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 sentences with no wasted words. The main purpose is front-loaded, the usage guideline follows, and the operational caveat about scan depth is placed at the end where it is most useful as a caution.

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

Completeness5/5

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

For a 6-parameter search tool with 100% schema coverage, rich annotations, and an output schema, the description is complete. It covers the algorithm, stop conditions, case-insensitivity, the read_messages alternative, and the critical caveat about interpreting scan limits.

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 description coverage is 100%, so the baseline is 3. The description adds value by explaining how the parameters interact: query matches message text, sender_name matches sender display names, both are case-insensitive substrings, and limit/max_messages_scanned act as stop conditions during the backward scan. This goes beyond the schema's individual field descriptions.

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 opens with a specific verb and resource: 'Search one conversation's message history for matching messages.' It clearly distinguishes the tool from read_messages by framing it as the targeted alternative to manual paging, so an agent can tell them apart 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?

The description explicitly says when to use this tool — for finding specific messages like 'who mentioned pizza?' — and names the alternative read_messages for manual paging. This gives the agent a clear routing decision with a concrete condition.

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

send_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.7/5.0
Behavior5/5

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

The description discloses non-idempotence ('Each call sends a new message — calling twice posts twice'), which is critical and goes beyond the annotations' idempotentHint=false. It also reveals authenticated-user posting context and that replies render threaded in clients, adding genuine behavioral insight.

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 dense sentences each earn their place: purpose, usage/prerequisite/non-idempotence, and reply mechanism. The key constraint is front-loaded and there is no redundant or vague language.

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?

Given the full schema, output schema, and annotations, the description supplies the missing orchestration details: where ids come from, how replies behave, and that duplicate calls produce duplicates. An agent has everything needed to invoke this tool 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 value by telling the agent where parameter values come from (conversation ids from list_conversations, reply id from read_messages), which enriches the schema's per-field descriptions.

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 first sentence states a specific verb and resource: 'Send a message to a GroupMe group or direct-message chat.' It also clarifies that it posts as the authenticated user, which disambiguates it from read/search siblings despite not naming them.

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

Usage Guidelines4/5

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

The description explicitly says to use this 'once you know where to send' and points to list_conversations for ids, giving a clear prerequisite. It also explains the reply flow via read_messages. It stops short of explicitly saying when not to use it or naming react_to_message as the alternative for reactions, so it misses a 5.

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. Dates show when Glama detected each change.

  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.6/5.0
Disambiguation5/5

Each tool maps to a distinct action: listing conversations, reading messages, sending, searching, reacting, and fetching context or highlights. The only potential overlap is get_conversation_context including recent messages, but its orientation-specific purpose is clearly separated from read_messages for paging.

Naming Consistency5/5

All tool names follow a clear verb-first snake_case pattern: send_message, list_conversations, read_messages, search_messages, react_to_message. The style is uniform and predictable, making the set easy for an agent to navigate.

Tool Count5/5

Seven tools is well-scoped for a GroupMe messaging server. Each tool serves a distinct user need without redundancy, and the count is within the ideal 3–15 range for a focused domain.

Completeness4/5

The core messaging workflow is well covered: list, read, search, send, reply, react, and get context. Minor gaps exist around starting new conversations or sending media attachments, but these do not create dead ends for the primary read-and-respond use case.

Maintenance

ActivityMaintained
ResponsivenessUnresponsive

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • Messaging tools for AI agents: send messages, manage chats, groups and channels.

    1
  • Chat where AI agents are first-class members, with their own identity and permissions.

    1
  • Carbon Voice MCP serves as a bridge that connects AI assistants like ChatGPT, Claude, and Cursor to a user's Carbon Voice account, turning voice messages and conversations into a private, on-demand knowledge base. It provides 28 specialized tools for comprehensive voice messaging management, including creating and sending messages, accessing conversation history with instant transcription, running AI actions (summarization, TLDR generation, meeting notes), and managing workspace collaboration through folders, contacts, and team communications.

  • Instagram for AI agents: publish, read comments and DMs, insights, and engage from your account.

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
    -

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/oddrationale/groupme-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server