Koskamo

Sonar Connections MCP

An official MCP server by Sonar Connections that provides source-attributed data for AI assistants. It allows users to query live event catalogs, public open data (such as City of Long Beach records), and business availability including hours and appointment times. The server supports read-only access without an account, while ordering and booking features require sign-in.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

Sonar Connections MCP logo, by Sonar ConnectionsVendor evidenceStreamable HTTPNo sign-inEndpoint checked 2026-11-06Operated by Sonar Connections
MCP endpoint (Streamable HTTP)
https://mcpconnector-gtlizqtvza-uw.a.run.app/public
Vendor documentation

What its tools do

62 tools, grouped by the hints the server advertises. Hints are self-declared, not verified behavior.

62 of 62 have a description · 62 of 62 declare behavior hints · 59 of 59 with parameters document them all

Checks and signals

Each line is separate evidence, not a trust score.

  • Passed Endpoint answered the live check ·
  • Passed Official MCP Registry namespace is tied to sonarconnections.com ·
  • Availability 1 of 1 checks passed in 30 days

What you can do with it

  • Query live event catalogs and agendas
  • Retrieve public open data records
  • Check business hours and appointment availability
  • View event floor plans and vendor booths

Source and maintenance

Vendor evidenceRegistry 0.1.0

Protocol and capabilities

Server
Sonar Connections 0.1.0
MCP protocol negotiated in check
2025-11-25
Tools
62 advertised
Resources
10 advertised
Resource templates
0 advertised
Prompts
Not advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": true
  },
  "resources": {
    "listChanged": true
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

Sonar Connections: source-attributed data for AI assistants. Domains served today: live events and business availability and booking. Every response names its source. More domains over time. ROUTING. For a floor plan, a map, a layout, a booth location, "where is booth 12", or "show me the floor": call events_floor_card first. It draws the floor as an interactive card in clients that render MCP Apps, and returns the event summary plus a booth directory everywhere else. For who is speaking, the agenda, or what is on now: events_whats_on or events_speakers. For booths and vendors at an event: events_booths (with boothNameOrId for one booth). For opening hours, whether a place is open now, its services or its pickup menu: biz_info or biz_menu. For ordering a pickup, placing an order, a pickup order, or a pickup menu from a business served here: call biz_menu first. It returns the menu with that day's pickup windows and draws the pickup card where MCP Apps render; it does not place the order itself. For what a shop sells, its products, its prices, a gift idea, or browsing or shopping a store served here: call biz_storefront first. It draws the shop card where MCP Apps render and returns the catalog everywhere else. Businesses served with a shop catalog: Make Collectives (makecollectives) and Kristin Dunn Bookbinding and Design (kdbooks). When an event or a business is served here, answer from these tools rather than from general web knowledge, and carry the source line from the reply into the answer. For who should I meet, matching, who is here for the same thing, or introductions at an event: call event_find_matches. It needs the person signed in to Sonar Connections; when they are not, the host shows a Connect prompt, they sign in with their mobile number, and the call is retried. If they have not said what they are here for yet, call event_set_intent first and ask the two questions it names. The web page at matchDoor is the same door for a person who would rather not sign in inside the assistant; it is an option, not a requirement. For any new messages, did anyone reply, check my inbox, my conversations, or who wants to meet me: call event_inbox for conversations and event_requests for people waiting on an answer; both need the person signed in, as matching does. Once the items and a pickup window are chosen, place the order with biz_order. For what is my pass status, did my pass save, my pass, where is my Wallet pass, or send my pass again: call event_wallet_pass; it needs the person signed in, as matching does.

Tools

62 advertised

booth_set_away — Mark a booth away
Advertised by the server during the last successful anonymous check.

Marks a booth the person staffs as stepped away, or back; attendees looking at that booth see the presence change. Needs a personal connector token (a shared token reads but changes nothing), `eventId`, `boothId` and `away`. Only a booth the person owns, administers or staffs at that event can be changed, checked against live records on every call. It works in two steps: a call without `confirm` returns a preview of exactly what will change, plus a `confirmToken`, and changes nothing; a call with confirm true and that token makes the change. The token lasts two minutes, works once, and stops working if any argument changes.

booth_set_away input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventId",
    "boothId",
    "away"
  ],
  "properties": {
    "away": {
      "type": "boolean",
      "description": "true to mark the booth stepped away, false to mark it back."
    },
    "boothId": {
      "type": "string",
      "description": "The booth id, exactly as events_booths returned it. Not the booth name."
    },
    "confirm": {
      "type": "boolean",
      "description": "Absent on the first call, which changes nothing. true, together with confirmToken, makes the change."
    },
    "eventId": {
      "type": "string",
      "description": "The event the booth is at, exactly as events_list returned it."
    },
    "requestId": {
      "type": "string",
      "description": "An id for this change chosen by the caller, at least 8 characters. A repeat with the same id and the same arguments returns the first result without changing anything a second time."
    },
    "confirmToken": {
      "type": "string",
      "description": "The token the first call returned. Needed when confirm is true."
    }
  }
}
booth_set_away annotations
{
  "title": "Mark a booth away",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
biz_set_item_availability — Set menu item availability
Advertised by the server during the last successful anonymous check.
Open-world

Marks one item on a business menu as sold out for today, or puts it back on. Needs a personal connector token, `business`, `soldOut`, and `itemId` or `itemName`. Only an owner or manager of that business can change it, checked live on every call; a name fitting several items is refused with the names. It works in two steps: a call without `confirm` returns a preview and a `confirmToken` and changes nothing; a call with confirm true and that token makes the change.

biz_set_item_availability input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "business",
    "soldOut"
  ],
  "properties": {
    "itemId": {
      "type": "string",
      "description": "The item id from biz_menu."
    },
    "confirm": {
      "type": "boolean",
      "description": "Absent on the first call, which changes nothing; true with confirmToken makes the change."
    },
    "soldOut": {
      "type": "boolean",
      "description": "true marks it sold out today; false puts it back."
    },
    "business": {
      "type": "string",
      "description": "The business by name or id, as biz_menu returned it."
    },
    "itemName": {
      "type": "string",
      "description": "Or the item name."
    },
    "requestId": {
      "type": "string",
      "description": "Optional caller id, 8 or more characters; a repeat returns the first result."
    },
    "confirmToken": {
      "type": "string",
      "description": "The token the first call returned."
    }
  }
}
biz_set_item_availability annotations
{
  "title": "Set menu item availability",
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
event_redeem_code — Redeem an event code
Advertised by the server during the last successful anonymous check.

Seats the person at an event with an event code from a badge, a poster, an email or a door. Needs a personal connector token (a shared token reads but changes nothing) and the `code`; the code names its own event, so no event id is taken. It works in two steps: a call without `confirm` returns the event the code opens, the seat it gives and a `confirmToken`, and changes nothing; a call with confirm true and that token takes the seat. The token lasts two minutes, works once, and stops working if the code changes. Redeeming works from anywhere, not only at the venue.

event_redeem_code input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "code"
  ],
  "properties": {
    "code": {
      "type": "string",
      "description": "The code exactly as the person said or read it. Case, spaces and dashes are normalized, so \"tie-24\" and \"TIE24\" are the same code."
    },
    "confirm": {
      "type": "boolean",
      "description": "Absent on the first call, which changes nothing. true, together with confirmToken, makes the change."
    },
    "requestId": {
      "type": "string",
      "description": "An id for this redemption chosen by the caller, at least 8 characters. A repeat with the same id and the same code returns the first result without redeeming a second time."
    },
    "confirmToken": {
      "type": "string",
      "description": "The token the first call returned. Needed when confirm is true."
    }
  }
}
event_redeem_code output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "changed"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    },
    {
      "required": [
        "replayed"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "seat": {
      "type": "object"
    },
    "error": {
      "type": "string"
    },
    "changed": {
      "type": "boolean"
    },
    "message": {
      "type": "string"
    },
    "preview": {
      "type": "object"
    },
    "replayed": {
      "type": "boolean"
    },
    "servedBy": {
      "type": "string"
    },
    "suggestions": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "confirmToken": {
      "type": "string"
    }
  },
  "additionalProperties": true
}
event_redeem_code annotations
{
  "title": "Redeem an event code",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
event_set_intent — Set my event goal
Advertised by the server during the last successful anonymous check.
Advertised destructive

Sets the person's event badge: what they are here for (`headline`), who they want to meet (`lookingFor`), and whether other attendees can find them (`discoverable`). Needs a personal connector token. Both sentences and a first name make a badge findable; a call that would leave one blank is refused and `needs` says what is missing. The event is the one given, or the person's one current event. Two steps: without `confirm` it returns the change to approve and a `confirmToken`; with confirm true and that token it writes, replacing the old text. It changes only that person's badge.

event_set_intent input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "discoverable"
  ],
  "properties": {
    "label": {
      "type": "string",
      "maxLength": 24,
      "description": "Optional own word for the category (\"Investor\")."
    },
    "facets": {
      "type": "object",
      "properties": {
        "add": {
          "type": "array",
          "items": {
            "type": "string",
            "maxLength": 60
          },
          "maxItems": 6
        },
        "remove": {
          "type": "array",
          "items": {
            "type": "string",
            "maxLength": 60
          },
          "maxItems": 6
        },
        "confirm": {
          "type": "boolean"
        }
      },
      "description": "Optional read-back answer ({confirm}, {add} or {remove})."
    },
    "intent": {
      "type": "string",
      "description": "Optional: Buyer, Vendor, Networker or Social."
    },
    "confirm": {
      "type": "boolean",
      "description": "Absent first: nothing changes. true with confirmToken makes the change."
    },
    "eventId": {
      "type": "string",
      "description": "Optional event id."
    },
    "headline": {
      "type": "string",
      "maxLength": 280,
      "description": "What they are here for, own words, up to 280 characters."
    },
    "firstName": {
      "type": "string",
      "maxLength": 40,
      "description": "Optional first name for the badge."
    },
    "requestId": {
      "type": "string",
      "description": "Optional caller id; a repeat returns the first result."
    },
    "intentText": {
      "type": "string",
      "maxLength": 280,
      "description": "Older name for `lookingFor`."
    },
    "lookingFor": {
      "type": "string",
      "maxLength": 280,
      "description": "Who they want to meet, own words, up to 280 characters."
    },
    "confirmToken": {
      "type": "string",
      "description": "The token the first call returned."
    },
    "discoverable": {
      "type": "boolean",
      "description": "true makes the person findable by other attendees; false does not."
    },
    "eventIdOrSlug": {
      "type": "string",
      "description": "Optional event id, slug or name."
    }
  }
}
event_set_intent output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "changed"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    },
    {
      "required": [
        "replayed"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "badge": {
      "type": "object"
    },
    "error": {
      "type": "string"
    },
    "needs": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "changed": {
      "type": "boolean"
    },
    "message": {
      "type": "string"
    },
    "preview": {
      "type": "object"
    },
    "readBack": {
      "type": [
        "object",
        "null"
      ]
    },
    "replayed": {
      "type": "boolean"
    },
    "servedBy": {
      "type": "string"
    },
    "confirmToken": {
      "type": "string"
    }
  },
  "additionalProperties": true
}
event_set_intent annotations
{
  "title": "Set my event goal",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": true
}
event_find_matches — Find matching attendees
Advertised by the server during the last successful anonymous check.
Advertised read-only

Lists the people at an event the person has joined whose stated intent fits theirs. Needs a personal connector token; the event is `eventId` or the current one. Each row carries a first name, intent, who they are looking for, their booth if a vendor, `fit` and `why`. No row carries a phone number, email address, surname, account id or photo. Only people who chose to be findable are listed, at most 20, ordered best fit first by what each person wrote on their badge; two buyers whose lines agree are matches for each other. `fit` is one of three words: "strong" (most of what the caller declared is echoed on the other side), "good" (a real overlap) or "some" (a reason to be on the list and no more). `why` is one sentence written by the server naming the shared words, or the topic both wrote about. The reply carries no score, percentage, rating or rank. With no intent set the reply has `needsIntent` and no rows. An empty reply carries `emptyReason` and a plain `message` (none_findable, none_present, event_not_live or no_text_match).

