Sign inSign up

aaronontheweb/meetup-mcp

By aaronontheweb

Updated 5 months ago

Model Context Protocol server for Meetup.com

Image
Machine learning & AI
0

727

aaronontheweb/meetup-mcp repository overview

meetup-mcp

Docker Hub

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 count
  • search_events — search by status: upcoming, past, draft
  • get_event — full event details by ID
  • list_venues — known venues for the group
  • create_event — creates as DRAFT by default
  • edit_event — update title, description, datetime, duration, venue, directions, featured photo
  • add_event_speaker — add structured speaker details to an event
  • update_event_speaker — edit structured speaker details or speaker photo
  • remove_event_speaker — remove structured speaker details from an event
  • attach_event_speaker_photo — attach an uploaded photo to the event speaker profile
  • publish_event — gated behind MEETUP_ALLOW_PUBLISH=true
  • create_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 (organizer vs read_only)
  • All writes require organizer mode
  • 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
  1. Go to https://www.meetup.com/api/oauth/create/
  2. Set Redirect URI to http://127.0.0.1:8787/meetup/oauth/callback
  3. 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

VariableRequiredDefaultDescription
MEETUP_GROUP_URLNAMEYesMeetup group URL name (e.g. nhdnug)
MEETUP_MODENoorganizerorganizer or read_only
MEETUP_ALLOW_PUBLISHNofalseEnable publish_event tool
MEETUP_ALLOW_DESTRUCTIVENofalseReserved for future destructive operations
MEETUP_USE_FAKE_APINofalseUse in-memory fake responses (local dev)
MEETUP_OAUTH_KEYYes*OAuth consumer key
MEETUP_OAUTH_SECRETYes*OAuth consumer secret
MEETUP_OAUTH_REDIRECT_URINohttp://127.0.0.1:8787/meetup/oauth/callbackOAuth redirect URI
MEETUP_TOKEN_STORE_PATHNo~/.meetup-mcp/tokens.jsonToken persistence path
MEETUP_API_URLNohttps://api.meetup.com/gql-extMeetup GraphQL endpoint
MEETUP_OAUTH_ACCESS_URLNohttps://secure.meetup.com/oauth2/accessToken exchange endpoint

*Not required when MEETUP_USE_FAKE_API=true

Image upload flow

Photo upload is a two-step process:

  1. Call create_event_photo_upload → returns { photoId, uploadUrl }
  2. PUT image bytes directly to uploadUrl
  3. Call attach_event_photo or attach_event_speaker_photo with eventId + 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_speaker
  • update_event_speaker
  • remove_event_speaker
  • attach_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

Tag summary

Content type

Image

Digest

sha256:cc736cddb

Size

92.3 MB

Last updated

5 months ago

docker pull aaronontheweb/meetup-mcp