groupme-mcp-server
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-Tokenrequest 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_idwhen a span is active.GROUPME_LOG_LEVELcontrols the server's own loggers. - Traces are opt-in: when
OTEL_EXPORTER_OTLP_ENDPOINTis set (andOTEL_SDK_DISABLEDis not truthy), the server installs an OTLP/HTTP span exporter. FastMCP emits a span for everytools/call, and outbound GroupMe HTTP requests get client spans via instrumentedhttpx2transports — 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, souv.lockmust be committed and current or the build fails - Environment variables: registered in the Horizon UI
(
GROUPME_ACCESS_TOKENat 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
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file groupme_mcp_server-0.2.0.tar.gz.
File metadata
- Download URL: groupme_mcp_server-0.2.0.tar.gz
- Upload date:
- Size: 38.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7d400161d2df8399831fc81fa017436dd0c50ed4905a2003ce00a196f8815c5a
|
|
| MD5 |
e22d94ca10f44d00ee432166e1d673a3
|
|
| BLAKE2b-256 |
c86c305454bcf990243068b56281cd99c65e315b27d26c801b536b935e485b1f
|
Provenance
The following attestation bundles were made for groupme_mcp_server-0.2.0.tar.gz:
Publisher:
release.yml on oddrationale/groupme-mcp-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
groupme_mcp_server-0.2.0.tar.gz -
Subject digest:
7d400161d2df8399831fc81fa017436dd0c50ed4905a2003ce00a196f8815c5a - Sigstore transparency entry: 2638758388
- Sigstore integration time:
-
Permalink:
oddrationale/groupme-mcp-server@330bde7cf4bcb705e639d5e3dd32854921cb04fb -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/oddrationale
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@330bde7cf4bcb705e639d5e3dd32854921cb04fb -
Trigger Event:
push
-
Statement type:
File details
Details for the file groupme_mcp_server-0.2.0-py3-none-any.whl.
File metadata
- Download URL: groupme_mcp_server-0.2.0-py3-none-any.whl
- Upload date:
- Size: 47.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
74002c1df43e3be9fde277ec3a9fe2b3483932d225c8ef0a39a5d0be8d8565d9
|
|
| MD5 |
f42a9df6d33e3279a4ec8af979ec2f29
|
|
| BLAKE2b-256 |
48c1245ef79bf3b2e138bba9c0803c0eec2c6e4904db22870277d34b745c8839
|
Provenance
The following attestation bundles were made for groupme_mcp_server-0.2.0-py3-none-any.whl:
Publisher:
release.yml on oddrationale/groupme-mcp-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
groupme_mcp_server-0.2.0-py3-none-any.whl -
Subject digest:
74002c1df43e3be9fde277ec3a9fe2b3483932d225c8ef0a39a5d0be8d8565d9 - Sigstore transparency entry: 2638758415
- Sigstore integration time:
-
Permalink:
oddrationale/groupme-mcp-server@330bde7cf4bcb705e639d5e3dd32854921cb04fb -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/oddrationale
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@330bde7cf4bcb705e639d5e3dd32854921cb04fb -
Trigger Event:
push
-
Statement type: