Connect your AI Agents to Luma in minutes

Available tools
get_calendar
Get the calendar this API key is scoped to: name, slug, public URL, description, images, and social handles. Luma API keys are scoped to exactly one calendar, so this takes no arguments. Returns the calendar ID needed by update_calendar.
update_calendar
Update the calendar's name, slug, description, avatar, or tint colour. Only the fields you pass are changed. Use get_calendar to find the calendar ID. Changing the slug changes the public URL and breaks existing links.
list_calendar_admins
List the administrators of this calendar with their names and email addresses. Takes no arguments — the API key determines the calendar, and the endpoint is not paginated.
list_calendar_events
List events on this calendar with cursor pagination. Filter server-side by date range (before/after, ISO 8601), platform, submission status (approved or pending), and access level, and sort by startat. This is the main way to find event IDs for getevent, list_guests, and every other event tool.
lookup_calendar_event
Report whether an event is on this calendar. platform is required and selects the identifier: 'luma' takes eventid or eventapiid, 'external' takes url. To turn a luma.com link into an event ID, use lookupentity with the slug instead. Returns null when nothing matches.
add_calendar_event
Add an event to this calendar: an existing Luma event by eventid (platform='luma'), or an event hosted elsewhere by url (platform='external'). submissionmode='auto' approves it immediately, 'pending' leaves it for admin review. Returns the calendar-event ID for approvecalendarevent.
approve_calendar_event
Approve an event submitted to this calendar, making it publicly visible on the calendar page. Use listcalendarevents with status='pending' to find submissions awaiting review. To decline one instead, use rejectcalendarevent.
reject_calendar_event
Reject an event submitted to this calendar, optionally with a message to the submitter. Use listcalendarevents with status='pending' to find submissions awaiting review. To accept one instead, use approvecalendarevent.
list_contacts
List contacts on this calendar with cursor pagination. Filter server-side by free-text query, tag names (use listcontacttags), membership status, or membership tier (use listmembershiptiers), and sort by name, created_at, revenue, or event counts. Returns contact IDs and user IDs for the contact and tag tools.
import_contacts
Import contacts onto this calendar in bulk. Each contact is an object with email and optional name. Optionally apply contact tags to every imported contact — use listcontacttags to find tag names. Existing contacts are matched by email rather than duplicated.
block_contact
Block a contact from registering for events on this calendar. Identify them by contactid or email — use listcontacts to find contact IDs. The record is kept and restorecontact brings it back unchanged, but a blocked contact disappears from listcontacts, which has no filter for blocked people. Use remove_contact to delete instead.
remove_contact
Remove a contact from this calendar. Identify them by contactid or email — use listcontacts to find contact IDs. Use restorecontact to bring them back. To keep the record but stop them registering, use blockcontact instead.
restore_contact
Restore a contact previously removed or blocked on this calendar, letting them register for events again. Identify them by contactid or email — use listcontacts to find contact IDs.
list_event_coupons
List discount coupons scoped to one event, with cursor pagination. Use listcalendarevents to find event IDs. Returns coupon codes for updateeventcoupon. For coupons that apply across every event on the calendar, use listcalendarcoupons.
create_event_coupon
Create a discount coupon on one event. discount requires a discounttype discriminator: {"discounttype": "percent", "percentoff": 20} or {"discounttype": "amount", "centsoff": 500, "currency": "usd"}. Optionally cap redemptions, set a validity window, or restrict it to one ticket type (listtickettypes for IDs). Use listcalendar_events for event IDs.
update_event_coupon
Update an event coupon's remaining redemption count or validity window. Identify it by event ID plus coupon code — use listeventcoupons to find codes. The discount amount cannot be changed; create a new coupon instead.
list_calendar_coupons
List discount coupons that apply across every event on this calendar, with cursor pagination. Returns coupon codes for updatecalendarcoupon. For coupons scoped to a single event, use listeventcoupons.
create_calendar_coupon
Create a discount coupon valid across every event on this calendar. discount requires a discounttype discriminator: {"discounttype": "percent", "percentoff": 20} or {"discounttype": "amount", "centsoff": 500, "currency": "usd"}. Optionally cap redemptions or set a validity window. To limit a coupon to one event, use createevent_coupon.
update_calendar_coupon
Update a calendar-wide coupon's remaining redemption count or validity window. Identify it by coupon code — use listcalendarcoupons to find codes. The discount amount cannot be changed; create a new coupon instead.
get_event
Get one Luma event by ID: schedule, location, capacity, visibility, hosts, and guest counts. Use listcalendarevents to find event IDs, or lookupcalendarevent to resolve a public URL to an ID. Some fields are omitted when the API key has view-only access to the event.
create_event
Create an event on the calendar this API key belongs to. Requires name, startat (ISO 8601), and an IANA timezone. Optionally set location, capacity, visibility, registration questions, and ticket types. Returns the new event ID for getevent, updateevent, and addguests.
update_event
Update an existing event. Only the fields you pass are changed. Set suppressnotifications=true to avoid emailing guests about a cosmetic edit. Use listcalendarevents to find event IDs. To change ticket prices use updateticket_type instead.
request_event_cancellation
Step 1 of cancelling an event. Returns a single-use cancellationtoken plus the guest count and whether the event has paid tickets. Nothing is cancelled by this call. Pass the token to cancelevent to confirm. Use listcalendarevents to find event IDs.
cancel_event
Step 2 of cancelling an event: permanently cancels it and notifies guests. Requires the cancellationtoken from requesteventcancellation, which you must call first. Set shouldrefund=true to refund paid tickets. This cannot be undone.
list_guests
List guests on an event with cursor pagination. Filter server-side by approvalstatus (approved, pendingapproval, invited, declined, waitlist, session) and sort by name, email, registeredat, or checkedinat. Use listcalendarevents to find event IDs. Returns guest IDs for getguest, updategueststatus, and updateguesttickets.
get_guest
Get one guest on an event: approval status, registration answers, tickets held, check-in QR code, and ticket purchase orders. Use listguests to find guest IDs. Returns more detail than listguests, including eventticketorders.
add_guests
Register one or more guests on an event directly, bypassing signup. Each guest is an object with email and optional name. Optionally assign a ticket type (use listtickettypes for IDs) and set approvalstatus. Set sendemail=false to add them without notifying them. To invite rather than register, use sendguestinvites.
update_guest_status
Change a guest's approval status on an event: approve them, decline them, send them back to pendingapproval, or move them to the waitlist. Use listguests to find guest IDs. Set should_refund=true when declining a guest holding paid tickets. Moving a guest off approved releases their ticket; re-approving issues a new ticket and order, not the original.
update_guest_tickets
Add or remove tickets held by a guest on an event. Use listtickettypes for ticket type IDs to add, and getguest to find the guest's existing ticket IDs to remove. Use listguests to find guest IDs. Set send_email=false to change tickets silently. A guest must keep at least one ticket: removing their last one is rejected.
send_guest_invites
Email event invitations to a list of people. Each guest is an object with email and optional name; an optional message is included in the invite. Invitees must accept to become registered. To register people directly without an invite, use add_guests instead.
add_host
Add a host to an event by email. accesslevel 'manager' can edit the event, 'check-in' can only check guests in, 'none' is listed publicly with no access; 'none' cannot be combined with isvisible=false. getevent lists only visible hosts, so a host added with isvisible=false will not appear there even though the call succeeded.
update_host
Change an existing host's access level or public visibility on an event. Identify the host by email. Use getevent to see current hosts and their access levels. To add a new host use addhost instead.
remove_host
Remove a host from an event by email. The person keeps their Luma account and any guest registration; only their host role on this event is removed. Use get_event to see current hosts.
list_membership_tiers
List the membership tiers on this calendar, with pricing, access rules, and the questions asked at signup. Returns tier IDs needed by addmembertotier and by the calendarmembershiptierid filter on list_contacts.
add_member_to_tier
Add someone to a membership tier by email. Use listmembershiptiers to find tier IDs. Set skip_payment=true to comp a paid tier without collecting payment. Returns the membership ID and the status it was created in.
update_member_status
Approve or decline a calendar membership, identified by Luma user ID. Declining removes the membership outright rather than just marking it declined, and works on an already-approved member, so the person stops being a member. Use listcontacts with membershipstatus or calendarmembershiptierid to find member user IDs. To add a member, use addmembertotier.
get_current_user
Get the Luma user this API key belongs to: user ID, name, and email. Takes no arguments. Use this to confirm which account is connected. For the calendar the key is scoped to, use get_calendar.
lookup_entity
Resolve a public Luma slug to the calendar, event, or user it belongs to. Pass just the slug from the URL, e.g. 'merge-events' for luma.com/merge-events, not the full URL. The result has a type field to branch on. Returns null when the slug matches nothing.
create_image_upload_url
Get a pre-signed URL for uploading a JPEG or PNG to Luma's image host. PUT the raw image bytes to uploadurl, then pass the returned fileurl as coverurl on createevent or updateevent, or as avatarurl on update_calendar. The upload URL expires shortly after issue.
list_contact_tags
List the contact tags defined on this calendar, with their IDs, names, and colours. Takes no arguments. Returns tag IDs for updatecontacttag and deletecontacttag, and tag names for applycontacttag and the list_contacts tag filter.
create_contact_tag
Create a contact tag on this calendar for labelling people. Colour is one of cranberry, barney, red, green, blue, purple, yellow, orange. Returns the new tag ID. Use applycontacttag to attach it to contacts. For labelling events, use createeventtag.
update_contact_tag
Rename a contact tag or change its colour. Use listcontacttags to find tag IDs. Renaming a tag updates it everywhere it is applied.
delete_contact_tag
Delete a contact tag from this calendar. The tag is removed from every contact carrying it; the contacts themselves are untouched. Use listcontacttags to find tag IDs. Deleting an ID that does not exist also reports success, so success is not proof the tag existed.
apply_contact_tag
Apply a contact tag to contacts, identified by userids or emails. Use listcontacttags for tag names and listcontacts for user IDs. Returns how many contacts were tagged and how many were skipped because they already had the tag.
unapply_contact_tag
Remove a contact tag from contacts, identified by userids or emails. The tag itself still exists — use deletecontacttag to remove it entirely. Use listcontacts to find user IDs. Returns how many contacts were changed and how many were skipped.
list_event_tags
List the event tags defined on this calendar, with their IDs, names, and colours. Takes no arguments. Returns tag IDs for updateeventtag and deleteeventtag, and tag names for applyeventtag. For tags on people, use listcontacttags.
create_event_tag
Create an event tag on this calendar for grouping events. Colour is one of cranberry, barney, red, green, blue, purple, yellow, orange. Returns the new tag ID. Use applyeventtag to attach it to events. For labelling people, use createcontacttag.
update_event_tag
Rename an event tag or change its colour. Use listeventtags to find tag IDs. Renaming a tag updates it everywhere it is applied.
delete_event_tag
Delete an event tag from this calendar. The tag is removed from every event carrying it; the events themselves are untouched. Use listeventtags to find tag IDs. Deleting an ID that does not exist also reports success, so success is not proof the tag existed.
apply_event_tag
Apply an event tag to one or more events. Use listeventtags for tag names and listcalendarevents for event IDs. Returns how many events were tagged and how many were skipped because they already had the tag.
unapply_event_tag
Remove an event tag from one or more events. The tag itself still exists — use deleteeventtag to remove it entirely. Use listcalendarevents to find event IDs. Returns how many events were changed and how many were skipped.
list_ticket_types
List the ticket types on an event, including price, capacity, and sale window. Set includehidden=true to also return types hidden from the public event page. Use listcalendarevents to find event IDs. Returns ticket type IDs needed by addguests, updateguesttickets, and createeventcoupon.
get_ticket_type
Get one ticket type by ID: name, free or paid, price, currency, capacity, approval requirement, and sale window. Use listtickettypes to find ticket type IDs.
create_ticket_type
Add a ticket type to an event. Requires eventid, name, and type ('free' or 'paid'); paid types also need cents and currency. Use listcalendarevents to find event IDs. Returns the new ticket type ID for addguests and createeventcoupon.
update_ticket_type
Update a ticket type: price, name, capacity, sale window, visibility, or approval requirement. Only the fields you pass are changed. Use listtickettypes to find ticket type IDs. Existing tickets already sold keep the price they were bought at.
delete_ticket_type
Delete a ticket type from an event. Use listtickettypes to find ticket type IDs. Consider updatetickettype with is_hidden=true instead if the type has already sold tickets.
validate_credential
Validate the Luma API key with a lightweight call to the current-user endpoint. Returns success plus a short message.
list_webhooks
List the webhook subscriptions on this calendar with cursor pagination. Returns webhook IDs for getwebhook, updatewebhook, and delete_webhook. Each entry also carries the signing secret, so treat this response as sensitive and do not log or display it.
get_webhook
Get one webhook subscription: destination URL, subscribed event types, active or paused status, and the signing secret used to verify callbacks. Use list_webhooks to find webhook IDs.
create_webhook
Create a webhook subscription that POSTs to your URL when calendar activity happens. Event types include event.created, event.updated, event.canceled, guest.registered, guest.updated, ticket.registered, and the calendar. events; pass [''] for all. Returns the webhook ID and signing secret.
update_webhook
Update a webhook subscription: replace its event types, or pause and resume delivery via status. eventtypes replaces the existing list rather than adding to it. Use listwebhooks to find webhook IDs. The destination URL cannot be changed; create a new webhook instead.
delete_webhook
Delete a webhook subscription permanently, stopping all callbacks to its URL. Use listwebhooks to find webhook IDs. To stop delivery temporarily instead, use updatewebhook with status='paused'.

