Skip to main content

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).

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

Metadata

Release files for groupme-mcp-server 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for groupme-mcp-server 0.2.1
File Size Uploaded
groupme_mcp_server-0.2.1.tar.gz 38.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for groupme-mcp-server 0.2.1
File Interpreter ABI Platform
groupme_mcp_server-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 85.2 kB

Release files / groupme_mcp_server-0.2.1.tar.gz

Download URL groupme_mcp_server-0.2.1.tar.gz
Size 38.0 kB
Tags Source
SHA-256 checksum
How to use checksums
3e8c6ba5943f1e8c6076c395194ae3e7c7486f74f21d17197c74ce4466fd54aa
BLAKE2b-256 checksum
How to use checksums
c6abb72d3c2e3f320ce4b0c8959c7f779bac799854c9e08cc89eb9c0459f9234
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release files / groupme_mcp_server-0.2.1-py3-none-any.whl

Download URL groupme_mcp_server-0.2.1-py3-none-any.whl
Size 47.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2c5cded1bed9b5a2114db41eb207406e3bd1cd62c0c73cf0d4f9a27b54672168
BLAKE2b-256 checksum
How to use checksums
d02ca8a72012778c46fb7889748f2433a3ae41fbf88ba941cfe254384331f04a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page