Model Context Protocol server for Meetup.com
727
Organizer-focused MCP server for managing a single Meetup group. Runs as a persistent HTTP service via Docker Compose — start it once, connect from any Claude Code session.
This server is intentionally simple:
Use your LLM to generate event content. Use this MCP server to execute Meetup operations safely.
authorize — OAuth2 authorization flow (first run only)get_group — group metadata and member countsearch_events — search by status: upcoming, past, draftget_event — full event details by IDlist_venues — known venues for the groupcreate_event — creates as DRAFT by defaultedit_event — update title, description, datetime, duration, venue, directions, featured photoadd_event_speaker — add structured speaker details to an eventupdate_event_speaker — edit structured speaker details or speaker photoremove_event_speaker — remove structured speaker details from an eventattach_event_speaker_photo — attach an uploaded photo to the event speaker profilepublish_event — gated behind MEETUP_ALLOW_PUBLISH=truecreate_event_photo_upload — get a direct upload ticket (photoId + uploadUrl)attach_event_photo — attach an uploaded photo to an eventMEETUP_GROUP_URLNAMEorganizer vs read_only)organizer modeMEETUP_ALLOW_PUBLISH=false)Policy violations return errors prefixed with POLICY_DENIED.
https://www.meetup.com/api/oauth/create/http://127.0.0.1:8787/meetup/oauth/callbackCopy .env.example to .env and fill in your values:
cp .env.example .env
MEETUP_GROUP_URLNAME=your-group-urlname
MEETUP_MODE=organizer
MEETUP_ALLOW_PUBLISH=false
MEETUP_OAUTH_KEY=your-consumer-key
MEETUP_OAUTH_SECRET=your-consumer-secret
dotnet publish src/Meetup.McpServer/Meetup.McpServer.csproj /t:PublishContainer
docker compose up -d
The server runs on http://localhost:5180/mcp and restarts automatically unless explicitly stopped.
The included .mcp.json points Claude Code at the running server:
{
"mcpServers": {
"meetup": {
"type": "http",
"url": "http://localhost:5180/mcp"
}
}
}
The first time you make any API call, the server will prompt for authorization. Call the authorize tool — it returns a URL to open in your browser. After you authorize on Meetup's site, the browser will redirect to http://127.0.0.1:8787/meetup/oauth/callback?code=....
Important: If the server is running on a remote machine (VM, cloud), the browser redirect lands on your local machine, not the server. Copy the full callback URL and run:
curl "http://YOUR_SERVER:8787/meetup/oauth/callback?code=THE_CODE"
Tokens are persisted in a Docker volume (meetup-mcp-tokens) and survive container restarts. You only need to authorize once per token lifetime.
Note: If you previously ran this image and the OAuth token store fails to persist, your Docker volume may have incorrect ownership. Remove and recreate it:
docker compose down docker volume rm meetup-mcp-tokens docker compose up -d
| Variable | Required | Default | Description |
|---|---|---|---|
MEETUP_GROUP_URLNAME | Yes | — | Meetup group URL name (e.g. nhdnug) |
MEETUP_MODE | No | organizer | organizer or read_only |
MEETUP_ALLOW_PUBLISH | No | false | Enable publish_event tool |
MEETUP_ALLOW_DESTRUCTIVE | No | false | Reserved for future destructive operations |
MEETUP_USE_FAKE_API | No | false | Use in-memory fake responses (local dev) |
MEETUP_OAUTH_KEY | Yes* | — | OAuth consumer key |
MEETUP_OAUTH_SECRET | Yes* | — | OAuth consumer secret |
MEETUP_OAUTH_REDIRECT_URI | No | http://127.0.0.1:8787/meetup/oauth/callback | OAuth redirect URI |
MEETUP_TOKEN_STORE_PATH | No | ~/.meetup-mcp/tokens.json | Token persistence path |
MEETUP_API_URL | No | https://api.meetup.com/gql-ext | Meetup GraphQL endpoint |
MEETUP_OAUTH_ACCESS_URL | No | https://secure.meetup.com/oauth2/access | Token exchange endpoint |
*Not required when MEETUP_USE_FAKE_API=true
Photo upload is a two-step process:
create_event_photo_upload → returns { photoId, uploadUrl }PUT image bytes directly to uploadUrlattach_event_photo or attach_event_speaker_photo with eventId + photoIdMeetup's current GraphQL API exposes a single structured speakerDetails object per event, not a free-form speaker array. The MCP server exposes this through focused tools:
add_event_speakerupdate_event_speakerremove_event_speakerattach_event_speaker_photoget_event now returns structured speaker details when present.
dotnet build MeetupMcp.slnx
dotnet test MeetupMcp.slnx
Run against in-memory fake data (no Meetup credentials needed):
MEETUP_GROUP_URLNAME=nhdnug \
MEETUP_USE_FAKE_API=true \
dotnet run --project src/Meetup.McpServer/Meetup.McpServer.csproj
https://github.com/Aaronontheweb/meetup-mcpContent type
Image
Digest
sha256:cc736cddb…
Size
92.3 MB
Last updated
5 months ago
docker pull aaronontheweb/meetup-mcp