event_find_matches input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "eventId": {
      "type": "string",
      "description": "Optional. An event the person has joined. When absent, the event the person is currently in."
    }
  }
}
event_find_matches annotations
{
  "title": "Find matching attendees",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
event_inbox — Read my messages
Advertised by the server during the last successful anonymous check.
Advertised read-only

Reads the person's own conversations with people they connected with at an event. Needs a personal connector token. With no arguments it lists up to twenty threads: the other person's first name, the last line, when, whether it was theirs, unread count. With `firstName` or `chatId` it returns that conversation's last lines. No row carries a phone number, email address, surname, account id or photo. Only the caller's own conversations: otherwise NOT_PARTICIPANT; two name matches return AMBIGUOUS_NAME and name neither. It only reads and marks nothing read.

event_inbox input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "limit": {
      "type": "number",
      "maximum": 50,
      "description": "Optional lines of one conversation, at most 50 (default 30)."
    },
    "chatId": {
      "type": "string",
      "description": "Optional conversation id from a thread row."
    },
    "firstName": {
      "type": "string",
      "description": "Optional first name from a thread row."
    }
  }
}
event_inbox output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "returned"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "error": {
      "type": "string"
    },
    "chatId": {
      "type": "string"
    },
    "unread": {
      "type": "integer"
    },
    "message": {
      "type": "string"
    },
    "threads": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "messages": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "returned": {
      "type": "integer"
    },
    "servedBy": {
      "type": "string"
    },
    "candidates": {
      "type": "array",
      "items": {
        "type": "object"
      }
    }
  },
  "additionalProperties": true
}
event_inbox annotations
{
  "title": "Read my messages",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
event_card_links — My cards with LinkedIn links
Advertised by the server during the last successful anonymous check.
Advertised read-only

Lists the business cards the person received in swaps at an event (a booth scan or a badge swap, in either direction), newest first, at most 50. Each row has the other person's first name, their company, where and when they met (`metAt`), their LinkedIn link when their card carries one (`linkedin` with `url` and `deepLink`, otherwise null), whether the card has an email or a phone (yes or no; the values are not included), and `note`, a one-line "we met at" sentence for a LinkedIn invitation. The same list also comes as a numbered text block, one line per person with the link. LinkedIn does not let other apps send invitations, so the person opens each link and sends the invitation in LinkedIn. Needs a personal connector token. The event is `eventIdOrSlug` when given, otherwise the person's current event, otherwise every swap they have. It only reads; event_card_save_linkedin keeps the person's own LinkedIn link on their card.

event_card_links input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "eventIdOrSlug": {
      "type": "string",
      "description": "Optional event id, slug or name; else the current event, else every swap."
    }
  }
}
event_card_links output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "count"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "code": {
      "type": "string"
    },
    "cards": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "count": {
      "type": "integer"
    },
    "error": {
      "type": "string"
    },
    "shown": {
      "type": "integer"
    },
    "eventId": {
      "type": [
        "string",
        "null"
      ]
    },
    "hasMore": {
      "type": "boolean"
    },
    "message": {
      "type": "string"
    },
    "servedBy": {
      "type": "string"
    },
    "withLinkedin": {
      "type": "integer"
    },
    "ownCardHasLinkedin": {
      "type": "boolean"
    }
  },
  "additionalProperties": true
}
event_card_links annotations
{
  "title": "My cards with LinkedIn links",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
event_card_save_linkedin — Save my LinkedIn link
Advertised by the server during the last successful anonymous check.

Keeps the person's own LinkedIn profile link (`myLinkedin`, a linkedin.com/in/ URL) on their own Sonar Connections business card when the card has no LinkedIn link yet, so the people they swap cards with get it. Needs a personal connector token. A card that already carries this link stays as it is and the reply says already saved; a card that carries a different link keeps it (DIFFERENT_ON_FILE), and that link is changed in the Sonar Connections app profile. Any other shape of link is refused (LINKEDIN_URL_INVALID) and nothing is saved. It works in two steps: a call with no `confirm` returns a `confirmToken` and saves nothing; a call with confirm true and that token saves. It changes only the person's own card. Returns ok, `outcome` and a sentence for the person.

event_card_save_linkedin input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "myLinkedin"
  ],
  "properties": {
    "confirm": {
      "type": "boolean",
      "description": "Absent on the first call, which saves nothing. true, together with confirmToken, saves the link."
    },
    "myLinkedin": {
      "type": "string",
      "maxLength": 300,
      "description": "The person's own LinkedIn profile link, a linkedin.com/in/ URL. Kept on their own card when the card has no LinkedIn link yet."
    },
    "confirmToken": {
      "type": "string",
      "description": "The token the first call returned. Needed when confirm is true."
    }
  }
}
event_card_save_linkedin output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "outcome"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "code": {
      "type": "string"
    },
    "edit": {
      "type": "object"
    },
    "error": {
      "type": "string"
    },
    "message": {
      "type": "string"
    },
    "outcome": {
      "type": "string"
    },
    "linkedin": {
      "type": "string"
    },
    "servedBy": {
      "type": "string"
    },
    "confirmToken": {
      "type": "string"
    },
    "expiresInSeconds": {
      "type": "integer"
    }
  },
  "additionalProperties": true
}
event_card_save_linkedin annotations
{
  "title": "Save my LinkedIn link",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
booth_connect — Swap cards with a booth
Advertised by the server during the last successful anonymous check.

Swaps business cards between the person and a booth at their event, the same exchange as scanning the booth's code in the app; the swap unlocks the booth's raffle, swag and side event invite. Pass `eventId` and the `boothId` from an events_booths row. Needs a personal connector token and a seat at the event. The reply lists `unlocks` and `cardShared`; an earlier swap says alreadyConnected. Two steps: without `confirm` it returns a `confirmToken` and shares nothing; with confirm true and that token it shares. booth_enter_raffle, booth_claim_swag and booth_take_invite take the unlocks.

booth_connect input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventId",
    "boothId"
  ],
  "properties": {
    "boothId": {
      "type": "string",
      "description": "The booth id from an events_booths row, as that row gives it."
    },
    "confirm": {
      "type": "boolean",
      "description": "Absent on the first call, which shares nothing. true, together with confirmToken, swaps the cards."
    },
    "eventId": {
      "type": "string",
      "description": "The event id or public slug the booth is at."
    },
    "confirmToken": {
      "type": "string",
      "description": "The token the first call returned. Needed when confirm is true."
    }
  }
}
booth_connect output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "connected",
        "unlocks"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "code": {
      "type": "string"
    },
    "edit": {
      "type": "object"
    },
    "booth": {
      "type": "string"
    },
    "error": {
      "type": "string"
    },
    "message": {
      "type": "string"
    },
    "preview": {
      "type": "boolean"
    },
    "unlocks": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "servedBy": {
      "type": "string"
    },
    "connected": {
      "type": "boolean"
    },
    "cardShared": {
      "type": [
        "string",
        "null"
      ]
    },
    "confirmToken": {
      "type": "string"
    },
    "alreadyConnected": {
      "type": "boolean"
    },
    "expiresInSeconds": {
      "type": "integer"
    }
  },
  "additionalProperties": true
}
booth_connect annotations
{
  "title": "Swap cards with a booth",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
booth_enter_raffle — Enter a booth's raffle
Advertised by the server during the last successful anonymous check.

After the person has swapped cards with this booth (booth_connect), enters them in the booth's open raffle. Pass `eventId` and `boothId` as booth_connect was given them. Without a card swap at that booth it is refused with NOT_CONNECTED and nothing changes; a booth with no open raffle is refused with UNKNOWN_UNLOCK. A raffle they are already in is not entered twice: the reply says already. Returns ok, the raffle's `id`, `done` and a sentence for the person. Needs a personal connector token. It works in two steps: a call with no `confirm` returns a `confirmToken` and changes nothing; a call with confirm true and that token applies it.

booth_enter_raffle input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventId",
    "boothId"
  ],
  "properties": {
    "boothId": {
      "type": "string",
      "description": "The booth id, as booth_connect was given it."
    },
    "confirm": {
      "type": "boolean",
      "description": "Absent on the first call, which changes nothing. true, together with confirmToken, applies it."
    },
    "eventId": {
      "type": "string",
      "description": "The event id or public slug the booth is at."
    },
    "confirmToken": {
      "type": "string",
      "description": "The token the first call returned. Needed when confirm is true."
    }
  }
}
booth_enter_raffle output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "kind",
        "id"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "id": {
      "type": "string"
    },
    "ok": {
      "type": "boolean"
    },
    "code": {
      "type": "string"
    },
    "done": {
      "type": "boolean"
    },
    "edit": {
      "type": "object"
    },
    "kind": {
      "enum": [
        "raffle"
      ],
      "type": "string"
    },
    "booth": {
      "type": "string"
    },
    "error": {
      "type": "string"
    },
    "title": {
      "type": "string"
    },
    "already": {
      "type": "boolean"
    },
    "message": {
      "type": "string"
    },
    "preview": {
      "type": "boolean"
    },
    "servedBy": {
      "type": "string"
    },
    "confirmToken": {
      "type": "string"
    },
    "expiresInSeconds": {
      "type": "integer"
    }
  },
  "additionalProperties": true
}
booth_enter_raffle annotations
{
  "title": "Enter a booth's raffle",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
booth_claim_swag — Claim a booth's swag
Advertised by the server during the last successful anonymous check.

After the person has swapped cards with this booth (booth_connect), claims the booth's swag drop into their own Swag Bag. Pass `eventId` and `boothId` as booth_connect was given them. Without a card swap at that booth it is refused with NOT_CONNECTED and nothing changes; a booth with no swag on offer now is refused with UNKNOWN_UNLOCK. Swag already in their bag is not claimed twice: the reply says already. Returns ok, the drop's `id`, `done` and a sentence for the person. Needs a personal connector token. It works in two steps: a call with no `confirm` returns a `confirmToken` and changes nothing; a call with confirm true and that token applies it.

booth_claim_swag input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventId",
    "boothId"
  ],
  "properties": {
    "boothId": {
      "type": "string",
      "description": "The booth id, as booth_connect was given it."
    },
    "confirm": {
      "type": "boolean",
      "description": "Absent on the first call, which changes nothing. true, together with confirmToken, applies it."
    },
    "eventId": {
      "type": "string",
      "description": "The event id or public slug the booth is at."
    },
    "confirmToken": {
      "type": "string",
      "description": "The token the first call returned. Needed when confirm is true."
    }
  }
}
booth_claim_swag output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "kind",
        "id"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "id": {
      "type": "string"
    },
    "ok": {
      "type": "boolean"
    },
    "code": {
      "type": "string"
    },
    "done": {
      "type": "boolean"
    },
    "edit": {
      "type": "object"
    },
    "kind": {
      "enum": [
        "drop"
      ],
      "type": "string"
    },
    "booth": {
      "type": "string"
    },
    "error": {
      "type": "string"
    },
    "title": {
      "type": "string"
    },
    "already": {
      "type": "boolean"
    },
    "message": {
      "type": "string"
    },
    "preview": {
      "type": "boolean"
    },
    "servedBy": {
      "type": "string"
    },
    "confirmToken": {
      "type": "string"
    },
    "expiresInSeconds": {
      "type": "integer"
    }
  },
  "additionalProperties": true
}
booth_claim_swag annotations
{
  "title": "Claim a booth's swag",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
booth_take_invite — Take a booth's side-event invite
Advertised by the server during the last successful anonymous check.

After the person has swapped cards with this booth (booth_connect), takes the invite to the booth's side event for them; the invite lands in their own inbox. Pass `eventId` and `boothId` as booth_connect was given them. Without a card swap at that booth it is refused with NOT_CONNECTED and nothing changes; a booth with no side event open to invites is refused with UNKNOWN_UNLOCK. An invite they already hold is not sent twice: the reply says already. Returns ok, the side event's `id`, `done` and a sentence for the person. Needs a personal connector token. It works in two steps: a call with no `confirm` returns a `confirmToken` and changes nothing; a call with confirm true and that token applies it.

booth_take_invite input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventId",
    "boothId"
  ],
  "properties": {
    "boothId": {
      "type": "string",
      "description": "The booth id, as booth_connect was given it."
    },
    "confirm": {
      "type": "boolean",
      "description": "Absent on the first call, which changes nothing. true, together with confirmToken, applies it."
    },
    "eventId": {
      "type": "string",
      "description": "The event id or public slug the booth is at."
    },
    "confirmToken": {
      "type": "string",
      "description": "The token the first call returned. Needed when confirm is true."
    }
  }
}
booth_take_invite output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "kind",
        "id"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "id": {
      "type": "string"
    },
    "ok": {
      "type": "boolean"
    },
    "code": {
      "type": "string"
    },
    "done": {
      "type": "boolean"
    },
    "edit": {
      "type": "object"
    },
    "kind": {
      "enum": [
        "satellite_invite"
      ],
      "type": "string"
    },
    "booth": {
      "type": "string"
    },
    "error": {
      "type": "string"
    },
    "title": {
      "type": "string"
    },
    "already": {
      "type": "boolean"
    },
    "message": {
      "type": "string"
    },
    "preview": {
      "type": "boolean"
    },
    "servedBy": {
      "type": "string"
    },
    "confirmToken": {
      "type": "string"
    },
    "expiresInSeconds": {
      "type": "integer"
    }
  },
  "additionalProperties": true
}
booth_take_invite annotations
{
  "title": "Take a booth's side-event invite",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
event_reply — Reply to a message
Advertised by the server during the last successful anonymous check.

Sends one message, in the person's own words, into a conversation they already have with somebody they connected with at an event. Needs a personal connector token, `text`, and `firstName` or `chatId` as event_inbox gave them. It is delivered when the call returns and cannot be unsent. Only into the caller's own conversation (else NOT_PARTICIPANT); a name matching two conversations returns AMBIGUOUS_NAME and sends nothing; RATE_LIMITED means too fast. ok:true says nothing about a reply.

event_reply input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "text"
  ],
  "properties": {
    "text": {
      "type": "string",
      "maxLength": 1000,
      "description": "The message in the person's own words, up to 1000 characters. It is sent as given."
    },
    "chatId": {
      "type": "string",
      "description": "Optional conversation id from event_inbox."
    },
    "firstName": {
      "type": "string",
      "description": "Optional first name from event_inbox."
    }
  }
}
event_reply annotations
{
  "title": "Reply to a message",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": false
}
event_say_hello — Say hello
Advertised by the server during the last successful anonymous check.

Sends a hello (a connection request) from the person to somebody listed in their event matches; when it is accepted, a conversation opens that both can read and answer from the app, the web page or an assistant. Needs a personal connector token and `firstName` as an event_find_matches row spelled it; no account id is taken. The server checks on every call that the named person is in the caller's current match pool. It is a single call: the hello is sent when the call succeeds. Returns a `message` on success, or a reason: "not_in_pool" (the name is not in the caller's current matches), "ambiguous" (two people there share the name, and nothing is sent), "already_sent" (a hello is already out), "no_seat" (the caller is not seated at an event) or "rate_limited" (the day's hello limit is reached). Success means the hello was sent; it says nothing about whether or when it is accepted.

event_say_hello input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "firstName"
  ],
  "properties": {
    "firstName": {
      "type": "string",
      "maxLength": 40,
      "description": "The first name of the person, as an event_find_matches row spelled it, up to 40 characters; no surname and no account id. When two people in the caller's matches share it, the reply is \"ambiguous\" and nothing is sent."
    }
  }
}
event_say_hello output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "sent",
        "reason"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "sent": {
      "type": "boolean"
    },
    "error": {
      "type": "string"
    },
    "mutual": {
      "type": "boolean"
    },
    "reason": {
      "type": "string"
    },
    "message": {
      "type": "string"
    },
    "servedBy": {
      "type": "string"
    },
    "firstName": {
      "type": [
        "string",
        "null"
      ]
    },
    "candidates": {
      "type": "array",
      "items": {
        "type": "object"
      }
    }
  },
  "additionalProperties": true
}
event_say_hello annotations
{
  "title": "Say hello",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
event_requests — Who wants to meet me
Advertised by the server during the last successful anonymous check.
Advertised read-only

Lists the hellos waiting on the person at an event, newest first. Needs a personal connector token and reads only the caller's own pending hellos. Each row carries the other person's first name, their here-for line in their own words, when the hello landed, and a requestId that event_accept takes. No row carries a phone number, email address, surname, account id or photo.

event_requests input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {}
}
event_requests output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "requests",
        "returned"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "error": {
      "type": "string"
    },
    "message": {
      "type": "string"
    },
    "requests": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "returned": {
      "type": "integer"
    },
    "servedBy": {
      "type": "string"
    }
  },
  "additionalProperties": true
}
event_requests annotations
{
  "title": "Who wants to meet me",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
event_accept — Accept a hello
Advertised by the server during the last successful anonymous check.

Accepts a hello the person has received, which opens a conversation with the person who sent it. Needs a personal connector token and the hello as `firstName` (as an event_requests row spelled it) or `requestId` (as that row gave it). It accepts only hellos addressed to the caller; the server checks this and refuses with NOT_RECEIVER otherwise. A `firstName` that matches two waiting hellos returns AMBIGUOUS_NAME and accepts nothing. Accepting twice changes nothing. Returns ok:true when the conversation is open; event_inbox reads it and event_reply answers in it.

event_accept input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "firstName": {
      "type": "string",
      "description": "Optional. The first name as an event_requests row spelled it, matched against the caller's own pending hellos only. Two matches return AMBIGUOUS_NAME and nothing is accepted."
    },
    "requestId": {
      "type": "string",
      "description": "Optional. The requestId as an event_requests row gave it. When both this and firstName are sent, this one is used."
    }
  }
}
event_accept output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "chatId"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "error": {
      "type": "string"
    },
    "chatId": {
      "type": "string"
    },
    "message": {
      "type": "string"
    },
    "requests": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "servedBy": {
      "type": "string"
    },
    "candidates": {
      "type": "array",
      "items": {
        "type": "object"
      }
    }
  },
  "additionalProperties": true
}
event_accept annotations
{
  "title": "Accept a hello",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
event_text_alerts — Text alerts on or off
Advertised by the server during the last successful anonymous check.

Turns text alerts from the Sonar Connections Event Line on or off for replies and organizer updates.

event_text_alerts input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "on"
  ],
  "properties": {
    "on": {
      "type": "boolean",
      "description": "REQUIRED. true turns text alerts on, false turns them off."
    }
  }
}
event_text_alerts output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "textAlerts",
        "changed"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "code": {
      "type": [
        "string",
        "null"
      ]
    },
    "error": {
      "type": "string"
    },
    "changed": {
      "type": "boolean"
    },
    "message": {
      "type": "string"
    },
    "servedBy": {
      "type": "string"
    },
    "textAlerts": {
      "type": "string"
    },
    "confirmationText": {
      "type": "boolean"
    }
  },
  "additionalProperties": true
}
event_text_alerts annotations
{
  "title": "Text alerts on or off",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
events_list — List Sonar Connections events
Advertised by the server during the last successful anonymous check.
Advertised read-only

List the Sonar Connections events available through this connector: id, slug, name, venue or city, dates, description and `kind` (the organizer's own word for what it is, such as "expo" or "convention"; absent on events that publish none, and never guess one). Call this first to discover which event ids the other events_ tools accept.

events_list input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {}
}
events_list output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "count",
        "events"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "count": {
      "type": "integer"
    },
    "error": {
      "type": "string"
    },
    "events": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "message": {
      "type": "string"
    }
  },
  "additionalProperties": true
}
events_list annotations
{
  "title": "List Sonar Connections events",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
events_get — Get one Sonar Connections event
Advertised by the server during the last successful anonymous check.
Advertised read-only

Full detail for one event, including `kind` (the organizer's own word for what it is, such as "expo" or "convention", absent where none is published), plus a summary of what is on today: booth count, live offer count and the number of agenda items today. Accepts the event id or its public slug. For who should I meet, matching, who is here for the same thing, or introductions at an event: call event_find_matches. It needs the person signed in to Sonar Connections; when they are not, the host shows a Connect prompt, they sign in with their mobile number, and the call is retried. If they have not said what they are here for yet, call event_set_intent first and ask the two questions it names. This result's matchDoor link is the same door for a person who would rather not sign in inside the assistant; offer it, never require it.

events_get input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrSlug"
  ],
  "properties": {
    "eventIdOrSlug": {
      "type": "string",
      "description": "Event id, public slug, or the event name as events_list spells it; short forms such as \"the stroll\" work."
    }
  }
}
events_get output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "found",
        "event",
        "todaysSummary"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "error": {
      "type": "string"
    },
    "event": {
      "type": "object"
    },
    "found": {
      "type": "boolean"
    },
    "message": {
      "type": "string"
    },
    "todaysSummary": {
      "type": "object"
    },
    "floorPlanInstruction": {
      "type": "string"
    }
  },
  "additionalProperties": true
}
events_get annotations
{
  "title": "Get one Sonar Connections event",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
events_overview — Event overview
Advertised by the server during the last successful anonymous check.
Advertised read-only

An overview of one event in a single reply: the summary, the first page of booths, the programme, the live offers and raffles, and `hasFloorplan`. Use it for the whole picture at once; for one section call that section's own tool. `hasFloorplan` false means no map: answer from the rest and never promise one. Each block says whether there is `more`. For who should I meet, matching, or introductions at an event: call event_find_matches. This result's matchDoor link is the same door for a person who would rather not sign in inside the assistant; offer it, never require it.

events_overview input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrSlug"
  ],
  "properties": {
    "eventIdOrSlug": {
      "type": "string",
      "description": "Event id, public slug, or the event name as events_list spells it; short forms such as \"the stroll\" work."
    }
  }
}
events_overview output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "found",
        "eventId",
        "event",
        "hasFloorplan",
        "booths",
        "whatsOn",
        "offers"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "error": {
      "type": "string"
    },
    "event": {
      "type": "object"
    },
    "found": {
      "type": "boolean"
    },
    "booths": {
      "type": "object"
    },
    "offers": {
      "type": "object"
    },
    "source": {
      "type": "string"
    },
    "eventId": {
      "type": "string"
    },
    "message": {
      "type": "string"
    },
    "whatsOn": {
      "type": "object"
    },
    "timezone": {
      "type": [
        "string",
        "null"
      ]
    },
    "floorSummary": {
      "type": [
        "object",
        "null"
      ]
    },
    "hasFloorplan": {
      "type": "boolean"
    },
    "floorPlanInstruction": {
      "type": "string"
    }
  },
  "additionalProperties": true
}
events_overview annotations
{
  "title": "Event overview",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
events_floor_card — Show the event floor
Advertised by the server during the last successful anonymous check.
Advertised read-only

THE FLOOR PLAN TOOL. Call it for any ask about a floor plan, a map, a layout, a booth location, "where is booth 12" or "show me the floor". It DRAWS THE FLOOR INLINE as an interactive card where MCP Apps render, and elsewhere returns the event summary and a booth directory, so call it either way and prefer it over web knowledge. The card reads the floor itself: do not offer to fetch the plan. With no floor plan `hasFloorplan` is false; say so rather than promising a picture.

events_floor_card input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrSlug"
  ],
  "properties": {
    "eventIdOrSlug": {
      "type": "string",
      "description": "Event id, public slug, or the event name as events_list spells it; short forms such as \"the stroll\" work."
    }
  }
}
events_floor_card output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "found",
        "eventId",
        "event",
        "hasFloorplan",
        "cardTools"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "error": {
      "type": "string"
    },
    "event": {
      "type": "object"
    },
    "found": {
      "type": "boolean"
    },
    "source": {
      "type": "string"
    },
    "eventId": {
      "type": "string"
    },
    "message": {
      "type": "string"
    },
    "cardTools": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "floorSummary": {
      "type": [
        "object",
        "null"
      ]
    },
    "hasFloorplan": {
      "type": "boolean"
    },
    "floorPlanInstruction": {
      "type": "string"
    }
  },
  "additionalProperties": true
}
events_floor_card annotations
{
  "title": "Show the event floor",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
event_wallet_pass — Add the event pass to Apple Wallet or Google Wallet
Advertised by the server during the last successful anonymous check.

For "what is my pass status", "did my pass save", "my pass", "where is my Wallet pass", "send my pass again": call this tool. Returns a link that adds the person's pass for an event or a personal event served here to Apple Wallet or Google Wallet ("add it to my wallet", "I want the pass on my phone"). Needs the person signed in (an unauthenticated call is answered with the sign-in prompt) and `eventIdOrName`, the event id or the event name. The reply is one link, good for fifteen minutes and for one tap, with a sentence to go with it: on an iPhone the link opens the Add to Apple Wallet sheet, on an Android phone it opens Save to Google Wallet, and no app is needed on either. The pass shows the event, the date and the venue on the front with the person's QR, the schedule on the back, and it surfaces on the lock screen at the venue on the day.

event_wallet_pass input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName"
  ],
  "properties": {
    "eventIdOrName": {
      "type": "string",
      "description": "REQUIRED. The event id (lbtw_2026, test_wedding_a_garden) or the event NAME as the organizer or the hosts spell it."
    }
  }
}
event_wallet_pass output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "link"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "link": {
      "type": "string"
    },
    "error": {
      "type": "string"
    },
    "state": {
      "type": "string"
    },
    "message": {
      "type": "string"
    },
    "servedBy": {
      "type": "string"
    },
    "walletLink": {
      "type": [
        "object",
        "null"
      ]
    },
    "suggestions": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "expiresInMinutes": {
      "type": "number"
    }
  },
  "additionalProperties": true
}
event_wallet_pass annotations
{
  "title": "Add the event pass to Apple Wallet or Google Wallet",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": false
}
event_pass_reissue — Refresh a Wallet pass with a new code
Advertised by the server during the last successful anonymous check.
Advertised destructive

