Reference

Tool reference.

Every tool the Enclave MCP server exposes, with inputs, output shapes and the scope and permission each one needs. Written for people building prompts, agents and integrations.

EndpointPOST https://api.enclavehq.com/api/mcp
ProtocolMCP 2026-07-28, Streamable HTTP, stateless
AuthOAuth 2.1 + PKCE. Client ID Metadata Documents. Bearer token per request.
Rate limit60 calls per minute per token
Discovery/.well-known/oauth-protected-resource/api/mcp
/.well-known/oauth-authorization-server
Scopesevents:read · events:write (implies read) · registrations:read
TokensAccess 1 h. Refresh 30 d, rotating. Bound to one user, organization and client.

events_list

events:readpermission events.viewread-onlyidempotent

Search and page through the organization's events.

Input

FieldTypeNotes
limitinteger 1-100optionalDefault 20.
offsetintegeroptionalDefault 0.
searchstring ≤200optionalCase-insensitive name search.
timeFilter"upcoming" | "past"optional
visibility"public" | "unlisted" | "private"optional
locationType"online" | "offline" | "hybrid"optional
sortBy"name" | "startAt" | "createdAt"optional
sortOrder"asc" | "desc"optional
  • attendeeCount is sold seats, not people checked in. Use checkin_stats for that.

Output

structuredContentcopy
{
  "events": [{
    "id": "evt_…", "slug": "…", "name": "…",
    "visibility": "public" | "unlisted" | "private",
    "locationType": "online" | "offline" | "hybrid",
    "startAt": "2026-10-03T19:00:00+02:00", "endAt": "…" | null,
    "timezone": "Europe/Ljubljana",
    "maxCapacity": 30 | null, "attendeeCount": 24 | null,
    "isSeries": false
  }],
  "total": 3, "limit": 20, "offset": 0, "nextOffset": null
}

Example

tools/callcopy
{ "name": "events_list",
  "arguments": { "timeFilter": "upcoming", "visibility": "private", "limit": 10 } }

events_get

events:readpermission events.viewread-onlyidempotent

Full detail of one event, including its ticket types.

Input

FieldTypeNotes
eventIdstringrequiredFrom events_list, for example evt_abc123.
  • attendeeCount is null here. It is populated only by events_list.

Output

structuredContentcopy
{
  …event summary fields,
  "descriptionText": "…" | null,
  "address": "…" | null, "latitude": 46.05 | null, "longitude": 14.5 | null,
  "meetingUrl": "…" | null,
  "requireApproval": false, "enableWaitlist": true, "showGuestList": false,
  "seriesId": "…" | null,
  "ticketTypes": [{ "id": "…", "name": "…", "priceCents": 4500, "currency": "EUR" }],
  "createdAt": "…", "updatedAt": "…"
}

Example

tools/callcopy
{ "name": "events_get", "arguments": { "eventId": "evt_abc123" } }

events_create

events:writepermission events.manage

Create an event, or a recurring series. Same fields as the console form, with a plain-text description.

Input

FieldTypeNotes
namestring ≤200required
locationType"online" | "offline" | "hybrid"requiredOnline and hybrid need meetingUrl.
startAtISO 8601 with offsetrequired
endAtISO 8601 with offsetoptional
timezoneIANA namerequiredFor example Europe/Ljubljana.
descriptionTextstring ≤20000optionalPlain text. Blank lines separate paragraphs.
visibility"public" | "unlisted" | "private"optionalDefault public.
geoAddressobjectoptionalplaceName, street, city, state, country, postalCode.
latitude, longitudenumberoptional
meetingUrlURLoptional
maxCapacityinteger 1-1000000optional
requireApproval, enableWaitlist, showGuestListbooleanoptional
recurrenceobjectoptionalfreq, interval, byWeekday, monthlyMode, ends. Makes a series. For weekly, byWeekday must include the start weekday.
  • Ticket types cannot be created here. Add them in the console.
  • Rich text and themes are not accepted. The server converts descriptionText to the stored document.

