Meetup MCP
Model Context Protocol server for Meetup.com
Ask AI about Meetup MCP
Powered by Claude Β· Grounded in docs
I know everything about Meetup MCP. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
meetup-mcp
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:
- no built-in content templating
- no raw GraphQL passthrough
- single-group scope per server instance
- publish actions gated by explicit configuration
Use your LLM to generate event content. Use this MCP server to execute Meetup operations safely.
Features
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 behindMEETUP_ALLOW_PUBLISH=truecreate_event_photo_uploadβ get a direct upload ticket (photoId + uploadUrl)attach_event_photoβ attach an uploaded photo to an event
Safety model
- Single group lock via
MEETUP_GROUP_URLNAME - Mode-based capability control (
organizervsread_only) - All writes require
organizermode - Publishing blocked by default (
MEETUP_ALLOW_PUBLISH=false) - Events created as DRAFT unless publish is explicitly enabled and requested
Policy violations return errors prefixed with POLICY_DENIED.
Deployment
Prerequisites
- Docker + Docker Compose
- A Meetup Pro account with API access
- A Meetup OAuth consumer (key + secret)
1. Create a Meetup OAuth consumer
- Go to
https://www.meetup.com/api/oauth/create/ - Set Redirect URI to
http://127.0.0.1:8787/meetup/oauth/callback - Copy your Consumer Key and Consumer Secret
2. Configure environment
Copy .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
3. Build the container image
dotnet publish src/Meetup.McpServer/Meetup.McpServer.csproj /t:PublishContainer
4. Start the server
docker compose up -d
The server runs on http://localhost:5180/mcp and restarts automatically unless explicitly stopped.
5. Configure Claude Code
The included .mcp.json points Claude Code at the running server:
{
"mcpServers": {
"meetup": {
"type": "http",
"url": "http://localhost:5180/mcp"
}
}
}
6. Authorize (first run only)
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
Configuration reference
| 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
Image upload flow
Photo upload is a two-step process:
- Call
create_event_photo_uploadβ returns{ photoId, uploadUrl } PUTimage bytes directly touploadUrl- Call
attach_event_photoorattach_event_speaker_photowitheventId+photoId
Structured speaker support
Meetup'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_photo
get_event now returns structured speaker details when present.
Local development
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
Repository
- GitHub:
https://github.com/Aaronontheweb/meetup-mcp