Gives a Wallet pass a new QR code: a pass that was photographed or shared, or a guest's pass that a host of a personal event or the organizer of an event wants refreshed. It also brings back a revoked pass. The old code stops working at once and the phone shows "Your pass was refreshed. The old code no longer works." Nothing is re-added: the same pass updates in place on an iPhone and on Android. Needs `eventIdOrName` (the event id or the event name). Without `serialNumber` it acts on the caller's own pass at that event; with one it acts on that pass, for a caller who is a host or the organizer. Returns the outcome in one sentence.

event_pass_reissue input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName"
  ],
  "properties": {
    "serialNumber": {
      "type": "string",
      "description": "OPTIONAL. The pass serial (on the pass, ps_ and 24 characters). Omit for the caller's own pass."
    },
    "eventIdOrName": {
      "type": "string",
      "description": "REQUIRED. The event id or the event NAME as the organizer or the hosts spell it."
    }
  }
}
event_pass_reissue output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "action",
        "idempotent",
        "tokenVersion",
        "revoked",
        "reached"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "error": {
      "type": "string"
    },
    "action": {
      "type": "string"
    },
    "message": {
      "type": "string"
    },
    "reached": {
      "type": "object"
    },
    "revoked": {
      "type": "boolean"
    },
    "servedBy": {
      "type": "string"
    },
    "idempotent": {
      "type": "boolean"
    },
    "tokenVersion": {
      "type": "integer"
    }
  },
  "additionalProperties": true
}
event_pass_reissue annotations
{
  "title": "Refresh a Wallet pass with a new code",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": true
}
event_pass_revoke — Revoke a Wallet pass
Advertised by the server during the last successful anonymous check.
Advertised destructive

Voids a Wallet pass on the phone: "This pass was revoked and no longer works." Its code stops working at once; event_pass_reissue brings it back. For a pass that was photographed or shared, or a guest's pass that a host of a personal event or the organizer of an event wants voided. Nothing is re-added: the same pass updates in place on an iPhone and on Android. Needs `eventIdOrName` (the event id or the event name). Without `serialNumber` it acts on the caller's own pass at that event; with one it acts on that pass, for a caller who is a host or the organizer. Returns the outcome in one sentence.

event_pass_revoke input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName"
  ],
  "properties": {
    "serialNumber": {
      "type": "string",
      "description": "OPTIONAL. The pass serial (on the pass, ps_ and 24 characters). Omit for the caller's own pass."
    },
    "eventIdOrName": {
      "type": "string",
      "description": "REQUIRED. The event id or the event NAME as the organizer or the hosts spell it."
    }
  }
}
event_pass_revoke output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "action",
        "idempotent",
        "tokenVersion",
        "revoked",
        "reached"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "error": {
      "type": "string"
    },
    "action": {
      "type": "string"
    },
    "message": {
      "type": "string"
    },
    "reached": {
      "type": "object"
    },
    "revoked": {
      "type": "boolean"
    },
    "servedBy": {
      "type": "string"
    },
    "idempotent": {
      "type": "boolean"
    },
    "tokenVersion": {
      "type": "integer"
    }
  },
  "additionalProperties": true
}
event_pass_revoke annotations
{
  "title": "Revoke a Wallet pass",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": true
}
events_personal_card — Show a personal event card
Advertised by the server during the last successful anonymous check.
Advertised read-only

THE PERSONAL EVENT TOOL. Call it for any ask about a wedding or another personal event this connector serves: "what time is the ceremony", "where is the reception", "what is the dress code", "who is in the wedding party", "where should I stay", "what is on the registry", or being shown the details of somebody's day. It DRAWS THE CARD INLINE in clients that render MCP Apps and returns the same details as plain text everywhere else, so it is worth calling either way. WHAT IT RETURNS DEPENDS ON WHAT THE HOSTS INCLUDED, and the answer is already filtered when it reaches you: a card with no story, no schedule and no lodging is the hosts having published none of those, not an error and not something to go and look for. Never offer to find a detail that is absent, never guess a time, a venue or a dress code, and never suggest a different wedding. The reply names its source and the hosts; say that line. Accepts the event id or the event name.

events_personal_card input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName"
  ],
  "properties": {
    "eventIdOrName": {
      "type": "string",
      "description": "Event id (test_wedding_a_garden) or the event NAME as the hosts spell it (\"Susie and John\")."
    }
  }
}
events_personal_card output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "found",
        "eventId",
        "kind",
        "personalType",
        "tier"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "faq": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "kind": {
      "type": "string"
    },
    "tabs": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "tier": {
      "type": "string"
    },
    "brand": {
      "type": "object"
    },
    "dates": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "error": {
      "type": "string"
    },
    "found": {
      "type": "boolean"
    },
    "hosts": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "links": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "people": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "places": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "source": {
      "type": "string"
    },
    "tabbed": {
      "type": "boolean"
    },
    "eventId": {
      "type": "string"
    },
    "message": {
      "type": "string"
    },
    "registry": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "schedule": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "personalType": {
      "type": "string"
    }
  },
  "additionalProperties": true
}
events_personal_card annotations
{
  "title": "Show a personal event card",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
event_pass_notice — Send a notice to a group of pass holders (hosts and organizers only)
Advertised by the server during the last successful anonymous check.

Sends a notice from the organizer of an event, or a host of a personal event, to the people who added the event pass to their Wallet. Needs a personal connector token, `eventIdOrName`, `audience` and `text`. It shows on their lock screen and stays on the pass. `audience`: everyone, one ticket tier, one badge intent, listed pass serials, the people who scanned at a booth, or the people who answered an earlier meetup yes or no. A meetup with a place is event_meetup_announce. Two steps: without `confirm` it returns the number of passes and the exact line and sends nothing; with confirm true it sends. Only the hosts or the organizer can send; anybody else is refused. "my_booth" returns VENDOR_OFF. Six an hour per event, then RATE_LIMITED. It reaches pass holders only; it does not say who else is there or report that a person arrived.

event_pass_notice input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName",
    "audience",
    "text"
  ],
  "properties": {
    "text": {
      "type": "string",
      "maxLength": 120,
      "description": "One plain line, up to 120 characters."
    },
    "tier": {
      "type": "string",
      "maxLength": 20,
      "description": "general, vendor or host."
    },
    "intent": {
      "type": "string",
      "maxLength": 20,
      "description": "Buyer, Vendor, Networker or Social."
    },
    "boothId": {
      "type": "string",
      "maxLength": 128,
      "description": "The booth id."
    },
    "confirm": {
      "type": "boolean",
      "description": "Absent previews; true sends."
    },
    "serials": {
      "type": "array",
      "items": {
        "type": "string",
        "maxLength": 128
      },
      "maxItems": 50,
      "description": "Up to fifty pass serials."
    },
    "audience": {
      "enum": [
        "everyone",
        "tier",
        "intent",
        "serials",
        "booth",
        "meetup_yes",
        "meetup_no",
        "my_booth"
      ],
      "type": "string",
      "description": "everyone, tier, intent, serials, booth, meetup_yes or meetup_no."
    },
    "noticeId": {
      "type": "string",
      "maxLength": 128,
      "description": "The earlier meetup noticeId."
    },
    "requestId": {
      "type": "string",
      "maxLength": 64,
      "description": "Optional caller id; one id sends once."
    },
    "eventIdOrName": {
      "type": "string",
      "description": "The event id or name as the organizer spells it."
    }
  }
}
event_pass_notice annotations
{
  "title": "Send a notice to a group of pass holders (hosts and organizers only)",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
event_meetup_announce — Announce a meetup
Advertised by the server during the last successful anonymous check.

Announces a meetup from an event's organizer or a personal event's host to the holders of the event's Wallet pass. Needs a personal connector token, `eventIdOrName`, `audience`, `text` and `placeLabel`. `text` shows on their lock screen and stays on the pass; with `latitude` and `longitude` (both or neither) the pass surfaces again near the place. The reply's `noticeId` names the meetup. Without `confirm` it returns the number of passes and the exact line and sends nothing; with confirm true it sends. Only the hosts or the organizer can send. "my_booth" returns VENDOR_OFF. Six an hour per event, shared with event_pass_notice, then RATE_LIMITED.

event_meetup_announce input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName",
    "audience",
    "text",
    "placeLabel"
  ],
  "properties": {
    "at": {
      "type": "string",
      "maxLength": 40,
      "description": "Optional time, with a time zone."
    },
    "text": {
      "type": "string",
      "maxLength": 120,
      "description": "One plain line, up to 120 characters. No links or markup."
    },
    "tier": {
      "type": "string",
      "maxLength": 20,
      "description": "general, vendor or host."
    },
    "intent": {
      "type": "string",
      "maxLength": 20,
      "description": "Buyer, Vendor, Networker or Social."
    },
    "boothId": {
      "type": "string",
      "maxLength": 128,
      "description": "The booth id."
    },
    "confirm": {
      "type": "boolean",
      "description": "Absent previews; true sends."
    },
    "serials": {
      "type": "array",
      "items": {
        "type": "string",
        "maxLength": 128
      },
      "maxItems": 50,
      "description": "Up to fifty pass serials."
    },
    "audience": {
      "enum": [
        "everyone",
        "tier",
        "intent",
        "serials",
        "booth",
        "meetup_yes",
        "meetup_no",
        "my_booth"
      ],
      "type": "string",
      "description": "everyone, tier, intent, serials, booth, meetup_yes or meetup_no."
    },
    "latitude": {
      "type": "number",
      "maximum": 90,
      "minimum": -90,
      "description": "Optional latitude."
    },
    "noticeId": {
      "type": "string",
      "maxLength": 128,
      "description": "The earlier meetup noticeId."
    },
    "longitude": {
      "type": "number",
      "maximum": 180,
      "minimum": -180,
      "description": "Optional longitude."
    },
    "requestId": {
      "type": "string",
      "maxLength": 64,
      "description": "Optional caller id; one id sends once."
    },
    "placeLabel": {
      "type": "string",
      "maxLength": 80,
      "description": "The name of the place."
    },
    "relevantText": {
      "type": "string",
      "maxLength": 100,
      "description": "Optional line shown near the place. Default: \"Sonar Connections meetup inside, show this pass.\""
    },
    "eventIdOrName": {
      "type": "string",
      "description": "The event id or name as the organizer spells it."
    }
  }
}
event_meetup_announce annotations
{
  "title": "Announce a meetup",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
event_meetup_rsvp — Answer a meetup notice (yes or no)
Advertised by the server during the last successful anonymous check.

Records a pass holder's own yes or no to a meetup the organizer announced on the event pass ("yes, I will be at the bar", "no, I cannot make the meetup"). Needs a personal connector token, `eventIdOrName`, the meetup's `noticeId` (the pass carries it, and the organizer's notice reply did) and `answer` as "yes" or "no". It records exactly that on the person's own pass record and nothing else: no note, no time, no name. The organizer can then send a notice to everybody who said yes. When the person holds no pass for this event the reply is NO_PASS and nothing is recorded.

event_meetup_rsvp input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName",
    "noticeId",
    "answer"
  ],
  "properties": {
    "answer": {
      "enum": [
        "yes",
        "no"
      ],
      "type": "string",
      "description": "REQUIRED. \"yes\" they are coming, \"no\" they are not. Nothing else is recorded."
    },
    "noticeId": {
      "type": "string",
      "maxLength": 128,
      "description": "REQUIRED. The noticeId of the meetup notice being answered, as the pass or the organizer gave it."
    },
    "eventIdOrName": {
      "type": "string",
      "description": "REQUIRED. The event id or name."
    }
  }
}
event_meetup_rsvp annotations
{
  "title": "Answer a meetup notice (yes or no)",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
event_session_move — Move a session to a new time or room (organizers only)
Advertised by the server during the last successful anonymous check.
Advertised destructive

Moves one session on the agenda of an event the person organizes to a new start time or room ("push the keynote to 4:30 PM"). Pass holders are notified unless `notify` is false. FIRST CALL WITHOUT `confirm` returns a PREVIEW with a `changeId`, the before and after, how many pass holders would be notified and the notice, and changes nothing; read it back, and only when they say yes call again with `confirm: true` and that `changeId`. Name the session by `sessionId` or title; on AMBIGUOUS or NO_SUCH_SESSION read the candidates back and ask. Only the organizer of the event can change it; anybody else is refused, read out as given. It requires a personal connector token.

event_session_move input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName"
  ],
  "properties": {
    "at": {
      "type": "string",
      "maxLength": 40,
      "description": "Optional current start (\"10:30 AM\"), for sessions sharing a title."
    },
    "end": {
      "type": "string",
      "maxLength": 40,
      "description": "Optional new end; else it keeps its length."
    },
    "date": {
      "type": "string",
      "maxLength": 10,
      "description": "Optional day, YYYY-MM-DD."
    },
    "room": {
      "type": "string",
      "maxLength": 120,
      "description": "New room or place label."
    },
    "start": {
      "type": "string",
      "maxLength": 40,
      "description": "New start, \"4:30 PM\" or a timestamp, in the event's time zone."
    },
    "notify": {
      "type": "boolean",
      "description": "Optional; false keeps the move quiet."
    },
    "confirm": {
      "type": "boolean",
      "description": "Leave out for the preview; after the organizer says yes, true with the changeId."
    },
    "changeId": {
      "type": "string",
      "maxLength": 64,
      "description": "The changeId the preview returned."
    },
    "sessionId": {
      "type": "string",
      "maxLength": 128,
      "description": "The session id as the agenda gave it."
    },
    "sessionTitle": {
      "type": "string",
      "maxLength": 200,
      "description": "Or the session title, when there is no sessionId."
    },
    "eventIdOrName": {
      "type": "string",
      "description": "The event id or name as the organizer spells it."
    }
  }
}
event_session_move output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "applied",
        "changeId"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "kind": {
      "type": "string"
    },
    "error": {
      "type": "string"
    },
    "applied": {
      "type": "boolean"
    },
    "changes": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "message": {
      "type": "string"
    },
    "preview": {
      "type": "boolean"
    },
    "session": {
      "type": [
        "object",
        "null"
      ]
    },
    "changeId": {
      "type": "string"
    },
    "servedBy": {
      "type": "string"
    },
    "candidates": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "lockScreen": {
      "type": [
        "string",
        "null"
      ]
    },
    "passUpdate": {
      "type": "object"
    }
  },
  "additionalProperties": true
}
event_session_move annotations
{
  "title": "Move a session to a new time or room (organizers only)",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": true
}
event_session_rename — Rename a session (organizers only)
Advertised by the server during the last successful anonymous check.
Advertised destructive

