Skip to main content
Glama

luma-mcp

lu.ma events MCP server. Create events, set ticket prices, issue coupon codes, list RSVPs, and email attendees. All writes go through draft+confirm so nothing posts to Luma until you explicitly approve. Built on the official Luma public API.

What it does

  • Create + update lu.ma events (name, date, timezone, capacity, meeting URL, visibility, cover image)

  • Set ticket types and pricing

  • Issue coupon codes (calendar-scoped or event-scoped, percentage or fixed-cents discounts, redemption caps)

  • List event guests / RSVPs

  • Send markdown emails to attendees (pre-work, day-of, follow-up)

  • Audit log of every API call (JSONL with key/token redaction)

  • Prompt-injection scrubber on user-supplied free-text fields

Related MCP server: Pulumi Events MCP

Tools (v0.1.0)

Reads (call API directly):

  • luma_health — auth check + draft store size

  • luma_get_event — fetch one event by ID

  • luma_list_events — paginated calendar listing

  • luma_list_event_guests — RSVPs filtered by status

  • luma_list_coupons — calendar or event-scoped

Writes (draft+confirm pairs):

  • luma_create_event_draft / luma_create_event_confirm

  • luma_update_event_draft / luma_update_event_confirm

  • luma_create_ticket_type_draft / luma_create_ticket_type_confirm

  • luma_create_coupon_draft / luma_create_coupon_confirm

  • luma_send_event_email_draft / luma_send_event_email_confirm

Plus:

  • luma_cancel_draft — cancel an unconfirmed draft (idempotent)

14 tools total.

Architecture

luma-mcp/
├── pyproject.toml
├── README.md
├── SETUP.md
├── LICENSE
├── .env.example
├── luma_mcp/
│   ├── __init__.py
│   ├── server.py             FastMCP entry point + .env loader
│   ├── client.py             HTTP wrapper around api.lu.ma/public/v1
│   ├── drafts.py             Thread-safe draft store with TTL
│   ├── audit.py              JSONL audit log with redaction
│   ├── scrubber.py           Prompt-injection neutralizer
│   ├── _shared/              Day-1 shared utilities
│   │   ├── normalize.py      Timezone alias + datetime helpers
│   │   └── types.py          Permissive typed shapes for API responses
│   └── tools/
│       ├── health.py         luma_health, luma_cancel_draft
│       ├── events.py         create / update / get / list events
│       ├── tickets.py        create ticket types
│       ├── coupons.py        create / list coupons
│       ├── guests.py         list event guests
│       └── emails.py         send email to attendees
└── tests/integration/
    └── test_full_pipeline.py 10-step bare-runnable verification

Safety patterns

  1. Draft + confirm on every write. The draft tool returns a draft_id; nothing hits Luma until the matching confirm tool is called. Drafts expire after 1 hour and can only be confirmed once.

  2. Audit log. Every API call is logged JSONL with ts, tool, action, args (redacted), status, latency_ms. Path: ~/.claude/luma-mcp/audit.log.

  3. Token redaction. Strings matching long-key heuristics, or values under keys like api_key, token, cookie, secret, are masked before logging.

  4. Prompt-injection scrubber. User-supplied free-text fields (event name, description, email subject, email body) are passed through unicodedata.normalize("NFKC"), stripped of zero-width characters, and have role-spoof prefixes / fake fences wrapped in backticks (preserving operator visibility, neutralizing model effect on downstream reads).

  5. Zero LLM in the tool path. Every routing decision is rule-based.

Use cases

  • Workshops + paid events — set sticker price, issue community-specific 100%-off coupons, pull guest list, blast pre-work email.

  • Multi-event programs — one cohorte announcement, sub-events on Luma, pull RSVPs across sessions.

  • Recurring meetups — duplicate event template via update_event_draft, change date, ship.

Install

Open Claude Code, paste:

/plugin marketplace add adelaidasofia/luma-mcp
/plugin install luma-mcp@luma-mcp

Two prerequisites for the server to authenticate:

  1. Luma Plus subscription on the calendar you'll use (the public API is gated behind Plus).

  2. API key generated from https://lu.ma/settings/api, dropped into ~/.claude/luma-mcp/.env as LUMA_API_KEY=....

After both steps, restart Claude Code. Tools appear under mcp__luma__*.

See SETUP.md for the manual .mcp.json registration path. The plugin install above replaces it.

Verification

cd ~/.claude/luma-mcp && python3 tests/integration/test_full_pipeline.py
# expected: PASSED — luma-mcp v0.1.0 integration test (10 steps green)

Then in a Claude Code session: mcp__luma__luma_health() → {ok: true, user: {...}}.

Rate limit

Luma's public API caps at 200 requests / minute / calendar. The client does not auto-retry on 429; it surfaces the error and lets the operator pace.