Output

structuredContentcopy
{
  …event summary fields,
  "descriptionText": "…" | null,
  "address": "…" | null, "latitude": 46.05 | null, "longitude": 14.5 | null,
  "meetingUrl": "…" | null,
  "requireApproval": false, "enableWaitlist": true, "showGuestList": false,
  "seriesId": "…" | null,
  "ticketTypes": [{ "id": "…", "name": "…", "priceCents": 4500, "currency": "EUR" }],
  "createdAt": "…", "updatedAt": "…"
}

Example

tools/callcopy
{ "name": "events_create",
  "arguments": {
    "name": "Onboarding Q&A", "locationType": "online",
    "startAt": "2026-09-15T18:00:00+02:00", "endAt": "2026-09-15T19:00:00+02:00",
    "timezone": "Europe/Ljubljana", "meetingUrl": "https://meet.example.com/x",
    "descriptionText": "Bring your questions."
  } }

events_update

events:writepermission events.manageidempotent

Change any subset of fields on an event, or on part of a series.

Input

FieldTypeNotes
eventIdstringrequiredFrom events_list, for example evt_abc123.
scope"this" | "following" | "all"optionalRequired only when the event belongs to a recurring series.
…any create fieldoptionalAll optional. Omitted fields keep their value.
descriptionTextstring | nulloptionalPass null to clear.
maxCapacityinteger | nulloptionalPass null to remove the cap.
  • A series event without scope returns a tool error asking for one.

Output

structuredContentcopy
{
  …event summary fields,
  "descriptionText": "…" | null,
  "address": "…" | null, "latitude": 46.05 | null, "longitude": 14.5 | null,
  "meetingUrl": "…" | null,
  "requireApproval": false, "enableWaitlist": true, "showGuestList": false,
  "seriesId": "…" | null,
  "ticketTypes": [{ "id": "…", "name": "…", "priceCents": 4500, "currency": "EUR" }],
  "createdAt": "…", "updatedAt": "…"
}

Example

tools/callcopy
{ "name": "events_update",
  "arguments": { "eventId": "evt_abc123", "maxCapacity": 80 } }

events_delete

events:writepermission events.deletedestructiveidempotent

Cancel an event. A soft cancel: the event stays in the console as cancelled.

Input

FieldTypeNotes
eventIdstringrequiredFrom events_list, for example evt_abc123.
scope"this" | "following" | "all"optionalRequired only when the event belongs to a recurring series.
confirmtruerequiredMust be literally true. Ask the user first.
  • Carries destructiveHint. Clients that honour it ask the user before calling. The confirm field covers clients that do not.
  • There is no hard delete over MCP.

Output

structuredContentcopy
{ "id": "evt_abc123", "deleted": true }

Example

tools/callcopy
{ "name": "events_delete",
  "arguments": { "eventId": "evt_abc123", "confirm": true } }

registrations_list

registrations:readpermission registrations.viewread-onlyidempotent

Attendees of one event, with paging and filters.

Input

FieldTypeNotes
eventIdstringrequiredFrom events_list, for example evt_abc123.
limitinteger 1-100optionalDefault 20.
offsetintegeroptionalDefault 0.
searchstring ≤200optionalAttendee name or email.
status"pending" | "confirmed" | "cancelled" | "waitlisted" | "rejected" | "awaiting_approval"optional
type"ticket" | "rsvp"optional
ticketTypeIdstringoptional
sortBy, sortOrderstringoptional
  • Never returns the check-in QR signature or answers to registration questions. Those fields do not exist at any permission level.
  • Email and phone are not in the list. Use registrations_get.

Output

structuredContentcopy
{
  "registrations": [{
    "id": "reg_…", "eventId": "evt_…",
    "type": "ticket" | "rsvp", "status": "confirmed",
    "attendeeName": "…",
    "createdAt": "…", "cancelledAt": "…" | null
  }],
  "total": 88, "limit": 20, "offset": 0, "nextOffset": 20
}

Example

