Content
# luma-events-mcp
<div align="center">
A Luma Calendar MCP server exposing event, guest, and ticket operations as tools for AI assistants.
[](https://github.com/unvibe-org/luma-events-mcp/actions/workflows/release.yml)
[](https://www.npmjs.com/package/luma-events-mcp)
[](https://choosealicense.com/licenses/mit/)
[](https://modelcontextprotocol.io)
[](https://github.com/semantic-release/semantic-release)
</div>
## 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
```json
{
"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`](https://dotenvx.com) to load it:
```
LUMA_API_KEY=your-api-key
```
```json
{
"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:
```bash
npm run dev
```
This will run the TypeScript code directly with watch mode and automatically load environment variables from `.env`.
### Manual Build
```bash
npm run build
node dist/index.js
```
## Available Tools
<!-- TOOLS:START - generated by scripts/gen-tool-docs.ts -->
### 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 datetime
- `before`: string (optional) — Only events starting before this ISO 8601 datetime
- `pagination_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 status
- `sort_column`: enum (`name` | `email` | `created_at` | `registered_at` | `checked_in_at`) (optional) — Sort column
- `pagination_limit`: number (optional) — Page size
- `pagination_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 title
- `start_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 markdown
- `meeting_url`: string (optional) — Virtual event URL
- `geo_address_json`: value (optional) — Address object with city, place, etc.
- `geo_latitude`: number (optional) — Latitude
- `geo_longitude`: number (optional) — Longitude
- `cover_url`: string (optional) — Cover image URL (must be Luma CDN)
- `visibility`: enum (`public` | `members-only` | `private`) (optional) — Event visibility
- `max_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 changes
- `name`: string (optional) — Event title
- `start_at`: string (optional) — Start datetime (ISO 8601)
- `end_at`: string (optional) — End datetime (ISO 8601)
- `timezone`: string (optional) — IANA timezone
- `description_md`: string (optional) — Event description in markdown
- `meeting_url`: string (optional) — Virtual event URL
- `cover_url`: string (optional) — Cover image URL
- `visibility`: enum (`public` | `members-only` | `private`) (optional) — Event visibility
- `max_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 email
- `approval_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 guest
- `should_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 name
- `type`: enum (`free` | `paid`) — Ticket pricing type
- `require_approval`: boolean (optional) — Require host approval
- `is_hidden`: boolean (optional) — Hide from public listing
- `description`: string (optional) — Ticket type description
- `max_capacity`: number (optional) — Maximum tickets available
- `cents`: 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 name
- `require_approval`: boolean (optional) — Require host approval
- `is_hidden`: boolean (optional) — Hide from public listing
- `description`: string (optional) — Ticket type description
- `valid_start_at`: string (optional) — ISO 8601 start date for ticket sales
- `valid_end_at`: string (optional) — ISO 8601 end date for ticket sales
- `max_capacity`: number (optional) — Maximum tickets available
- `type`: enum (`free` | `paid`) (optional) — Ticket pricing type
- `cents`: number (optional) — Price in cents (for paid tickets)
- `currency`: string (optional) — Currency code (e.g. USD, EUR)
- `is_flexible`: boolean (optional) — Allow flexible pricing
- `min_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 size
- `pagination_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 upload
- `purpose`: 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
<!-- TOOLS:END -->
## License
MIT
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available