Same author, same architecture pattern (FastMCP, draft+confirm on writes, vault auto-export where applicable):

Telemetry

This plugin sends a single anonymous install signal to myceliumai.co the first time it loads in a Claude Code session on a given machine.

What is sent:

  • Plugin name (e.g. slack-mcp)

  • Plugin version (e.g. 0.1.0)

What is NOT sent:

  • No user identifiers, names, emails, tokens, or API keys

  • No file paths, message content, or anything from your work

  • No IP address is stored after dedup processing

Why: Helps the maintainer know which plugins people actually install, so attention goes to the ones that get used.

Opt out: Set the environment variable MYCELIUM_NO_PING=1 before launching Claude Code. The hook will skip the network call entirely. Already-pinged installs leave a sentinel at ~/.mycelium/onboarded-<plugin> — delete it if you want to reset state.

License

MIT. See LICENSE.

Available Tools

16 tools
luma_cancel_draftC

Cancel an unconfirmed draft. Idempotent.

Inputs: draft_id (required). Returns: object

luma_create_coupon_confirmB

Commit a previously-drafted coupon.

Inputs: draft_id (required). Returns: object

luma_create_coupon_draftA

Stage a coupon. Nothing posts until confirm.

Pass exactly one of discount_percentage or discount_cents.

Inputs: code (required), extra, event_id, expires_at, +4 more. Returns: object

luma_create_event_confirmA

Commit a previously-drafted event creation. Returns the new event.

Inputs: draft_id (required). Returns: object

luma_create_event_draftA

Stage an event for creation. Nothing posts to Luma until confirm.

Inputs: name (required), start_at (required), timezone (required), extra, +7 more. Returns: object

luma_create_ticket_type_confirmA

Commit a previously-drafted ticket type.

Inputs: draft_id (required). Returns: object

luma_create_ticket_type_draftA

Stage a ticket type for an event. Nothing posts until confirm.

Pass either price_usd (decimal, e.g. 250.0) or cents (integer, e.g. 25000). Setting both raises. Setting neither creates a free ticket.

Inputs: name (required), event_id (required), cents, extra, +5 more. Returns: object

luma_get_eventA

Fetch one event by ID. Returns the typed shape plus the raw payload.

Inputs: event_id (required). Returns: object

luma_healthA

Verify the LUMA_API_KEY is set and authenticates against the Luma API.

Returns the calling user's profile on success (proves the key works) plus the active draft count so the operator can see if anything is staged.

Inputs: no named parameters. Returns: object

luma_list_couponsA

List coupons scoped to an event (or calendar-wide if event_id is None).

Inputs: event_id. Returns: object

luma_list_event_guestsB

List RSVPs / guests for an event.

Inputs: event_id (required), limit, status. Returns: object

luma_list_eventsA

List events on the API key's calendar. Pagination via after/before cursors.

Inputs: after, limit, before. Returns: object

luma_send_event_email_confirmC

Commit a previously-drafted attendee email blast.

Inputs: draft_id (required). Returns: object

luma_send_event_email_draftB

Stage an email blast to event attendees. Body markdown supported.

Inputs: body_md (required), subject (required), event_id (required), extra, +1 more. Returns: object

luma_update_event_confirmB

Commit a previously-drafted event update.

Inputs: draft_id (required). Returns: object

luma_update_event_draftC

Stage an event update. Only fields provided are changed.

Inputs: event_id (required), name, extra, end_at, +7 more. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 16 tools

    Disambiguation5/5

    Each tool has a distinct purpose: health check, event CRUD with draft/confirm pattern, ticket types, coupons, guests, and email blasts. No overlapping functionality, and descriptions clearly differentiate operations.

    Naming Consistency5/5

    All tools follow a consistent 'luma_verb_noun' pattern with underscores. Verbs are intuitive (create, update, list, get, cancel, send) and nouns describe the resource (event, ticket_type, coupon, guest). Very predictable.

    Tool Count5/5

    16 tools is a well-scoped set for an event management API. It covers draft/confirm workflows, listing, and auxiliary operations without unnecessary bloat or missing essentials.

    Completeness4/5

    Core event lifecycle (create, update, get, list, cancel drafts) is covered, plus ticket types, coupons, guests, and email sending. Missing: ability to delete confirmed events or update ticket types/coupons after creation. Minor gaps but overall comprehensive.

    Maintenance

    ActivityActive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      B
      maintenance
      An MCP server for managing Luma events, including listing, creating, updating events and guest registrations with privacy-conscious summaries.
      23
      14 npm
      2
      MIT
    • F
      license
      Not graded
      quality
      D
      maintenance
      An MCP server that dynamically sources global technology events, communities, and niche networking mixers from Luma, Eventbrite, Meetup, and fallback search sources, enabling event discovery and community finding via natural language.
      -