MCP setup

Build an AI agent (Claude, custom assistant, etc.) that registers people for events on their behalf via MCP.

This guide walks through the end-to-end flow: provisioning an agent API account, discovering the MCP endpoint, verifying the user's email with an OTP, and submitting a registration that the user completes (paying if needed) via a returned resume URL.

Payment is always a human step.agent_submit_registration creates the participant + advances them to whatever step is next. When that step is checkout, the agent receives a URL — it does NOT receive payment intent details. The user must open the URL to complete payment.

1. Get an agent API account

Ask your Jade administrator to provision an ApiAccount with canActAsParticipantAgent: true and allowedClients / allowedEvents scoped to the events you'll act on. Each entry in allowedClients is a { tenantCode, clientCode } object; each entry in allowedEvents is a { tenantCode, clientCode, eventCode } object. Copy the bearer token at issue time; plaintext is unrecoverable afterward.

2. Discover the endpoint

curl /api/.well-known/mcp.json

The response lists every externally-callable MCP endpoint, its transport (currently streamable-http), and the tools it exposes. The participant-agent endpoint is the one you want.

3. Connect

Point your MCP client at:

POST /api/mcp/participant-agent
Authorization: Bearer jdo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

The bearer is required on every call. The server will fail 403 Forbidden if the token lacks the canActAsParticipantAgent flag.

4. Request an OTP

Call agent_request_otp with the human's email + the target event. We send a 6-digit code to that inbox. The user reads the email and reads the code back to the agent.

// MCP tool call
{
  "name": "agent_request_otp",
  "arguments": {
    "clientCode": "acme",
    "eventCode": "acme-2026",
    "email": "alex@example.com"
  }
}

// Response
{
  "sent": true,
  "expiresInSeconds": 900
}

Throttles:

  • 3 codes per email per hour (per-inbox cap).
  • 200 codes per agent account per day (anti-harvest cap).

5. Verify the OTP

// MCP tool call
{
  "name": "agent_verify_otp",
  "arguments": {
    "clientCode": "acme",
    "eventCode": "acme-2026",
    "email": "alex@example.com",
    "code": "421907"
  }
}

On success the server returns a session token:

{
  "verified": true,
  "session": {
    "token": "eyJ...session-token...",
    "expiresAt": "2026-05-21T13:14:00.000Z"
  },
  "participantExists": false
}

Pass this token on every subsequent call in the X-Participant-Session header. The session is scoped to that single (clientCode, eventCode, email) for 1 hour — request a fresh OTP after expiry. Wrong codes burn the OTP after 3 attempts.

6. Discover the flows

Call agent_list_flows to see what registration entry points the event exposes (attendee, exhibitor, speaker, etc.) along with the field schema for each. Use this to decide which flow to register the user under and which fields you still need to collect from them.

// MCP tool call (uses X-Participant-Session header)
{
  "name": "agent_list_flows",
  "arguments": {}
}

// Response (abridged)
{
  "flows": [
    {
      "slug": "primary-attendee",
      "name": "Attendee Registration",
      "visibleForTags": null,
      "descriptor": { /* page layout + field bindings */ }
    },
    {
      "slug": "exhibitor",
      "name": "Exhibitor Registration",
      "visibleForTags": { "all": [{ "tag": "exhibitor" }] },
      "descriptor": { /* page layout + field bindings */ }
    }
  ]
}

7. Submit the registration

Send everything you know about the user. The more fields you can provide up front, the fewer follow-up prompts the user will see on the resume URL.

// MCP tool call
{
  "name": "agent_submit_registration",
  "arguments": {
    "flowSlug": "primary-attendee",
    "data": {
      "@participant.firstName": "Alex",
      "@participant.lastName":  "Rivera",
      "@custom.tShirtSize":     "L",
      "@custom.dietaryNotes":   "vegetarian"
    }
  }
}

// Response (new registration)
{
  "status": "new",
  "matchStatus": "new",
  "url": "https://app.example.com/client/acme/event/acme-2026/register/primary-attendee?t=...",
  "jwt": "eyJ...resume-token...",
  "participantId": "507f1f77bcf86cd799439011",
  "flowSlug": "primary-attendee"
}

Field keys use the @entity.property token format — @participant.* for built-in fields, @custom.* for the event's custom fields. The session's verified email is automatically stamped — you cannot register a different email under someone else's session.

8. Hand off to the user

The response carries:

  • url — the resume URL the user opens to finish the flow (including any payment step).
  • jwt — a session-resume token baked into the URL for fresh or incomplete registrations.
  • matchStatusnew, existing_incomplete, or existing_complete (the modify-login URL flow).

After the user finishes

Use the read-only participant tools to confirm completion or fetch details: get_my_registration, check_balance_due, describe_my_flow. See the MCP overview for the full participant-agent tool catalog.