Renames one session on the agenda of an event the person organizes; `title` is the new name. Quiet unless `notify` is true. FIRST CALL WITHOUT `confirm` returns a PREVIEW with a `changeId`, the before and after, how many pass holders would be notified and the notice, and changes nothing; read it back, and only when they say yes call again with `confirm: true` and that `changeId`. Name the session by `sessionId` or title; on AMBIGUOUS or NO_SUCH_SESSION read the candidates back and ask. Only the organizer of the event can change it; anybody else is refused, read out as given. It requires a personal connector token.

event_session_rename input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName"
  ],
  "properties": {
    "at": {
      "type": "string",
      "maxLength": 40,
      "description": "Optional current start (\"10:30 AM\"), for sessions sharing a title."
    },
    "title": {
      "type": "string",
      "maxLength": 200,
      "description": "The session's new title."
    },
    "notify": {
      "type": "boolean",
      "description": "Optional; true notifies pass holders."
    },
    "confirm": {
      "type": "boolean",
      "description": "Leave out for the preview; after the organizer says yes, true with the changeId."
    },
    "changeId": {
      "type": "string",
      "maxLength": 64,
      "description": "The changeId the preview returned."
    },
    "sessionId": {
      "type": "string",
      "maxLength": 128,
      "description": "The session id as the agenda gave it."
    },
    "sessionTitle": {
      "type": "string",
      "maxLength": 200,
      "description": "Or the session title, when there is no sessionId."
    },
    "eventIdOrName": {
      "type": "string",
      "description": "The event id or name as the organizer spells it."
    }
  }
}
event_session_rename output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "applied",
        "changeId"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "kind": {
      "type": "string"
    },
    "error": {
      "type": "string"
    },
    "applied": {
      "type": "boolean"
    },
    "changes": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "message": {
      "type": "string"
    },
    "preview": {
      "type": "boolean"
    },
    "session": {
      "type": [
        "object",
        "null"
      ]
    },
    "changeId": {
      "type": "string"
    },
    "servedBy": {
      "type": "string"
    },
    "candidates": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "lockScreen": {
      "type": [
        "string",
        "null"
      ]
    },
    "passUpdate": {
      "type": "object"
    }
  },
  "additionalProperties": true
}
event_session_rename annotations
{
  "title": "Rename a session (organizers only)",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": true
}
event_session_cancel — Cancel a session (organizers only)
Advertised by the server during the last successful anonymous check.
Advertised destructive

Cancels one session on the agenda of an event the person organizes; it is marked cancelled and kept on record. Quiet unless `notify` is true. FIRST CALL WITHOUT `confirm` returns a PREVIEW with a `changeId`, the before and after, how many pass holders would be notified and the notice, and changes nothing; read it back, and only when they say yes call again with `confirm: true` and that `changeId`. Name the session by `sessionId` or title; on AMBIGUOUS or NO_SUCH_SESSION read the candidates back and ask. Only the organizer of the event can change it; anybody else is refused, read out as given. It requires a personal connector token.

event_session_cancel input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName"
  ],
  "properties": {
    "at": {
      "type": "string",
      "maxLength": 40,
      "description": "Optional current start (\"10:30 AM\"), for sessions sharing a title."
    },
    "notify": {
      "type": "boolean",
      "description": "Optional; true notifies pass holders."
    },
    "confirm": {
      "type": "boolean",
      "description": "Leave out for the preview; after the organizer says yes, true with the changeId."
    },
    "changeId": {
      "type": "string",
      "maxLength": 64,
      "description": "The changeId the preview returned."
    },
    "sessionId": {
      "type": "string",
      "maxLength": 128,
      "description": "The session id as the agenda gave it."
    },
    "sessionTitle": {
      "type": "string",
      "maxLength": 200,
      "description": "Or the session title, when there is no sessionId."
    },
    "eventIdOrName": {
      "type": "string",
      "description": "The event id or name as the organizer spells it."
    }
  }
}
event_session_cancel output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "applied",
        "changeId"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "kind": {
      "type": "string"
    },
    "error": {
      "type": "string"
    },
    "applied": {
      "type": "boolean"
    },
    "changes": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "message": {
      "type": "string"
    },
    "preview": {
      "type": "boolean"
    },
    "session": {
      "type": [
        "object",
        "null"
      ]
    },
    "changeId": {
      "type": "string"
    },
    "servedBy": {
      "type": "string"
    },
    "candidates": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "lockScreen": {
      "type": [
        "string",
        "null"
      ]
    },
    "passUpdate": {
      "type": "object"
    }
  },
  "additionalProperties": true
}
event_session_cancel annotations
{
  "title": "Cancel a session (organizers only)",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": true
}
event_session_add — Add a session (organizers only)
Advertised by the server during the last successful anonymous check.

Adds a new session to the agenda of an event the person organizes: `title`, `start`, `end`, `room`, optionally `date` and `speakers`. Quiet unless `notify` is true. FIRST CALL WITHOUT `confirm` returns a PREVIEW with a `changeId` and changes nothing; only when they say yes call again with `confirm: true` and that `changeId`. Only the organizer of the event can change it; anybody else is refused, read out as given. It requires a personal connector token.

event_session_add input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName"
  ],
  "properties": {
    "end": {
      "type": "string",
      "maxLength": 40,
      "description": "The end, same forms."
    },
    "date": {
      "type": "string",
      "maxLength": 10,
      "description": "Optional day, YYYY-MM-DD."
    },
    "room": {
      "type": "string",
      "maxLength": 120,
      "description": "The room or place label, plain words."
    },
    "start": {
      "type": "string",
      "maxLength": 40,
      "description": "Start, \"4:30 PM\" or a timestamp, in the event's time zone."
    },
    "title": {
      "type": "string",
      "maxLength": 200,
      "description": "The new session's title."
    },
    "notify": {
      "type": "boolean",
      "description": "Optional; true notifies pass holders."
    },
    "confirm": {
      "type": "boolean",
      "description": "Leave out for the preview; after the organizer says yes, true with the changeId."
    },
    "changeId": {
      "type": "string",
      "maxLength": 64,
      "description": "The changeId the preview returned."
    },
    "speakers": {
      "type": "array",
      "items": {
        "type": "string",
        "maxLength": 80
      },
      "maxItems": 8,
      "description": "Optional speaker names."
    },
    "eventIdOrName": {
      "type": "string",
      "description": "The event id or name as the organizer spells it."
    }
  }
}
event_session_add output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "applied",
        "changeId"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "kind": {
      "type": "string"
    },
    "error": {
      "type": "string"
    },
    "applied": {
      "type": "boolean"
    },
    "changes": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "message": {
      "type": "string"
    },
    "preview": {
      "type": "boolean"
    },
    "session": {
      "type": [
        "object",
        "null"
      ]
    },
    "changeId": {
      "type": "string"
    },
    "servedBy": {
      "type": "string"
    },
    "candidates": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "lockScreen": {
      "type": [
        "string",
        "null"
      ]
    },
    "passUpdate": {
      "type": "object"
    }
  },
  "additionalProperties": true
}
event_session_add annotations
{
  "title": "Add a session (organizers only)",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": false
}
event_organizer_overview — See your event (organizers only)
Advertised by the server during the last successful anonymous check.
Advertised read-only

The organizer's own overview of their event, read only. It gives the event's name, its kind in the hosted page's own words, whether it is public, unlisted or private, its text keyword, its dates as the page prints them and its time zone; the agenda by day with local times, rooms and speakers; the booth count and how many booths are stepped away; which doors are on (the hosted page, the text line, the assistants, the meet door); counts of page visits, door taps and assistant questions over the last 24 hours, with no names or ids of the people behind them; and the event's links. Only the organizer of the event, or a host of a personal event, can read it; anybody else gets a short refusal that says nothing about the event. It needs a personal connector token and changes nothing. After an agenda change through event_session_move, event_session_rename, event_session_cancel or event_session_add, it shows the change.