How to set up Merge Agent Handler
In an mcp.json file, add the configuration below, and restart Cursor.
Learn more in the official documentation ↗
1{
2 "mcpServers": {
3 "agent-handler": {
4 "url": "https://ah-api-develop.merge.dev/api/v1/tool-packs/{TOOL_PACK_ID}/registered-users/{REGISTERED_USER_ID}/mcp",
5 "headers": {
6 "Authorization": "Bearer yMt*****"
7 }
8 }
9 }
10}
11Open your Claude Desktop configuration file and add the server configuration below. You'll also need to restart the application for the changes to take effect.
Make sure Claude is using the Node v20+.
Learn more in the official documentation ↗
1{
2 "mcpServers": {
3 "agent-handler": {
4 "command": "npx",
5 "args": [
6 "-y",
7 "mcp-remote@latest",
8 "https://ah-api-develop.merge.dev/api/v1/tool-packs/{TOOL_PACK_ID}/registered-users/{REGISTERED_USER_ID}/mcp",
9 "--header",
10 "Authorization: Bearer ${AUTH_TOKEN}"
11 ],
12 "env": {
13 "AUTH_TOKEN": "yMt*****"
14 }
15 }
16 }
17}Open your Windsurf MCP configuration file and add the server configuration below.
Click on the refresh button in the top right of the Manage MCP server page or in the top right of the chat box in the box icon.
Learn more in the official documentation ↗
1{
2 "mcpServers": {
3 "agent-handler": {
4 "command": "npx",
5 "args": [
6 "-y",
7 "mcp-remote@latest",
8 "https://ah-api.merge.dev/api/v1/tool-packs/<tool-pack-id>/registered-users/<registered-user-id>/mcp",
9 "--header",
10 "Authorization: Bearer ${AUTH_TOKEN}"
11 ],
12 "env": {
13 "AUTH_TOKEN": "<ah-production-access-key>"
14 }
15 }
16 }
17 }In Command Palette (Cmd+Shift+P on macOS, Ctrl+Shift+P on Windows), run "MCP: Open User Configuration".
You can then add the configuration below and press "start" right under servers. Enter the auth token when prompted.
Learn more in the official documentation ↗
1{
2 "inputs": [
3 {
4 "type": "promptString",
5 "id": "agent-handler-auth",
6 "description": "Agent Handler AUTH_TOKEN", // "yMt*****" when prompt
7 "password": true
8 }
9 ],
10 "servers": {
11 "agent-handler": {
12 "type": "stdio",
13 "command": "npx",
14 "args": [
15 "-y",
16 "mcp-remote@latest",
17 "https://ah-api-develop.merge.dev/api/v1/tool-packs/{TOOL_PACK_ID}/registered-users/{REGISTERED_USER_ID}/mcp",
18 "--header",
19 "Authorization: Bearer ${input:agent-handler-auth}"
20 ]
21 }
22 }
23}FAQs on using Merge's Luma MCP server
FAQs on using Merge's Luma MCP server
Ready to try it out?
Whether you're an engineer experimenting with agents or a product manager looking to add tools, you can get started for free now

























