Luma Calendar MCP server — event, guest, and ticket operations as tools for AI assistants.
luma-events-mcp
Features
- Get calendar info associated with your API key
- List, create, and update events
- List guests, get guest details, add guests, update guest status, send invites
- List and create ticket types
- List and create coupons
- Dual pagination mode: auto-paginate all results or manual cursor-based paging
Setup
Add the server to your MCP client config. Get your API key from your Luma dashboard (requires Luma Plus).
With inline API key
{
"mcpServers": {
"luma": {
"command": "npx",
"args": ["luma-events-mcp"],
"env": {
"LUMA_API_KEY": "<your Luma API key>"
}
}
}
}
With a .env file
Keep your API key in a .env file (gitignored) and use dotenvx to load it:
LUMA_API_KEY=your-api-key
{
"mcpServers": {
"luma": {
"command": "npx",
"args": ["@dotenvx/dotenvx", "run", "--", "npx", "luma-events-mcp"]
}
}
}
Development
Quick Start
Run the MCP server in development mode with auto-reload:
npm run dev
This will run the TypeScript code directly with watch mode and automatically load environment variables from .env.
Manual Build
npm run build
node dist/index.js
Available Tools
get-calendar
Get the calendar associated with the current API key
Parameters: none
Returns:
- Calendar object with api_id, name, and geo fields
list-events
List events for the calendar. Optionally filter by date range. Without pagination params, returns all events; with them, returns one page.
Parameters:
after: string (optional) — Only events starting after this ISO 8601 datetimebefore: string (optional) — Only events starting before this ISO 8601 datetimepagination_limit: number (optional) — Page size (max 50)pagination_cursor: string (optional) — Cursor from a previous page
Returns:
- Array of event objects, or paginated result with next_cursor
get-event
Get admin details of a specific event by its ID
Parameters:
event_id: string — Event ID (e.g. evt-...)
Returns:
- Full event object including name, dates, location, description, and ticket info
list-guests
List guests for an event. Without pagination params, returns all guests; with them, returns one page.
Parameters:
event_id: string — Event ID (e.g. evt-...)approval_status: enum (approved|session|pending_approval|invited|declined|waitlist) (optional) — Filter by approval statussort_column: enum (name|email|created_at|registered_at|checked_in_at) (optional) — Sort columnpagination_limit: number (optional) — Page sizepagination_cursor: string (optional) — Cursor from a previous page
Returns:
- Array of guest objects, or paginated result with next_cursor
get-guest
Get detailed info for a single event guest. The id field accepts a guest ID (gst-...), guest key (g-...), ticket key, or email address.
Parameters:
event_id: string — Event ID (e.g. evt-...)id: string — Guest identifier: guest ID (gst-...), guest key (g-...), or email
Returns:
- Full guest object with approval status, ticket info, event_ticket_orders, and profile
list-ticket-types
List all ticket types for an event
Parameters:
event_id: string — Event ID (e.g. evt-...)
Returns:
- Array of ticket type objects with name, price, and availability info
create-event
Create a new event on the calendar
Parameters:
name: string — Event titlestart_at: string — Start datetime (ISO 8601)timezone: string — IANA timezone (e.g. America/New_York)end_at: string (optional) — End datetime (ISO 8601)description_md: string (optional) — Event description in markdownmeeting_url: string (optional) — Virtual event URLgeo_address_json: value (optional) — Address object with city, place, etc.geo_latitude: number (optional) — Latitudegeo_longitude: number (optional) — Longitudecover_url: string (optional) — Cover image URL (must be Luma CDN)visibility: enum (public|members-only|private) (optional) — Event visibilitymax_capacity: number (optional) — Maximum attendee capacity
Returns:
- The created event object
update-event
Update an existing event. Only provided fields are changed.
Parameters:
event_id: string — Event ID (e.g. evt-...)suppress_notifications: boolean (optional) — Prevent guest notifications for name/time/location changesname: string (optional) — Event titlestart_at: string (optional) — Start datetime (ISO 8601)end_at: string (optional) — End datetime (ISO 8601)timezone: string (optional) — IANA timezonedescription_md: string (optional) — Event description in markdownmeeting_url: string (optional) — Virtual event URLcover_url: string (optional) — Cover image URLvisibility: enum (public|members-only|private) (optional) — Event visibilitymax_capacity: number (optional) — Maximum attendee capacity
Returns:
- The updated event object
add-guests
Add guests to an event. By default guests are approved and receive one default ticket.
Parameters:
event_id: string — Event ID (e.g. evt-...)guests: array of object — Array of guest objects with emailapproval_status: enum (approved|pending_approval|waitlist) (optional) — Approval status for added guests (default: approved)send_email: boolean (optional) — Send notification email (default: true)ticket: value (optional) — Ticket type to assign to all guests
Returns:
- Confirmation of added guests
update-guest-status
Update a guest's approval status (approve or decline)
Parameters:
event_id: string — Event ID (e.g. evt-...)guest: value — Guest identifier object (e.g. { email: '...' } or { id: 'gst-...' })status: enum (approved|declined) — New status for the guestshould_refund: boolean (optional) — Refund the guest if declining a paid ticket
Returns:
- Confirmation of status update
send-invites
Send invites to guests for an event. Sends email and SMS if phone is linked.
Parameters:
event_id: string — Event ID (e.g. evt-...)guests: array of object — Array of guest objects with email and optional message
Returns:
- Confirmation of sent invites
create-ticket-type
Create a new ticket type for an event
Parameters:
event_id: string — Event ID (e.g. evt-...)name: string — Ticket type nametype: enum (free|paid) — Ticket pricing typerequire_approval: boolean (optional) — Require host approvalis_hidden: boolean (optional) — Hide from public listingdescription: string (optional) — Ticket type descriptionmax_capacity: number (optional) — Maximum tickets availablecents: number (optional) — Price in cents (for paid tickets)currency: string (optional) — Currency code (e.g. USD, EUR)
Returns:
- The created ticket type object
update-ticket-type
Update an existing ticket type
Parameters:
event_ticket_type_api_id: string — Ticket type ID (e.g. ett-...)name: string (optional) — Ticket type namerequire_approval: boolean (optional) — Require host approvalis_hidden: boolean (optional) — Hide from public listingdescription: string (optional) — Ticket type descriptionvalid_start_at: string (optional) — ISO 8601 start date for ticket salesvalid_end_at: string (optional) — ISO 8601 end date for ticket salesmax_capacity: number (optional) — Maximum tickets availabletype: enum (free|paid) (optional) — Ticket pricing typecents: number (optional) — Price in cents (for paid tickets)currency: string (optional) — Currency code (e.g. USD, EUR)is_flexible: boolean (optional) — Allow flexible pricingmin_cents: number (optional) — Minimum price in cents (for flexible pricing)
Returns:
- The updated ticket type object
delete-ticket-type
Delete a ticket type (soft-delete). Cannot delete if tickets have been sold or if it is the last visible ticket type.
Parameters:
event_ticket_type_api_id: string — Ticket type ID (e.g. ett-...)
Returns:
- Confirmation of the deleted ticket type
list-coupons
List all coupons for an event. Without pagination params, returns all coupons; with them, returns one page.
Parameters:
event_id: string — Event ID (e.g. evt-...)pagination_limit: number (optional) — Page sizepagination_cursor: string (optional) — Cursor from a previous page
Returns:
- Array of coupon objects, or paginated result with next_cursor
create-coupon
Create a coupon for an event. Coupon terms cannot be edited after creation.
Parameters:
event_id: string — Event ID (e.g. evt-...)code: string — Coupon code (1-20 chars, case-insensitive)discount: value — Discount object (e.g. { type: 'percent', percent_off: 20 })remaining_count: number (optional) — Number of uses (0-1000000; use 1000000 for unlimited)valid_start_at: string (optional) — Validity start (ISO 8601)valid_end_at: string (optional) — Validity end (ISO 8601)
Returns:
- The created coupon object
upload-image
Upload a local image file to Luma's CDN and return the final URL. Reads the file from disk, obtains a presigned upload URL, PUTs the binary, and returns the CDN URL.
Parameters:
file_path: string — Absolute path to the local image file to uploadpurpose: string — Upload purpose (e.g. "event-cover", "avatar")content_type: string (optional) — MIME type of the image (default: "image/png")
Returns:
- The Luma CDN URL for the uploaded image
License
MIT