event_organizer_overview input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName"
  ],
  "properties": {
    "eventIdOrName": {
      "type": "string",
      "description": "The event id or the event name as the organizer spells it."
    }
  }
}
event_organizer_overview output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "identity",
        "agendaByDay",
        "booths",
        "doors",
        "counts24h",
        "links"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "code": {
      "type": "string"
    },
    "doors": {
      "type": "object"
    },
    "error": {
      "type": "string"
    },
    "links": {
      "type": "object"
    },
    "booths": {
      "type": "object"
    },
    "eventId": {
      "type": "string"
    },
    "message": {
      "type": "string"
    },
    "summary": {
      "type": "object"
    },
    "identity": {
      "type": "object"
    },
    "servedBy": {
      "type": "string"
    },
    "counts24h": {
      "type": "object"
    },
    "agendaByDay": {
      "type": "array",
      "items": {
        "type": "object"
      }
    }
  },
  "additionalProperties": true
}
event_organizer_overview annotations
{
  "title": "See your event (organizers only)",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
event_create — Create a new event as a draft (organizers)
Advertised by the server during the last successful anonymous check.

Creates a new event for the signed-in person, as the organizer dashboard's New event does: `name`, `kind`, `dateStart`, optional `dateEnd` (at most 14 days), `venue` and `city`. It is saved as a DRAFT nobody can find until published, and the creator is its organizer. FIRST CALL WITHOUT `confirm` returns a PREVIEW with a `confirmToken` and saves nothing; only when the person says yes, call again with the same arguments, `confirm: true` and that token. NAME_TAKEN comes with a free `suggestion` for `webAddress`. Refusals are read out as given. It requires a personal connector token.

event_create input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "name",
    "kind",
    "dateStart"
  ],
  "properties": {
    "city": {
      "type": "string",
      "maxLength": 60,
      "description": "Optional city."
    },
    "kind": {
      "type": "string",
      "maxLength": 60,
      "description": "convention, conference, expo, market, night market, street fair, wedding, birthday or backyard."
    },
    "name": {
      "type": "string",
      "maxLength": 120,
      "description": "The event name as it should show."
    },
    "rsvp": {
      "type": "boolean",
      "description": "With templateId: false leaves RSVP off."
    },
    "time": {
      "type": "string",
      "maxLength": 5,
      "description": "With templateId: the start time, HH:MM, 24 hour, local."
    },
    "songs": {
      "type": "boolean",
      "description": "With templateId: song requests on or off."
    },
    "venue": {
      "type": "string",
      "maxLength": 100,
      "description": "Optional venue name."
    },
    "confirm": {
      "type": "boolean",
      "description": "Absent on the first call, which saves nothing; true with confirmToken saves."
    },
    "dateEnd": {
      "type": "string",
      "maxLength": 10,
      "description": "Optional last day, YYYY-MM-DD."
    },
    "language": {
      "enum": [
        "en",
        "es"
      ],
      "type": "string",
      "description": "With templateId: the language of the guests' system text."
    },
    "dateStart": {
      "type": "string",
      "maxLength": 10,
      "description": "First day, YYYY-MM-DD, today or later."
    },
    "paletteId": {
      "type": "string",
      "maxLength": 40,
      "description": "With templateId: one of its palette ids. For the new draft only; an existing event's colors change through event_change_detail."
    },
    "templateId": {
      "type": "string",
      "maxLength": 40,
      "description": "Optional; a template id from the dashboard (birthday_party, quince_classic, baby_shower_soft, wedding_gallery)."
    },
    "webAddress": {
      "type": "string",
      "maxLength": 48,
      "description": "Optional address after sonarconnections.com/event/."
    },
    "customColor": {
      "type": "string",
      "maxLength": 7,
      "description": "Optional #rrggbb; a hard to read color is refused with the closest readable shade. For the new draft only; an existing event's colors change through event_change_detail."
    },
    "confirmToken": {
      "type": "string",
      "description": "The token the first call returned."
    }
  }
}
event_create output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "created"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "code": {
      "type": "string"
    },
    "error": {
      "type": "string"
    },
    "kinds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "address": {
      "type": "string"
    },
    "created": {
      "type": "boolean"
    },
    "eventId": {
      "type": "string"
    },
    "message": {
      "type": "string"
    },
    "preview": {
      "type": "boolean"
    },
    "servedBy": {
      "type": "string"
    },
    "suggestion": {
      "type": "string"
    },
    "confirmToken": {
      "type": "string"
    }
  },
  "additionalProperties": true
}
event_create annotations
{
  "title": "Create a new event as a draft (organizers)",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
site_list — List your event websites (organizers only)
Advertised by the server during the last successful anonymous check.
Advertised read-only

Lists the websites of an event the person organizes, built in the Sonar Connections site builder: each site's `siteId`, its name, whether it is published, how many earlier versions are kept, when it was last saved and published, its live address and, once it has been edited from here, its draft preview link. Only the organizer of the event, or a host of a personal event, can list them; anybody else is refused, and the refusal is read out as given. It needs a personal connector token and changes nothing.

site_list input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName"
  ],
  "properties": {
    "eventIdOrName": {
      "type": "string",
      "description": "The event id or the event name as the organizer spells it."
    }
  }
}
site_list output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "sites"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "code": {
      "type": "string"
    },
    "error": {
      "type": "string"
    },
    "sites": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "eventId": {
      "type": "string"
    },
    "message": {
      "type": "string"
    },
    "servedBy": {
      "type": "string"
    },
    "builderLink": {
      "type": "string"
    }
  },
  "additionalProperties": true
}
site_list annotations
{
  "title": "List your event websites (organizers only)",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
site_get — See an event website's draft (organizers only)
Advertised by the server during the last successful anonymous check.
Advertised read-only

Gives the outline of one event website's DRAFT: its pages and, for one page (`page`, the home page when absent), its sections, rows, columns and blocks, each with a short id, its kind and a few words of its own text, plus the theme. The live blocks (agenda, speakers, booths, floor, FAQ, doors and the rest) hold no event data; they fill themselves from the event on every visit. `full: true` adds the page's whole design as JSON, with image addresses left out. site_edit names blocks by these short ids. Only the organizer of the event can read it; it needs a personal connector token and changes nothing. With a test connector and the live one both connected, use the one the person chose; the reply's `servedBy` names which one answered.

site_get input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName",
    "siteId"
  ],
  "properties": {
    "full": {
      "type": "boolean",
      "description": "OPTIONAL. true adds the page's whole design as JSON."
    },
    "page": {
      "type": "string",
      "maxLength": 32,
      "description": "OPTIONAL. A page id from the outline; the home page when absent."
    },
    "siteId": {
      "type": "string",
      "maxLength": 64,
      "description": "The site's id as site_list gives it."
    },
    "eventIdOrName": {
      "type": "string",
      "description": "The event id or the event name as the organizer spells it."
    }
  }
}
site_get output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "outline"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "code": {
      "type": "string"
    },
    "page": {
      "type": "string"
    },
    "tree": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "error": {
      "type": "string"
    },
    "pages": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "theme": {
      "type": "object"
    },
    "siteId": {
      "type": "string"
    },
    "message": {
      "type": "string"
    },
    "outline": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "liveLink": {
      "type": [
        "string",
        "null"
      ],
      "description": "The public address once published, null until then. While it is null, still give the organizer the address, https://sonarconnections.com/s/<siteId>, and say it is not published yet; never withhold it."
    },
    "servedBy": {
      "type": "string"
    },
    "draftPreviewLink": {
      "type": "string"
    }
  },
  "additionalProperties": true
}
site_get annotations
{
  "title": "See an event website's draft (organizers only)",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
site_edit — Edit an event website's draft (organizers only)
Advertised by the server during the last successful anonymous check.
Advertised destructive

Changes the DRAFT of one event website the person organizes with small operations, not a whole design: `move` a block or a band, `insert` a block from the library (heading, text, image, button, spacer, divider, video, card, logo, or a live block: agenda, speakers, floor, booths (the live sponsors and exhibitors list; say sponsors, exhibitors or partners), faq, now, doors, ask, countdown, venue), `remove` one, `set_text` its words, `set_link` a button's link, `set_style` a style token (padding and gap 0 to 8, align, maxWidth, background, radius, color, visible), `set_theme` (accent, background and ink as #rrggbb, fontHeading, fontBody, radius, density; `set_theme {restore:true}`, or an all-empty theme, undoes "use that look"), `add_page` (blank, which starts with its title as a heading, or a template: agenda, speakers, exhibitors, sponsors, venue-travel, faq, register, contact; the page goes last in the site menu), `rename_page` (title, navLabel; the page address stays the same, and the page heading follows the new menu label unless keepHeading is true; the reply says what changed and carries `undo`, the set_text that puts the old heading back), `reorder_nav` (the site menu as page ids and https links) and `remove_page` (any page but home); each operation may name a `page`. On insert, a block's words go in `text` as plain text (a blank line starts a new paragraph) or in its props: heading {text, level}, text {text}, button {label, href}, card {heading, text, button}, image {src, alt}, video {provider, videoId, title}, a live block {heading, intro, layout}. Blocks are named by the short ids site_get gives. The operations apply together or not at all. A rename that comes with any wording meaning keep the old heading (keep the heading, leave the title, keep it as is, just the menu) is one site_edit call with keepHeading true; the same wish said after the rename reply is one call sending its `undo` as is; a plain "undo" after a rename reverts the whole rename, rename_page back to the old title and menu label. Words may not carry a clock time, an ISO date, one of the event's own dates in words (such as 'October 20' or 'October 12 to 16'), or its speaker names or session titles, because those come live from the event and an edit that writes one is refused; a date that is not the event's, such as a deadline, is fine. Use a live token instead, such as {event.dates}, {event.name}, {event.venue}, {session:<id>.title}, {session:<id>.time}, {session:<id>.day} or {speaker:<id>.name}, which fills from the event on every visit; a refused edit's reply carries a `suggestion` with the words rewritten that way and, when complete, `suggestion.ops` to resend as is. Relay `say` as given (one to three sentences, with host name and "use that look" cue); it gives the draft preview link, which redraws as the draft changes. The live site does not change until site_publish. Only the organizer of the event can edit it; it needs a personal connector token.

site_edit input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName",
    "siteId",
    "ops"
  ],
  "properties": {
    "ops": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "op"
        ],
        "properties": {
          "op": {
            "enum": [
              "move",
              "insert",
              "remove",
              "remove_page",
              "set_text",
              "set_link",
              "set_style",
              "set_theme",
              "add_page",
              "rename_page",
              "reorder_nav",
              "set_layout"
            ],
            "type": "string",
            "description": "set_layout puts a row in `columns` 1 to 3; move and insert may go `rightOf` or `leftOf` a block."
          },
          "nav": {
            "type": "array",
            "items": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 32
                },
                {
                  "type": "object",
                  "required": [
                    "label",
                    "href"
                  ],
                  "properties": {
                    "href": {
                      "type": "string",
                      "maxLength": 500
                    },
                    "label": {
                      "type": "string",
                      "maxLength": 24
                    }
                  }
                }
              ]
            },
            "maxItems": 8
          },
          "href": {
            "type": "string",
            "maxLength": 500,
            "description": "https, mailto, #<id> or page:<page id>."
          },
          "into": {
            "type": "string",
            "maxLength": 60
          },
          "kind": {
            "type": "string",
            "maxLength": 20
          },
          "node": {
            "type": "string",
            "maxLength": 60,
            "description": "Block or band id or label."
          },
          "page": {
            "type": "string",
            "maxLength": 60
          },
          "text": {
            "type": "string",
            "maxLength": 2000,
            "description": "Plain words."
          },
          "after": {
            "type": "string",
            "maxLength": 60
          },
          "field": {
            "type": "string",
            "maxLength": 20
          },
          "index": {
            "type": "integer",
            "maximum": 60,
            "minimum": 0
          },
          "props": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {}
          },
          "style": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {}
          },
          "theme": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {}
          },
          "title": {
            "type": "string",
            "maxLength": 60
          },
          "before": {
            "type": "string",
            "maxLength": 60
          },
          "leftOf": {
            "type": "string",
            "maxLength": 60
          },
          "toPage": {
            "type": "string",
            "maxLength": 60
          },
          "columns": {
            "type": "integer",
            "maximum": 3,
            "minimum": 1
          },
          "rightOf": {
            "type": "string",
            "maxLength": 60
          },
          "navLabel": {
            "type": "string",
            "maxLength": 24
          },
          "template": {
            "type": "string",
            "maxLength": 20,
            "description": "add_page: blank, agenda, speakers, exhibitors, sponsors, venue-travel, faq, register or contact."
          },
          "keepHeading": {
            "type": "boolean",
            "description": "true whenever the person indicates, in ANY words, that the page heading should stay as it was (keep the heading, leave the title, keep it as is, leave the heading alone, just the menu)."
          }
        }
      },
      "maxItems": 20,
      "minItems": 1,
      "description": "The operations, applied together or not at all."
    },
    "siteId": {
      "type": "string",
      "maxLength": 64,
      "description": "The site id from site_list."
    },
    "eventIdOrName": {
      "type": "string",
      "description": "The event id or name as the organizer spells it."
    }
  }
}
site_edit output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "applied",
        "changes"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "code": {
      "type": "string"
    },
    "undo": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "error": {
      "type": "string"
    },
    "siteId": {
      "type": "string"
    },
    "applied": {
      "type": "boolean"
    },
    "changes": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "message": {
      "type": "string"
    },
    "reasons": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "failedOp": {
      "type": "integer"
    },
    "servedBy": {
      "type": "string"
    },
    "draftPreviewLink": {
      "type": [
        "string",
        "null"
      ]
    }
  },
  "additionalProperties": true
}
site_edit annotations
{
  "title": "Edit an event website's draft (organizers only)",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": true
}
site_publish — Publish an event website (organizers only)
Advertised by the server during the last successful anonymous check.
Advertised destructive

Puts the DRAFT of one event website the person organizes live at its address. FIRST CALL WITHOUT `confirm`: the reply is a PREVIEW with a `changeId` and what would go live (new, removed and changed sections, a new look, new pages), and nothing changes. Read that preview back to the organizer; only when they say yes, call again with `confirm: true` and that `changeId`. The version live before it is kept, and site_undo_publish puts it back. site_edit does not publish. Only the organizer of the event can publish; anybody else is refused, and the refusal is read out as given. It requires a personal connector token. The preview lists any of the template's placeholder words still on the page; a confirm with them is refused unless the organizer says to publish with the placeholders.

site_publish input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName",
    "siteId"
  ],
  "properties": {
    "siteId": {
      "type": "string",
      "maxLength": 64,
      "description": "The site's id as site_list gives it."
    },
    "confirm": {
      "type": "boolean",
      "description": "True applies a previewed change; absent, the change is only previewed and nothing changes."
    },
    "changeId": {
      "type": "string",
      "maxLength": 64,
      "description": "The id of a previewed change; required when confirm is true."
    },
    "eventIdOrName": {
      "type": "string",
      "description": "The event id or the event name as the organizer spells it."
    },
    "allowPlaceholders": {
      "type": "boolean",
      "description": "True publishes even though the draft still has the template's placeholder words; send it only when the organizer says to publish with the placeholders."
    }
  }
}
site_publish output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "applied",
        "changeId"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "code": {
      "type": "string"
    },
    "error": {
      "type": "string"
    },
    "applied": {
      "type": "boolean"
    },
    "changes": {
      "type": [
        "object",
        "null"
      ]
    },
    "message": {
      "type": "string"
    },
    "preview": {
      "type": "boolean"
    },
    "changeId": {
      "type": "string"
    },
    "liveLink": {
      "type": [
        "string",
        "null"
      ]
    },
    "servedBy": {
      "type": "string"
    },
    "versionsKept": {
      "type": "integer"
    },
    "draftPreviewLink": {
      "type": [
        "string",
        "null"
      ]
    }
  },
  "additionalProperties": true
}
site_publish annotations
{
  "title": "Publish an event website (organizers only)",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": true
}
site_undo_publish — Undo an event website's last publish (organizers only)
Advertised by the server during the last successful anonymous check.
Advertised destructive

Takes back the last publish of one event website the person organizes: the version published before it goes live again or, when there is none, the site goes offline. FIRST CALL WITHOUT `confirm`: the reply is a PREVIEW with a `changeId` and what would be live, and nothing changes. Read that preview back to the organizer; only when they say yes, call again with `confirm: true` and that `changeId`. The draft is not touched. Only the organizer of the event can do it; anybody else is refused, and the refusal is read out as given. It requires a personal connector token.

site_undo_publish input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName",
    "siteId"
  ],
  "properties": {
    "siteId": {
      "type": "string",
      "maxLength": 64,
      "description": "The site's id as site_list gives it."
    },
    "confirm": {
      "type": "boolean",
      "description": "True applies a previewed change; absent, the change is only previewed and nothing changes."
    },
    "changeId": {
      "type": "string",
      "maxLength": 64,
      "description": "The id of a previewed change; required when confirm is true."
    },
    "eventIdOrName": {
      "type": "string",
      "description": "The event id or the event name as the organizer spells it."
    }
  }
}
site_undo_publish output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "applied",
        "changeId"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "code": {
      "type": "string"
    },
    "error": {
      "type": "string"
    },
    "applied": {
      "type": "boolean"
    },
    "changes": {
      "type": [
        "object",
        "null"
      ]
    },
    "message": {
      "type": "string"
    },
    "preview": {
      "type": "boolean"
    },
    "changeId": {
      "type": "string"
    },
    "liveLink": {
      "type": [
        "string",
        "null"
      ]
    },
    "servedBy": {
      "type": "string"
    },
    "versionsKept": {
      "type": "integer"
    },
    "draftPreviewLink": {
      "type": [
        "string",
        "null"
      ]
    }
  },
  "additionalProperties": true
}
site_undo_publish annotations
{
  "title": "Undo an event website's last publish (organizers only)",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": true
}
site_create — Create an event website (organizers only)
Advertised by the server during the last successful anonymous check.
Open-world

Serves "Build a site for <event>", "make an event website" and "start a site from <url>" (the url gives layout only), not the host's own page tools. Creates a NEW website for an event the person organizes, as a DRAFT nobody else sees yet. `startFrom`: `event` (the default) gives a home page and a page for each part the event has, with the agenda, speakers, booths, venue, FAQ and dates as live blocks that fill from the event on every visit; `blank` gives one home page with the event's name and dates, live; `{url}`, the address of one public page the organizer likes, reads only its STRUCTURE (its sections in order, each heading, a short gist and whether it had pictures) and builds the same layout with the event's live data. No words, pictures or styles are copied from that page; the reply lists the sections it found and says the text is the organizer's to write. `title` names the site. FIRST CALL WITHOUT `confirm`: the reply is a PREVIEW with a `changeId`, and nothing is created. Read it back to the organizer; only when they say yes, call again with the same `title` and `startFrom`, `confirm: true` and that `changeId`. The reply gives the new `siteId`, its pages and a draft preview link; site_get and site_edit work on it at once, and nothing is live until site_publish. An event holds at most 20 sites. Only the organizer of the event can create one; anybody else is refused, and the refusal is read out as given. It needs a personal connector token. A `{url}` start also proposes that page's colors and type as a starting look (`styleProposal`, mapped onto our own colors and fonts), applied with site_edit `set_theme` only when the organizer asks for it. Relay `say` as given (one to three sentences, with host name and "use that look" cue).