tools/callcopy
{ "name": "registrations_list",
  "arguments": { "eventId": "evt_abc123", "status": "waitlisted" } }

registrations_get

registrations:readpermission registrations.viewread-onlyidempotent

One registration. Contact fields appear only when the caller holds registrations.manage.

Input

FieldTypeNotes
eventIdstringrequiredFrom events_list, for example evt_abc123.
registrationIdstringrequiredFrom registrations_list.
  • The permission check shapes the output. It never fails the call.

Output

structuredContentcopy
{
  …registration summary fields,
  "email": "…",        // only with registrations.manage
  "phone": "…" | null  // only with registrations.manage
}

Example

tools/callcopy
{ "name": "registrations_get",
  "arguments": { "eventId": "evt_abc123", "registrationId": "reg_def456" } }

checkin_stats

registrations:readpermission registrations.viewread-onlyidempotent

Aggregate attendance counts for one event. Live during the event.

Input

FieldTypeNotes
eventIdstringrequiredFrom events_list, for example evt_abc123.
  • Counts only. No names, no list.
  • There is no tool to mark attendance or add a walk-in.

Output

structuredContentcopy
{
  "allGuests": 150,  // ticket seats + RSVP-only guests
  "going": 32,       // confirmed, not yet checked in
  "checkedIn": 118,
  "notGoing": 4,     // guest cancellations
  "declined": 2,     // organizer-rejected approvals
  "pending": 6,
  "waitlisted": 12,
  "rsvp": 20         // RSVP-only guests
}

Example

tools/callcopy
{ "name": "checkin_stats", "arguments": { "eventId": "evt_abc123" } }

ticket_types_list

events:readpermission events.viewread-onlyidempotent

Ticket types of one event: price, sales window, caps.

Input

FieldTypeNotes
eventIdstringrequiredFrom events_list, for example evt_abc123.
  • Never returns member-tier pricing or admin-fee configuration.
  • Does not compute remaining inventory.

Output

structuredContentcopy
{
  "ticketTypes": [{
    "id": "…", "name": "…", "description": "…" | null,
    "type": "free" | "paid", "priceCents": 4500, "currency": "EUR",
    "access": "everyone" | "members_only",
    "isHidden": false, "requireApproval": false,
    "maxQuantity": 100 | null, "seatsPerTicket": 1, "maxPerAttendee": 4 | null,
    "salesStartAt": "…" | null, "salesEndAt": "…" | null,
    "sortOrder": 0
  }]
}

Example

tools/callcopy
{ "name": "ticket_types_list", "arguments": { "eventId": "evt_abc123" } }

Errors.

Transport problems are HTTP errors. Problems the model can fix are tool results with isError: true and a plain message.

401 invalid_tokenMissing, expired, revoked, wrong audience, or the user is no longer staff. Re-authorize.
403 insufficient_scope · scope="events:write"The token lacks the scope the tool needs. Repeat authorization with the wider scope. Existing grants on other devices stay valid.
403 · error_description onlyThe organization has assistant access turned off. No error code, so clients do not loop on re-authorization.
404The deployment has MCP disabled. Endpoint, metadata and OAuth routes all return 404.
429Over 60 calls per minute on this token. Back off and retry.
isError: trueValidation failure, missing scope on a series event, not found, or the staff role lacks the permission. Read the message and adjust the call.

Conventions.

Dates are ISO 8601 with an offset. Time zones are IANA names. Always pass one when you set a date and time.

Results carry structuredContent, validated against the tool's output schema, plus a text block with a one-line summary and the same JSON.

Series: events in a recurring series need scope on update and delete: this, following or all.

Descriptions are plain text in and out. Blank lines separate paragraphs.

tools/list is static and cacheable: cacheScope: private, ttlMs: 300000.

Audit: every create, update and delete writes an audit row with source: mcp and the client ID.

Origin: browser requests must come from an allowed origin. Requests without an Origin header, such as command-line clients, are allowed. The bearer token is what authenticates.

Permissions resolve through the same resolver as the console, so custom roles behave the same way.