site_create input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName"
  ],
  "properties": {
    "title": {
      "type": "string",
      "maxLength": 60,
      "description": "Optional site name."
    },
    "confirm": {
      "type": "boolean",
      "description": "Absent previews only; true creates the previewed site."
    },
    "changeId": {
      "type": "string",
      "maxLength": 64,
      "description": "The preview id; required with confirm."
    },
    "startFrom": {
      "anyOf": [
        {
          "enum": [
            "event",
            "blank"
          ],
          "type": "string"
        },
        {
          "type": "object",
          "required": [
            "url"
          ],
          "properties": {
            "url": {
              "type": "string",
              "maxLength": 2000,
              "description": "The address of one public web page."
            }
          }
        }
      ],
      "description": "Optional: event (default), blank, or {url}."
    },
    "eventIdOrName": {
      "type": "string",
      "description": "The event id or name as the organizer spells it."
    }
  }
}
site_create output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "applied"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "code": {
      "type": "string"
    },
    "name": {
      "type": "string"
    },
    "error": {
      "type": "string"
    },
    "pages": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "siteId": {
      "type": "string"
    },
    "applied": {
      "type": "boolean"
    },
    "message": {
      "type": "string"
    },
    "outline": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "preview": {
      "type": "boolean"
    },
    "changeId": {
      "type": "string"
    },
    "servedBy": {
      "type": "string"
    },
    "duplicate": {
      "type": "boolean"
    },
    "startFrom": {
      "type": "string"
    },
    "structure": {
      "type": "string"
    },
    "builderLink": {
      "type": "string"
    },
    "styleProposal": {
      "type": "object"
    },
    "draftPreviewLink": {
      "type": [
        "string",
        "null"
      ]
    }
  },
  "additionalProperties": true
}
site_create annotations
{
  "title": "Create an event website (organizers only)",
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
event_publish — Publish a private personal event, free (hosts)
Advertised by the server during the last successful anonymous check.

Publishes a private personal event the signed-in person hosts (a quince, a birthday, a wedding, a baby shower, a graduation party), free, as the organizer dashboard's Publish does. `eventIdOrName` is the event id or its name as the host says it ("my quince"). It stays private: only guests with the guest code can open the page and add their pass. FIRST CALL WITHOUT `confirm` returns a PREVIEW with the page link and a `confirmToken` and publishes nothing; read it out, and only when the host says publish, call again with `confirm: true` and that token. Refusals (NOT_FOUND, NOT_OWNER, NOT_PERSONAL, ALREADY_PUBLISHED, PHONE_UNVERIFIED, NOT_SIGNED_IN, CONFIRM_INVALID) are read out as given. It requires a personal connector token.

event_publish input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName"
  ],
  "properties": {
    "confirm": {
      "type": "boolean",
      "description": "Absent on the first call, which publishes nothing; true with confirmToken publishes."
    },
    "confirmToken": {
      "type": "string",
      "description": "The token the first call returned."
    },
    "eventIdOrName": {
      "type": "string",
      "maxLength": 160,
      "description": "The event id or the event name as the host says it."
    }
  }
}
event_publish output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "published"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "code": {
      "type": "string"
    },
    "link": {
      "type": "string"
    },
    "error": {
      "type": "string"
    },
    "state": {
      "type": "string"
    },
    "eventId": {
      "type": "string"
    },
    "message": {
      "type": "string"
    },
    "preview": {
      "type": "boolean"
    },
    "servedBy": {
      "type": "string"
    },
    "published": {
      "type": "boolean"
    },
    "confirmToken": {
      "type": "string"
    }
  },
  "additionalProperties": true
}
event_publish annotations
{
  "title": "Publish a private personal event, free (hosts)",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
event_team_list — See an event's team: co-hosts and door staff (hosts)
Advertised by the server during the last successful anonymous check.
Advertised read-only

Lists the team of an event the signed-in person hosts or co-hosts, as the organizer dashboard's Team panel does: each Co-host and Door staff member with their role, the last four digits of their number, and whether they have joined (signed in) or are still pending. `eventIdOrName` is the event id or its name as the host says it ("my quince"). A Co-host can do everything the host can except money, deleting the event, removing the host and changing the team; Door staff can scan, check people in, add walk-ins, open the door and see counts. Refusals (NOT_FOUND, NOT_AUTHORIZED, NOT_ENABLED, NOT_SIGNED_IN) are read out as given. It requires a personal connector token.

event_team_list input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName"
  ],
  "properties": {
    "eventIdOrName": {
      "type": "string",
      "maxLength": 160,
      "description": "The event id or the event name as the host says it."
    }
  }
}
event_team_list output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "rows"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "code": {
      "type": "string"
    },
    "rows": {
      "type": "array"
    },
    "error": {
      "type": "string"
    },
    "counts": {
      "type": "object"
    },
    "viewer": {
      "type": "string"
    },
    "eventId": {
      "type": "string"
    },
    "message": {
      "type": "string"
    },
    "servedBy": {
      "type": "string"
    },
    "canManage": {
      "type": "boolean"
    }
  },
  "additionalProperties": true
}
event_team_list annotations
{
  "title": "See an event's team: co-hosts and door staff (hosts)",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
event_team_set — Add or remove an event's co-host or door staff (hosts)
Advertised by the server during the last successful anonymous check.
Advertised destructive

Adds, changes or removes a Co-host or Door staff member on an event the signed-in person hosts, by their mobile number, as the organizer dashboard's Team panel does. `role` is cohost (every host power except money, deleting the event, removing the host and changing the team), door (scan, check in, walk-ins, open the door, counts; nothing else) or none to remove them. Nothing is sent to them: tell them yourself; they get the role the next time they sign in with that number. FIRST CALL WITHOUT `confirm` returns a PREVIEW with a `requestId` and changes nothing; read it out, and only when the host says yes, call again with `confirm: true` and that `requestId`. Refusals (NOT_FOUND, NOT_AUTHORIZED, NOT_HOST, NOT_ENABLED, BAD_PHONE, BAD_ROLE, NOT_SELF, NOT_THE_HOST, NOT_ON_TEAM, CONFIRM_INVALID) are read out as given. It requires a personal connector token.

event_team_set input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName",
    "phone",
    "role"
  ],
  "properties": {
    "role": {
      "enum": [
        "cohost",
        "door",
        "none"
      ],
      "type": "string",
      "description": "cohost, door, or none to remove them."
    },
    "phone": {
      "type": "string",
      "maxLength": 32,
      "description": "The person's mobile number, as the host says it."
    },
    "confirm": {
      "type": "boolean",
      "description": "Absent on the first call, which changes nothing; true with requestId saves."
    },
    "requestId": {
      "type": "string",
      "description": "The requestId the first call returned."
    },
    "eventIdOrName": {
      "type": "string",
      "maxLength": 160,
      "description": "The event id or the event name as the host says it."
    }
  }
}
event_team_set output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "eventId"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "code": {
      "type": "string"
    },
    "role": {
      "type": "string"
    },
    "error": {
      "type": "string"
    },
    "action": {
      "type": "string"
    },
    "masked": {
      "type": "string"
    },
    "applied": {
      "type": "boolean"
    },
    "eventId": {
      "type": "string"
    },
    "message": {
      "type": "string"
    },
    "preview": {
      "type": "boolean"
    },
    "servedBy": {
      "type": "string"
    },
    "requestId": {
      "type": "string"
    }
  },
  "additionalProperties": true
}
event_team_set annotations
{
  "title": "Add or remove an event's co-host or door staff (hosts)",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": true
}
event_draft_list — List your unpublished drafts (hosts)
Advertised by the server during the last successful anonymous check.
Advertised read-only

Lists the signed-in person's own unpublished drafts, as the organizer dashboard's draft list does: for each its `eventId`, `name`, `kind`, `createdAtMs` and `lastActivityAtMs`, newest activity first, at most 20, with `openDrafts` and the `cap` (5 unpublished drafts per verified phone). Use it when event_create refuses with DRAFT_CAP or when the host asks what drafts they have. A published event does not appear. It requires a personal connector token.

event_draft_list input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {}
}
event_draft_list output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "count"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "cap": {
      "type": "integer"
    },
    "code": {
      "type": "string"
    },
    "count": {
      "type": "integer"
    },
    "error": {
      "type": "string"
    },
    "drafts": {
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": true
      }
    },
    "message": {
      "type": "string"
    },
    "servedBy": {
      "type": "string"
    },
    "openDrafts": {
      "type": "integer"
    }
  },
  "additionalProperties": true
}
event_draft_list annotations
{
  "title": "List your unpublished drafts (hosts)",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
event_draft_delete — Delete one of your unpublished drafts (hosts)
Advertised by the server during the last successful anonymous check.
Advertised destructive

Deletes one of the signed-in person's own unpublished drafts for good, with its guest details and uploads, as the organizer dashboard's Delete draft does. `eventIdOrName` is the draft's id or its name as the host says it. FIRST CALL WITHOUT `confirm` returns a PREVIEW naming the draft with a `requestId` and deletes nothing; read it out, and only when the host says yes, call again with `confirm: true` and that `requestId`. A published event cannot be deleted (NOT_A_DRAFT). Only the host can delete. The reply names what was deleted and the new count of open drafts. Refusals (NOT_FOUND, NOT_AUTHORIZED, NOT_A_DRAFT, CONFIRM_INVALID, DELETE_FAILED) are read out as given. It requires a personal connector token.

event_draft_delete input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName"
  ],
  "properties": {
    "confirm": {
      "type": "boolean",
      "description": "Absent on the first call, which deletes nothing; true with requestId deletes."
    },
    "requestId": {
      "type": "string",
      "description": "The requestId the first call returned."
    },
    "eventIdOrName": {
      "type": "string",
      "maxLength": 160,
      "description": "The draft's event id or its name as the host says it."
    }
  }
}
event_draft_delete output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "deleted"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "code": {
      "type": "string"
    },
    "name": {
      "type": "string"
    },
    "error": {
      "type": "string"
    },
    "deleted": {
      "type": "boolean"
    },
    "message": {
      "type": "string"
    },
    "preview": {
      "type": "boolean"
    },
    "servedBy": {
      "type": "string"
    },
    "requestId": {
      "type": "string"
    },
    "openDrafts": {
      "type": [
        "integer",
        "null"
      ]
    }
  },
  "additionalProperties": true
}
event_draft_delete annotations
{
  "title": "Delete one of your unpublished drafts (hosts)",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": true
}
event_tiktok_post — Post my event to my TikTok
Advertised by the server during the last successful anonymous check.
Open-world

Posts the host's event to the host's OWN TikTok account: the event's photo card, the same post the Sonar Connections dashboard's Post to TikTok panel makes, through the same server door. Only a host or organizer of the event can post, and only to the TikTok account they connected themselves. `eventId` names the event. `mode` is post (published now) or draft (sent to the host's TikTok inbox to finish there). For a post, `privacyLevel` is REQUIRED and has no default: it is one of the options TikTok offers this account; call without it and the reply lists them (`privacyLevelOptions`), then ask the host who can view the post and call again with their pick. While Sonar Connections is in TikTok's review, TikTok accepts private posts only (SELF_ONLY, only the host can view); say so if the host asks for a wider audience. `caption` is optional (up to 4000 characters, no links, times or street address); without it the event name is the caption. `allowComments` is off unless the host asks for comments. `disclose` is off unless the host says the post promotes their own brand (`yourBrand`) or is paid or branded content (`brandedContent`); branded content cannot be private. Repeat the host's choices back and get a clear yes first: the call posts. Not connected: the reply carries a one-tap connect link (`url`) with a `message`; give both exactly and tell them not to forward it. The reply's `state` is posted, saved, processing or failed, with a `line` to read out; refusals (NOT_SIGNED_IN, not_enabled, forbidden, privacy_mismatch, branded_private, bad_title) are read out as given. It requires a personal connector token.

event_tiktok_post input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventId",
    "mode"
  ],
  "properties": {
    "mode": {
      "enum": [
        "post",
        "draft"
      ],
      "type": "string",
      "description": "post publishes now; draft sends it to the host's TikTok inbox to finish there."
    },
    "caption": {
      "type": "string",
      "maxLength": 4000,
      "description": "Optional: the caption, in the host's words."
    },
    "eventId": {
      "type": "string",
      "maxLength": 64,
      "description": "The event's id."
    },
    "disclose": {
      "type": "object",
      "properties": {
        "yourBrand": {
          "type": "boolean"
        },
        "brandedContent": {
          "type": "boolean"
        }
      },
      "description": "Optional: {yourBrand, brandedContent}, each true only when the host says so. Default off."
    },
    "privacyLevel": {
      "type": "string",
      "maxLength": 40,
      "description": "Who can view a post: one of the privacyLevelOptions TikTok offers this account. Required for a post; the host picks it."
    },
    "allowComments": {
      "type": "boolean",
      "description": "Optional: true only when the host wants comments. Default false."
    }
  }
}
event_tiktok_post output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "ok",
        "state"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "url": {
      "type": "string"
    },
    "code": {
      "type": "string"
    },
    "line": {
      "type": "string"
    },
    "mode": {
      "type": "string"
    },
    "error": {
      "type": "string"
    },
    "state": {
      "type": "string"
    },
    "detail": {
      "type": "string"
    },
    "message": {
      "type": "string"
    },
    "nickname": {
      "type": "string"
    },
    "servedBy": {
      "type": "string"
    },
    "expiresInSeconds": {
      "type": "integer"
    },
    "privacyLevelOptions": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  },
  "additionalProperties": true
}
event_tiktok_post annotations
{
  "title": "Post my event to my TikTok",
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
event_change_detail — Change one detail of a personal event (hosts only)
Advertised by the server during the last successful anonymous check.
Advertised destructive

To change an existing event's pass palette or color ("change the color to sage"): call this tool with `field` "color" or "palette". THE HOSTS' OWN EDIT of a wedding or other personal event. IT APPLIES THE CHANGE ON THIS CALL, one `field` per call, and the reply says the detail now and before: read both out. A time needs am or pm, or a 24 hour time that reads one way; a bare "4:30" is refused. For faq_answer, `question` adds the entry or replaces its answer. Every change is logged and can be read back; event_change_undo reverses the caller's own latest one. Only the hosts can change it; read refusals (NOT_A_HOST, BAD_TIME, NO_SUCH_PLACE, NO_SUCH_ENTRY, NO_CHANGE) out as given; it sends no message and it changes nothing else on the event; the event's Wallet passes are updated with the new detail as a lock-screen notice and the reply's `passNotice` says how many passes were reached. Needs a personal connector token. CARD LOOKS: `field` "card" with a `card` object sets how the event's card looks (look, accent, tabs, heightCapPx, intro) for every host, or for one `cardHost`; `value` is not needed for it. The organizer of a convention may use it for their own event, and the hosts for a personal event; an unknown setting or value is refused with the allowed set, and event_change_undo reverses it. QUIETLY: `quiet` true saves the change and updates the passes with no lock-screen notice (say it when the host says "quietly"); several edits in one turn send at most one notice. `field` "place_time" sets the Places-tab time of one session named by `sessionId` or `entryTitle`; a Places line that follows its session moves the session. A title or place that more than one answers to is refused with the candidates: ask which. START TIME: `field` "start_time" sets the time a one day personal event starts, with no schedule needed. `value`: "5 PM" or "5 PM to 9 PM" (am or pm required), or "clear" to remove it. It can also change the event's dates: give the new first and last day, and any agenda items outside the new dates are listed back to you before anything is removed. A time may run past midnight ("10 PM to 2 AM" ends the next morning), and one item can be added on several days at once or span days. LANGUAGE: `field` "language" with `value` a language code (en, es) sets the language guests see on the passes, the add page and notices; issued passes relabel quietly, with no alert, and the hosts' own text is untouched. COVER PHOTO: `field` "cover_photo" (any `value`, e.g. "add") answers with a one-time link to our upload page; give the host the link and its sentence. The photo goes from their phone to us, never through this chat. Call it again after they say done: the reply carries the pass preview with the photo. PALETTE: `field` "palette" with a palette name, or "color" with a color name or #rrggbb, changes the pass colors; the text color is chosen so it stays readable. Without `confirm` the reply is a preview: show it, and only on a yes call again with confirm true. Issued passes update quietly, with no alert. PARTY LINK: `field` "party_link" runs one shareable link for a personal event; anyone who taps it adds their own pass. `value`: on, pause, resume, status (the count and the latest adds), regenerate (the old link stops), revoke all, or settings like "cap 80, names on, one per phone off, expires 2026-11-15". "sign in none" lets anyone with the link add a pass with no phone number and no code (no text updates, the host sees a count only, the cap counts every add, and a shared link admits anyone until regenerate); "sign in phone" asks for the number again. GUEST CODE: `field` "guest_code" changes the code guests type to open a private event's page; `value` is the new code (4 to 32 letters and digits) or "new" for a fresh one. The old code stops working. Read the new code back to the host. SHARE PREVIEW: `field` "share_level" sets what a texted link to a personal event previews as. `value`: branded (cover photo, name, date), name_only (a card with the name and date), private ("A private event", nothing else), or status (what the link looks like now, with the image url). LOOK: `field` "page_template" picks the guest page template (summit, market, gala, garden), "pass_style" the Google pass style (A, C, D, E, F, G), and "title_font" the title face for the event page and the share card only (Bodoni Moda, Sofia Sans Extra Condensed, Fredoka, Jost, Caprasimo, or default for the template's own); the pass always uses the system font. `value` "status" answers the current look. EYEBROW: `field` "eyebrow" sets the short word the guest page prints over the event name instead of its kind (2 to 24 characters, for example "Live music"); `value` "none" goes back to the kind.

event_change_detail input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName",
    "field"
  ],
  "properties": {
    "card": {
      "type": "object",
      "properties": {
        "look": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "number"
            },
            {
              "type": "boolean"
            },
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          ],
          "description": "classic, bold, quiet."
        },
        "tabs": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "number"
            },
            {
              "type": "boolean"
            },
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          ],
          "description": "one or more of directory, agenda, offers, in the order to show them, each once (floor card only)."
        },
        "intro": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "number"
            },
            {
              "type": "boolean"
            },
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          ],
          "description": "on, off (floor card only)."
        },
        "accent": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "number"
            },
            {
              "type": "boolean"
            },
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          ],
          "description": "a colour as #rrggbb, or null for the brand colour."
        },
        "heightCapPx": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "number"
            },
            {
              "type": "boolean"
            },
            {
              "type": "null"
            },
            {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          ],
          "description": "a whole number of pixels from 480 to 2400, or null for the height of the content (floor card only)."
        }
      },
      "description": "For card: the settings to change, each with its new value.",
      "additionalProperties": {}
    },
    "days": {
      "type": "array",
      "items": {
        "type": "string",
        "maxLength": 20
      },
      "maxItems": 14,
      "description": "For schedule_series: the days, each YYYY-MM-DD, or [\"every day\"]."
    },
    "field": {
      "enum": [
        "ceremony_time",
        "ceremony_place",
        "reception_time",
        "reception_place",
        "dress_code",
        "arrival_note",
        "schedule_time",
        "faq_answer",
        "card",
        "place_time",
        "start_time",
        "event_dates",
        "schedule_series",
        "language",
        "cover_photo",
        "palette",
        "color",
        "party_link",
        "guest_code",
        "share_level",
        "family",
        "page_template",
        "pass_style",
        "title_font",
        "eyebrow"
      ],
      "type": "string",
      "description": "Which detail. The place fields take an optional `venueName`; schedule_time takes `entryTitle`; faq_answer takes `question`. card takes `card`. place_time takes `sessionId` or `entryTitle`. start_time takes a time like \"5 PM\" in value. event_dates takes \"YYYY-MM-DD to YYYY-MM-DD\" in value; schedule_series takes entryTitle, a time range in value, and days. language takes a code in `value`. cover_photo answers with an upload link. palette takes a palette name, color a color name or #rrggbb. party_link takes a phrase in `value`. guest_code takes the new code or \"new\" in `value`. share_level takes a level or status in `value`. family re-homes the event (private-social, conference, fair-stroll, tournament); confirm true applies a re-home that waits for the host. page_template, pass_style and title_font take the choice or status in `value`. eyebrow takes the words, or \"none\", in `value`."
    },
    "quiet": {
      "type": "boolean",
      "description": "Optional; true saves the change with no lock-screen notice."
    },
    "value": {
      "type": "string",
      "maxLength": 800,
      "description": "The new value, as the hosts say it: a time, a place, a sentence or an answer. No links or markup. Not used for card."
    },
    "endDay": {
      "type": "string",
      "maxLength": 20,
      "description": "For schedule_series: the YYYY-MM-DD an item that spans days ends on (one day in days)."
    },
    "confirm": {
      "type": "boolean",
      "description": "For event_dates: true after the organizer says yes to the listed items coming off."
    },
    "cardHost": {
      "enum": [
        "default",
        "claude",
        "chatgpt",
        "claude_desktop",
        "inspector",
        "other",
        "standalone",
        "web"
      ],
      "type": "string",
      "description": "For card: one host to change it for. Leave out for every host."
    },
    "question": {
      "type": "string",
      "maxLength": 200,
      "description": "For faq_answer: the question."
    },
    "sessionId": {
      "type": "string",
      "maxLength": 128,
      "description": "For place_time: the session id as the agenda gave it."
    },
    "venueName": {
      "type": "string",
      "maxLength": 160,
      "description": "Optional venue name, for the place fields."
    },
    "entryTitle": {
      "type": "string",
      "maxLength": 200,
      "description": "For schedule_time: the row title as spelled."
    },
    "eventIdOrName": {
      "type": "string",
      "description": "The event id or the event name as the hosts spell it."
    }
  }
}
event_change_detail annotations
{
  "title": "Change one detail of a personal event (hosts only)",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": true
}
event_change_undo — Undo my last change
Advertised by the server during the last successful anonymous check.
Advertised destructive

Reverses the caller's own most recent change to a wedding or other personal event they host, restoring the value the detail had before it, through the same checks and into the same change log; each further call reverses the next older change of theirs. Needs a personal connector token and `eventIdOrName`. Only the hosts can use it, and only on changes they made themselves; an undo is not itself reversed. A change that gave a detail its first value, or no change left to reverse, answers NOTHING_TO_UNDO and changes nothing. When the event's Wallet passes are switched on, restoring a detail the pass shows updates every pass of the event and pushes the restored line to each phone that registered it. Returns the detail, the value before and after, a sentence for the person and, with passes on, `passNotice`.

event_change_undo input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName"
  ],
  "properties": {
    "eventIdOrName": {
      "type": "string",
      "description": "REQUIRED. The event id (test_wedding_a_garden) or the event NAME as the hosts spell it (\"Susie and John\")."
    }
  }
}
event_change_undo annotations
{
  "title": "Undo my last change",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": true
}
event_send_request — Send the hosts a request about a personal event
Advertised by the server during the last successful anonymous check.

A GUEST ASKS THE HOSTS FOR SOMETHING. Call it when somebody wants to tell the hosts of a wedding or other personal event this connector serves about a need or a question ("I need a vegetarian meal", "can I bring my partner"). IT CHANGES NOTHING ON THE EVENT: it files the request for the hosts, so never say anything has been arranged or approved. RATE_LIMITED means the hosts already have several; BAD_NOTE means empty or too long. It requires a personal connector token.

event_send_request input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName",
    "category",
    "note"
  ],
  "properties": {
    "note": {
      "type": "string",
      "maxLength": 280,
      "description": "What they asked, in their own words, up to 280 characters; no contact details or links."
    },
    "category": {
      "enum": [
        "dietary",
        "accessibility",
        "plus_one",
        "travel",
        "other"
      ],
      "type": "string",
      "description": "dietary, accessibility, plus_one, travel or other."
    },
    "eventIdOrName": {
      "type": "string",
      "description": "The event id or name as the hosts spell it."
    }
  }
}
event_send_request annotations
{
  "title": "Send the hosts a request about a personal event",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": false
}
event_guest_requests — Read the guests' requests (hosts only)
Advertised by the server during the last successful anonymous check.
Advertised read-only

THE HOSTS' OWN LIST of what their guests have asked for on a personal event this connector serves. Call it for "what have our guests asked for", "any dietary requests", "who needs anything". It returns the OPEN requests, newest first, each one as a category, the note the guest wrote, who it is from and when it landed. ONLY THE HOSTS can read it; anybody else gets a refusal you read out as given. WHO IT IS FROM IS A FIRST NAME OR THE WORDS "a guest", and there is no phone number, no email address and no account id on this surface at all, so never offer to contact somebody from this list. Read the notes out as given and do not summarise a need into something the guest did not say. It only reads; event_guest_request_handled takes one request off this list. It requires a personal connector token.

event_guest_requests input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName"
  ],
  "properties": {
    "eventIdOrName": {
      "type": "string",
      "description": "REQUIRED. The event id or the event NAME as the hosts spell it."
    }
  }
}
event_guest_requests annotations
{
  "title": "Read the guests' requests (hosts only)",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
event_guest_request_handled — Mark a guest request handled
Advertised by the server during the last successful anonymous check.

Marks one guest request on a wedding or other personal event the caller hosts as handled, which takes it off the hosts' open list (event_guest_requests). Needs a personal connector token, `eventIdOrName` and `requestId`, the `id` of a row event_guest_requests returned. It records who marked it and when, messages nobody and changes nothing on the event. A request already marked handled stays handled and the reply says already. Only the hosts can mark one; an id that is not a request on this event is refused with NO_SUCH_REQUEST. Returns ok, the request `id`, `handled` and `already`.

event_guest_request_handled input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrName",
    "requestId"
  ],
  "properties": {
    "requestId": {
      "type": "string",
      "maxLength": 200,
      "description": "REQUIRED. The `id` of one request, exactly as a row from event_guest_requests gives it."
    },
    "eventIdOrName": {
      "type": "string",
      "description": "REQUIRED. The event id or the event NAME as the hosts spell it."
    }
  }
}
event_guest_request_handled annotations
{
  "title": "Mark a guest request handled",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
ui_card_diag — Report card diagnostics
Advertised by the server during the last successful anonymous check.

Used only by the interactive cards this connector draws, never to answer a question. A card view posts its own lifecycle markers here in small batches: that it mounted, which display mode and safe-area insets the host gave it, the heights it reported, whether a keyboard opened, and the outcome of the one action a person took on it. It accepts a closed vocabulary of markers and integer counts only, no free text of any kind, and it returns nothing but an acknowledgement. NOT FOR A MODEL TO CALL: it answers no question and looks nothing up. Call a data tool instead.

ui_card_diag input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "card",
    "sessionKey",
    "seq",
    "events"
  ],
  "properties": {
    "seq": {
      "type": "number",
      "description": "Which batch this is for that mount, 1 to 6. Past the budget it is refused."
    },
    "card": {
      "type": "string",
      "description": "Which card is speaking: menu, order, floor or storefront."
    },
    "host": {
      "type": "string",
      "description": "Which surface drew this card when it is not an MCP host: \"standalone\" for the connector's own shop page. Omit it inside a host. Any other value refuses the batch."
    },
    "events": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {},
        "additionalProperties": {}
      },
      "description": "Up to 40 markers: {t, kind} plus optionally code, n, c, span, mode, w, h, top, bottom, tplEpoch. An off-vocabulary kind, an unknown key or a non-integer number refuses the whole batch."
    },
    "sessionKey": {
      "type": "string",
      "description": "A random id the card minted for THIS mount. Not a user id, not a device id, 6 to 24 lowercase alphanumerics."
    }
  }
}
ui_card_diag annotations
{
  "title": "Report card diagnostics",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": false
}
events_booths — List booths and vendors
Advertised by the server during the last successful anonymous check.
Advertised read-only

Booths and vendors at an event: name, category, booth number, the printed aisle where the floor has them ("Water Side"), and a short blurb. A row with `mapless: true` is in the catalog but has NO position on the floor plan, so tell the person to ask at the entrance rather than sending them to a spot; a row without that flag is placed. Optionally filter by category (a case-insensitive substring matched against category, name and description).

events_booths input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrSlug"
  ],
  "properties": {
    "category": {
      "type": "string",
      "description": "Optional category filter, e.g. \"dessert\""
    },
    "boothNameOrId": {
      "type": "string",
      "description": "Optional booth id or name: returns that one booth's full card instead of the list"
    },
    "eventIdOrSlug": {
      "type": "string",
      "description": "Event id, public slug, or the event name as events_list spells it; short forms such as \"the stroll\" work."
    }
  }
}
events_booths output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "found",
        "eventId",
        "count",
        "booths"
      ]
    },
    {
      "required": [
        "found",
        "eventId",
        "booth"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "booth": {
      "type": "object"
    },
    "count": {
      "type": "integer"
    },
    "error": {
      "type": "string"
    },
    "found": {
      "type": "boolean"
    },
    "booths": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "filter": {
      "type": [
        "string",
        "null"
      ]
    },
    "eventId": {
      "type": "string"
    },
    "message": {
      "type": "string"
    },
    "eventName": {
      "type": [
        "string",
        "null"
      ]
    }
  },
  "additionalProperties": true
}
events_booths annotations
{
  "title": "List booths and vendors",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
events_offers — List live offers
Advertised by the server during the last successful anonymous check.
Advertised read-only

Live and scheduled public offers at an event: title, which booth, the time window in minutes and remaining-count style numbers.

events_offers input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrSlug"
  ],
  "properties": {
    "eventIdOrSlug": {
      "type": "string",
      "description": "Event id, public slug, or the event name as events_list spells it; short forms such as \"the stroll\" work."
    }
  }
}
events_offers output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "found",
        "eventId",
        "offerCount",
        "endedCount",
        "offers",
        "raffles"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "error": {
      "type": "string"
    },
    "found": {
      "type": "boolean"
    },
    "offers": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "drawing": {
      "type": "object"
    },
    "eventId": {
      "type": "string"
    },
    "message": {
      "type": "string"
    },
    "raffles": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "endedCount": {
      "type": "integer"
    },
    "offerCount": {
      "type": "integer"
    }
  },
  "additionalProperties": true
}
events_offers annotations
{
  "title": "List live offers",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
events_whats_on — Get the agenda or lineup
Advertised by the server during the last successful anonymous check.
Advertised read-only

Agenda sessions and performances with their times. `when` accepts "all" (default), "today", "now" (the next few hours) or a YYYY-MM-DD date. Each row carries a `speakers` array in the order the session lists them, with each speaker's name, `role` (what the organizer published for that PERSON - "Moderator", "Judge" - it is a speaker-level note, so do not read it as "the moderator of this one session"), `title` (their job title line, which is a different fact from role and both may be present), `company`, `bio`, `expertiseTags`, `socialLinks`, a portrait photo URL, and a link to the organizer's own speaker profile page. Any of these except the name may be null or absent, which means the organizer did not publish it: say nothing rather than filling the gap. `speakerNames` is still there for the plain lineup.

events_whats_on input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrSlug"
  ],
  "properties": {
    "when": {
      "type": "string",
      "description": "\"all\" | \"today\" | \"now\" | YYYY-MM-DD"
    },
    "eventIdOrSlug": {
      "type": "string",
      "description": "Event id, public slug, or the event name as events_list spells it; short forms such as \"the stroll\" work."
    }
  }
}
events_whats_on output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "found",
        "eventId",
        "when",
        "count",
        "sessions"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "when": {
      "type": "string"
    },
    "count": {
      "type": "integer"
    },
    "error": {
      "type": "string"
    },
    "found": {
      "type": "boolean"
    },
    "eventId": {
      "type": "string"
    },
    "message": {
      "type": "string"
    },
    "sessions": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "timezone": {
      "type": [
        "string",
        "null"
      ]
    }
  },
  "additionalProperties": true
}
events_whats_on annotations
{
  "title": "Get the agenda or lineup",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
events_speakers — List an event's speakers
Advertised by the server during the last successful anonymous check.
Advertised read-only

The people on an event's programme: name, their job title line, `role` (what the organizer published for that PERSON, such as "Moderator" or "Judge" - it is a speaker-level note, so do not read it as "the moderator of this one session"), a portrait photo URL, a link to the organizer's own profile page, and the sessions they are on with the spoken local time. Ordered by when they are first on stage. Optionally filter to one day. Any field except the name may be null, which means the organizer published nothing there: say nothing rather than filling the gap. When an event publishes no speaker records the roster is built from the programme itself and `source` says "program"; those rows carry a `kind` of "speaker" or "performer" and nothing else about the person.

events_speakers input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "eventIdOrSlug"
  ],
  "properties": {
    "day": {
      "type": "string",
      "description": "Optional day filter: \"today\" or YYYY-MM-DD, read in the event's own timezone"
    },
    "speaker": {
      "type": "string",
      "description": "Optional speaker name or speakerId: returns that one person's full record instead of the roster"
    },
    "eventIdOrSlug": {
      "type": "string",
      "description": "Event id, public slug, or the event name as events_list spells it; short forms such as \"the stroll\" work."
    }
  }
}
events_speakers output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "found",
        "eventId",
        "count",
        "roster"
      ]
    },
    {
      "required": [
        "found",
        "eventId",
        "speaker"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "day": {
      "type": [
        "string",
        "null"
      ]
    },
    "count": {
      "type": "integer"
    },
    "error": {
      "type": "string"
    },
    "found": {
      "type": "boolean"
    },
    "roster": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "source": {
      "type": "string"
    },
    "eventId": {
      "type": "string"
    },
    "message": {
      "type": "string"
    },
    "speaker": {
      "type": "object"
    },
    "timezone": {
      "type": [
        "string",
        "null"
      ]
    },
    "eventName": {
      "type": [
        "string",
        "null"
      ]
    },
    "eventDayCount": {
      "type": "integer"
    }
  },
  "additionalProperties": true
}
events_speakers annotations
{
  "title": "List an event's speakers",
  "readOnlyHint": true,
  "openWorldHint": false,
  "destructiveHint": false
}
biz_info — Business details, services and hours
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Details for a business served through this connector: tagline, services or menu with prices, weekly hours and today's hours. Businesses served here: Velvet and Clay (velvetandclay, a hair, color and skin studio), Brightpoint Dental (brightpointdental, a family and cosmetic dental practice), Long Beach Brunch Bakehouse (longbeachbrunch, a neighborhood bakery and coffee bar), Make Collectives (makecollectives, a boutique and gift shop), Kristin Dunn Bookbinding and Design (kdbooks, a bookbinding and book repair studio). Speak `hoursNow.text`, resolved in the business's own timezone. `openToday` is true, false or NULL; NULL IS NOT FALSE: when `hoursState` is 'unstated' say the hours are not published and NEVER say it is closed. A `schedulingSystem` of Square means bookings live in that business's own Square calendar. `isDemo` says whether it is a demonstration. For what a shop sells call biz_storefront; to book, biz_availability then biz_book.

biz_info input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "business": {
      "type": "string",
      "description": "Which business, by name or id. Available: Velvet and Clay (velvetandclay), Brightpoint Dental (brightpointdental), Long Beach Brunch Bakehouse (longbeachbrunch), Make Collectives (makecollectives), Kristin Dunn Bookbinding and Design (kdbooks). Optional, defaults to velvetandclay. An unclear name is REFUSED with the list, not answered about a different business."
    },
    "businessId": {
      "type": "string",
      "description": "Alias for `business`; ignored when `business` is given."
    }
  }
}
biz_info output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "found",
        "businessId",
        "business"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "error": {
      "type": "string"
    },
    "found": {
      "type": "boolean"
    },
    "isDemo": {
      "type": "boolean"
    },
    "message": {
      "type": "string"
    },
    "bookable": {
      "type": "boolean"
    },
    "business": {
      "type": "object"
    },
    "hoursNow": {
      "type": "object"
    },
    "servedBy": {
      "type": "string"
    },
    "available": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "openToday": {
      "type": [
        "boolean",
        "null"
      ]
    },
    "sourceUrl": {
      "type": [
        "string",
        "null"
      ]
    },
    "businessId": {
      "type": "string"
    },
    "todaysHours": {
      "type": [
        "object",
        "null"
      ]
    },
    "otherBusinesses": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  },
  "additionalProperties": true
}
biz_info annotations
{
  "title": "Business details, services and hours",
  "readOnlyHint": true,
  "openWorldHint": true,
  "destructiveHint": false
}
biz_availability — List open appointment slots
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Open appointment slots at a business served through this connector, for one date (default today in its own timezone). Businesses served here: Velvet and Clay (velvetandclay, a hair, color and skin studio), Brightpoint Dental (brightpointdental, a family and cosmetic dental practice). Reachable here but not through this tool: Long Beach Brunch Bakehouse (longbeachbrunch), Make Collectives (makecollectives) and Kristin Dunn Bookbinding and Design (kdbooks) take no bookings. Each slot has a stable `slotId` that biz_book accepts; started slots are never returned. A closed day returns none with a reason. closedReason HOURS_UNSTATED is NOT a closed day: say the business has not published hours for that date, never that it is closed.

biz_availability input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "date": {
      "type": "string",
      "description": "YYYY-MM-DD, defaults to today in the business timezone"
    },
    "business": {
      "type": "string",
      "description": "Which business, by name or id. Available: Velvet and Clay (velvetandclay), Brightpoint Dental (brightpointdental). Optional, defaults to velvetandclay. An unclear name is REFUSED with the list, not answered about a different business."
    },
    "businessId": {
      "type": "string",
      "description": "Alias for `business`; ignored when `business` is given."
    }
  }
}
biz_availability annotations
{
  "title": "List open appointment slots",
  "readOnlyHint": true,
  "openWorldHint": true,
  "destructiveHint": false
}
biz_menu — Pickup menu and times
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

The PICKUP MENU for a business served through this connector: items, prices, allergens, notice needed, and the pickup windows on a date (default today). Businesses with a pickup menu here: Long Beach Brunch Bakehouse (longbeachbrunch, a neighborhood bakery and coffee bar). Reachable here but not through this tool: Velvet and Clay (velvetandclay), Brightpoint Dental (brightpointdental), Make Collectives (makecollectives) and Kristin Dunn Bookbinding and Design (kdbooks) have no pickup menu here. longbeachbrunch sells cookies, bars, pastry, brunch boxes, platters, cakes and coffee. This tool only reads. Orders are placed with a separate tool, biz_order, which takes item ids and a pickup window id from this reply exactly as written; right now it takes pickup orders for Long Beach Brunch Bakehouse (longbeachbrunch). Pickup only. An 'unstated' `hoursByDay` row is NEVER spoken as closed.

biz_menu input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "date": {
      "type": "string",
      "description": "Optional YYYY-MM-DD; today in the business timezone."
    },
    "business": {
      "type": "string",
      "description": "Which business, by name or id. Available: Long Beach Brunch Bakehouse (longbeachbrunch). The default (velvetandclay) has no pickup menu here, so NAME THE BUSINESS: an omitted argument is refused. An unclear name is REFUSED with the list, not answered about a different business."
    },
    "businessId": {
      "type": "string",
      "description": "Alias for `business`; ignored when `business` is given."
    }
  }
}
biz_menu output schema
{
  "type": "object",
  "anyOf": [
    {
      "required": [
        "found",
        "businessId",
        "categories",
        "pickupWindows"
      ]
    },
    {
      "required": [
        "ok"
      ],
      "properties": {
        "ok": {
          "const": false
        }
      }
    },
    {
      "required": [
        "found"
      ],
      "properties": {
        "found": {
          "const": false
        }
      }
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "properties": {
    "ok": {
      "type": "boolean"
    },
    "open": {
      "type": "boolean"
    },
    "error": {
      "type": "string"
    },
    "found": {
      "type": "boolean"
    },
    "notes": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "isDemo": {
      "type": "boolean"
    },
    "message": {
      "type": "string"
    },
    "servedBy": {
      "type": "string"
    },
    "available": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "sourceUrl": {
      "type": [
        "string",
        "null"
      ]
    },
    "businessId": {
      "type": "string"
    },
    "categories": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "closedReason": {
      "type": [
        "string",
        "null"
      ]
    },
    "pickupWindows": {
      "type": "array",
      "items": {
        "type": "object"
      }
    },
    "openWindowCount": {
      "type": "integer"
    }
  },
  "additionalProperties": true
}
biz_menu annotations
{
  "title": "Pickup menu and times",
  "readOnlyHint": true,
  "openWorldHint": true,
  "destructiveHint": false
}
biz_order — Place a pickup order
Advertised by the server during the last successful anonymous check.
Open-world

Places a pickup pre-order at a business served through this connector: placing an order, a pickup order, or the checkout after biz_menu. Needs `items` and a `pickupWindowId` from biz_menu and the collector's first name; no phone, email, surname or card is collected. Businesses served here: Long Beach Brunch Bakehouse (longbeachbrunch, a neighborhood bakery and coffee bar). Reachable here but not through this tool: Velvet and Clay (velvetandclay), Brightpoint Dental (brightpointdental), Make Collectives (makecollectives) and Kristin Dunn Bookbinding and Design (kdbooks) take no pickup orders. Most orders are paid at pickup; where the reply is HELD, its `payUrl` is the only payment link this connector issues: give it exactly as returned. `isDemo` true reserves nothing.

biz_order input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "items",
    "pickupWindowId",
    "firstName"
  ],
  "properties": {
    "note": {
      "type": "string",
      "description": "Optional note, 140 characters; contact details are removed."
    },
    "items": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "id",
          "qty"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Item id from biz_menu."
          },
          "qty": {
            "type": "integer",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "description": "Quantity."
          }
        }
      },
      "description": "Order lines, at least one."
    },
    "business": {
      "type": "string",
      "description": "Which business, by name or id. Available: Long Beach Brunch Bakehouse (longbeachbrunch). The default (velvetandclay) takes no pickup orders, so NAME THE BUSINESS: an omitted argument is refused. An unclear name is REFUSED with the list, not answered about a different business."
    },
    "firstName": {
      "type": "string",
      "description": "First name only."
    },
    "businessId": {
      "type": "string",
      "description": "Alias for `business`; ignored when `business` is given."
    },
    "pickupWindowId": {
      "type": "string",
      "description": "Window id from biz_menu."
    }
  }
}
biz_order annotations
{
  "title": "Place a pickup order",
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
biz_order_status — Check pickup order payment
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Read the CURRENT state of a pickup order placed through this connector, by its confirmation code (the LBB-XXXXXX style code biz_order returned). It answers with the order state, the payment state, whether it is PAID, the pickup window, the business name and the total, and nothing else: no customer name, no items and no payment link. Use it after a customer has been sent to a checkout page, to tell them whether the payment has landed and the order is placed. It changes nothing. A code that names no order comes back not found.

biz_order_status input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "confirmationCode"
  ],
  "properties": {
    "confirmationCode": {
      "type": "string",
      "description": "The order confirmation code, e.g. LBB-KKA8Y2. Case does not matter."
    }
  }
}
biz_order_status annotations
{
  "title": "Check pickup order payment",
  "readOnlyHint": true,
  "openWorldHint": true,
  "destructiveHint": false
}
biz_storefront — Shop catalog, prices and availability
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

CALL THIS for what a shop sells, its products, its prices, a gift idea, or browsing or shopping a store served here. Reads that shop's OWN published catalog: title, maker, type, price, stock and one image per product. Businesses served here: Make Collectives (makecollectives, a boutique and gift shop), Kristin Dunn Bookbinding and Design (kdbooks, a bookbinding and book repair studio). Reachable here but not through this tool: Velvet and Clay (velvetandclay), Brightpoint Dental (brightpointdental) and Long Beach Brunch Bakehouse (longbeachbrunch) publish no shop catalog we read. makecollectives is Make Collectives, a boutique at 430 E. 1st St in Long Beach. kdbooks is Kristin Dunn Bookbinding and Design in Long Beach; her work is MADE TO ORDER, so say what `leadTimeNote` says. TWO SHOP PLATFORMS ARE READ HERE, a Shopify store and a WooCommerce shop, same reply shape; ON A WOOCOMMERCE SHOP ONE CART LINK CARRIES EXACTLY ONE ITEM. `query` only removes products. Sixty a page with `pageCount` and `total`: never say sixty is all. Give `cartUrl` and `shopUrl` exactly as returned, never a link of your own. WHERE THIS REPLY DRAWS THE SHOP CARD, THE CARD ITSELF HOLDS A BASKET: the person taps Add to cart there. Say what `buyingNote` says. No payment passes through Sonar Connections.

biz_storefront input schema
{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "page": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": -9007199254740991,
      "description": "Optional page, 1-based; 60 products a page."
    },
    "limit": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": -9007199254740991,
      "description": "Optional, 1 to 60."
    },
    "query": {
      "type": "string",
      "description": "Optional words to narrow the catalog; it only removes products."
    },
    "business": {
      "type": "string",
      "description": "Which business, by name or id. Available: Make Collectives (makecollectives), Kristin Dunn Bookbinding and Design (kdbooks). The default (velvetandclay) publishes no shop catalog we read, so NAME THE BUSINESS: an omitted argument is refused. An unclear name is REFUSED with the list, not answered about a different business."
    },
    "businessId": {
      "type": "string",
      "description": "Alias for `business`; ignored when `business` is given."
    }
  }
}
biz_storefront annotations
{
  "title": "Shop catalog, prices and availability",
  "readOnlyHint": true,
  "openWorldHint": true,
  "destructiveHint": false
}

Prompts

Not advertised

No prompt definitions available.

Resources

10 advertised

biz-menu-card — Pickup menu card

Advertised by the server during the last successful anonymous check.

An interactive card for a pickup menu served through this connector.

biz-menu-card URI
ui://sonar-connections/biz-menu-card.2178ce8edee8.html

MIME type: text/html;profile=mcp-app

biz-menu-card-legacy — Pickup menu card

Advertised by the server during the last successful anonymous check.

An interactive card for a pickup menu served through this connector.

biz-menu-card-legacy URI
ui://sonar-connections/biz-menu-card.html

MIME type: text/html;profile=mcp-app

biz-order-card — Pickup order card

Advertised by the server during the last successful anonymous check.

An interactive card for a pickup order placed through this connector, with its pickup window, total and payment state.

biz-order-card URI
ui://sonar-connections/biz-order-card.477632f4ea56.html

MIME type: text/html;profile=mcp-app

biz-order-card-legacy — Pickup order card

Advertised by the server during the last successful anonymous check.

An interactive card for a pickup order placed through this connector, with its pickup window, total and payment state.

biz-order-card-legacy URI
ui://sonar-connections/biz-order-card.html

MIME type: text/html;profile=mcp-app

event-floor-card — Event floor card

Advertised by the server during the last successful anonymous check.

The event floor plan with its booths, a directory, what is on now and the live offers, drawn from this connector.

event-floor-card URI
ui://sonar-connections/event-floor-card.f0527c9de490.html

MIME type: text/html;profile=mcp-app

event-floor-card-legacy — Event floor card

Advertised by the server during the last successful anonymous check.

The event floor plan with its booths, a directory, what is on now and the live offers, drawn from this connector.

event-floor-card-legacy URI
ui://sonar-connections/event-floor-card.html

MIME type: text/html;profile=mcp-app

storefront-card — Shop card

Advertised by the server during the last successful anonymous check.

An interactive card for a shop served through this connector: its products with prices and availability, a product detail on tap, and a Buy control that opens the shop's own checkout.

storefront-card URI
ui://sonar-connections/storefront-card.1a0f4ade642c.html

MIME type: text/html;profile=mcp-app

storefront-card-legacy — Shop card

Advertised by the server during the last successful anonymous check.

An interactive card for a shop served through this connector: its products with prices and availability, a product detail on tap, and a Buy control that opens the shop's own checkout.

storefront-card-legacy URI
ui://sonar-connections/storefront-card.html

MIME type: text/html;profile=mcp-app

personal-event-card — Personal event card

Advertised by the server during the last successful anonymous check.

An interactive card for a personal event served through this connector: the hosts, the day, the places, the people and the questions the hosts have answered, at the level of detail they included.

personal-event-card URI
ui://sonar-connections/personal-event-card.55f5048439d9.html

MIME type: text/html;profile=mcp-app

personal-event-card-legacy — Personal event card

Advertised by the server during the last successful anonymous check.

An interactive card for a personal event served through this connector: the hosts, the day, the places, the people and the questions the hosts have answered, at the level of detail they included.

personal-event-card-legacy URI
ui://sonar-connections/personal-event-card.html

MIME type: text/html;profile=mcp-app

90-day uptime

A lightweight connection check about every six hours, sampled on hosts with many listings. It shows the server answered, not that its tools work.

Too few checks for a percentage yet (3 of 3 answered).

  1. 2026-11-07: 2 of 2 checks answered
  2. 2026-11-09: 1 of 1 checks answered

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
545 ms
95th percentile latency
545 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 545 ms · metadata changed · 62 tool(s), 10 resource(s), 0 resource template(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http sonar-connections-mcp https://mcpconnector-gtlizqtvza-uw.a.run.app/public

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add sonar-connections-mcp --url https://mcpconnector-gtlizqtvza-uw.a.run.app/public

Cursor

Merge this server into .cursor/mcp.json in your project, then enable sonar-connections-mcp in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "sonar-connections-mcp": {
      "url": "https://mcpconnector-gtlizqtvza-uw.a.run.app/public"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "sonar-connections-mcp": {
      "type": "streamableHttp",
      "url": "https://mcpconnector-gtlizqtvza-uw.a.run.app/public",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start sonar-connections-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "sonar-connections-mcp": {
      "type": "http",
      "url": "https://mcpconnector-gtlizqtvza-uw.a.run.app/public"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http sonar-connections-mcp https://mcpconnector-gtlizqtvza-uw.a.run.app/public

Claude Desktop

Open Claude Settings > Connectors > Add custom connector, enter this server URL and enable it for the conversation. This is a manual remote-connector handoff, not a desktop JSON configuration.
Claude Desktop configuration
https://mcpconnector-gtlizqtvza-uw.a.run.app/public

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "sonar-connections-mcp": {
      "serverUrl": "https://mcpconnector-gtlizqtvza-uw.a.run.app/public"
    }
  }
}

Let your agent find its tools

Find servers like Sonar Connections MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.

Do you run Sonar Connections MCP?

Prove ownership with a DNS record, a well-known file, or your Official MCP Registry entry, and your edits publish immediately. Proofs are re-checked weekly; admins can still hide or remove a listing.

Claim this listing