LeanData MCP
Manage and schedule meetings
- Category
- Sales & CRM
- Primary Subcategory
- Meeting Scheduling & Booking
Integration details
Description
Run LeanData Scheduling conversationally. Sales reps handle their own links and meetings; admins handle pools, routing, and availability across the team. What you can do: Get a scheduling link: “Give me my booking link for the 30-minute intro meeting.” Manage your own meetings: “Reschedule my customer sync to next Wednesday afternoon.” Check team availability: “Check real-time availability for the SDR team for a 30-minute meeting Friday.” Route and book on a rep's behalf: “Route this prospect to an available rep and book a meeting for next week.” Run pool operations: “Add Priya to the Enterprise pool at half weight and auto-calibrate her.” Diagnose scheduling health: “List users with a broken calendar connection.”
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Meeting Scheduling & Booking
- Secondary Subcategories
- None listed
- Brand
- LeanData
- Access
- Account required
- First tracked
- 2026-09-29
- Tool count
- 28
- Geography
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Get alerts for LeanData MCP
Get updates when LeanData MCP’s Discoverability Score or category rank changes.
ChatGPT Plugin Discovery Score
ChatGPT Plugin discovery is coming soon
ChatGPT can surface a Plugin when it matches a user's request.Your Plugin Discovery Score measures how often yours appears.
No spam. Unsubscribe any time.
What discovery looks like

Competing in ChatGPT Meeting Scheduling & Booking
View Category28 tools agents can invoke
Add and/or remove members on an existing BookIt pool. Mirrors editing a pool's membership on the FuzzyMatcher Round Robin Pools page. **Incremental, not a replace.** `add` and `remove` name only the users to change; everyone else is left alone. There is no way to set a roster wholesale, which means a partial list can't accidentally empty a pool. To replace a roster, pass the departures in `remove` and the arrivals in `add` in the same call. **Removing a member leaves their meeting counts for this pool intact**, so re-adding them later restores the counts they had rather than starting them at zero. Only deleting the whole pool clears them. That makes remove-then-re-add closer to a pause than a reset — but prefer pausing the *user* if a pause is what you want, since removal also takes them out of the roster BookIt reads, and re-adding puts them back at the end of the member order. If the pool has `autoCalibrateNewMembers` on, added members start at the pool's current average rather than zero. **`add` doubles as the way to change an existing member's weighting.** Pass a user who is already in the pool with a different `weighting` and their weight is updated in place; they appear under `weightingUpdated` with the before and after values, not under `added`. Pass them with no `weighting`, or the same value they already have, and nothing happens — they're reported under `alreadyMembers`. Their position in the pool and their meeting counts are untouched either way. The same user cannot appear in both `add` and `remove`. **Called with only `poolId` and no `add`/`remove`, this is a repair.** It re-pushes the pool's current Salesforce state to BookIt without changing membership. That's what to do when any pool tool reports a partial failure — where Salesforce was updated but the BookIt sync didn't complete, leaving a pool that exists but won't be usable. Safe to repeat, and it won't move anyone's counts. Idempotent: repeating a call adds nobody twice and reports already-satisfied changes under `alreadyMembers` / `notInPool`.
bookit_edit_pool_members
Approve or deny pending credit-back requests in batch. The admin equivalent of the Invalid Meeting Management → Pending Requests tab in the BookIt admin UI. Find pending requests via `bookit_list_meeting_logs({ creditBackStatus: "pending" })` — each row's `sfdcMeetingLogId` is the input for this tool. On **approve**: the original host receives the credit-back (refunds their meeting count via incrementUserTotalCredit), `credit_back_status` is set to 'approved', and Salesforce is synced. On **deny**: `credit_back_status` is set to 'denied', no credit refund happens, and SF is synced. **Auto-classification to 'invalid'**: if any provided sfdcMeetingLogId's category has been deleted since the request was filed, that row is classified as invalid (no credit applied) regardless of the decision. The response surfaces this split via `processed.invalid[]` vs `processed.approved[]` / `processed.denied[]`. **Status validation**: refuses if ANY input ID is not currently `pending` (e.g. already-Approved or already-Denied). The internal UI hides these rows in the action buttons; the MCP tool checks server-side since there's no UI roster. Wraps POST /v1/credit-back/process. Requires SFDC-authenticated admin connection — the audit trail (`request_reviewer_id`) needs an SF user ID. **Deltas from internal /v2/updateMeetingLogCredit endpoint**: adds server-side pending-status validation; adds the SF sync that the UI flow does separately via iframe postMessage → Apex.
bookit_process_credit_back_requests
Create a booking/event for forms flow using the encrypted token returned from routing. Use this tool after the routing tool has been called. Pass the `routing.token` value from the bookit_route_and_fetch_availability response as the `params` argument (that token is the encrypted booking context — do NOT use `routing.calendarLink` or its `link=` value). The users array must come from the selected timeslot's users field in the availability response.
bookit_create_booking_forms
Cancel an existing BookIt meeting. Wraps DELETE /v1/meeting/:eventId. Throws "Meeting has already been canceled" if the meeting was previously canceled. Triggers bearoku's full cancel flow (calendar event removal, conferencing teardown, credit-back if applicable, meeting log update).
bookit_cancel_meeting
Grant or revoke BookIt product access for one or more users. Mirrors "Edit Product Access" on the BookIt tab of the FuzzyMatcher users page. **Revoking Links access takes down that user's booking links.** Turning `links` off soft-deletes every top-level scheduling link they own, so anyone holding those URLs gets a dead link. Turning it back on restores the links — that works here because the user stays BookIt-authorized. Two caveats: the links are also removed from every user's saved link library and that is **not** undone by restoring them, and links a user deleted themselves are never resurrected. Never revoke `links` as incidental tidying — only when someone specifically asks for that user to lose BookIt Links. Omitted flags keep their current value. `{ userId: "005...", handoff: true }` grants Handoff and leaves Forms and Links exactly as they are — it does not revoke them. So you never need to look up current access before calling this; send only what should change. A user must still authorize their calendar to actually use a product. Granting access to a user who has never authorized is valid setup, but it doesn't make them bookable — check `bookitAuthStatus` via `bookit_lookup type=users` if that matters. Repeating an identical call changes nothing.
bookit_edit_product_access
Return information about the current MCP connection, including whether its Salesforce authorization is still valid. Use this to verify what org you're connected to, your scope (admin vs user), how you authenticated, your Salesforce user ID, and — for SFDC connections — whether that Salesforce authorization is still live. Returns: - `ok` — always true if you reach this tool (auth passed) - `orgId` — the Salesforce organization ID this connection is scoped to - `email` — the email address tied to this connection - `scope` — `"admin"` or `"user"` (drives which tools you have access to) - `authMethod` — `"sfdc"` (Salesforce login) or `"agentforce"` (machine credentials). Several tools require SFDC auth (anything needing a user identity, e.g. bookit_get_my_user_details, or bookit_request_credit_back under user scope) and will reject a machine connection. One-time email codes (`"otc"`) were retired 2026-09-08 and no longer authenticate. - `userId` — the authenticated Salesforce user ID. Populated for `authMethod="sfdc"`; `null` otherwise. - `salesforce` — validity of the stored Salesforce authorization, checked live against Salesforce's token introspection endpoint: - `status: "valid"` — Salesforce confirms the authorization is active. - `status: "expired"` — revoked, or the user's access to the connected app was removed. **The user must re-authenticate with Salesforce**; SFDC-dependent tools will fail until they do. - `status: "not_connected"` — an SFDC connection with no stored Salesforce token; re-authenticate. - `status: "not_applicable"` — machine connection, so there is no Salesforce user authorization to check. - `status: "unknown"` — **the check itself failed** (couldn't reach Salesforce, or the server lacks Salesforce consumer credentials). This does NOT mean the authorization is bad — do not tell the user to re-authenticate on `unknown`; report that validity couldn't be determined. - `detail` — human-readable explanation of the status. - `lastUsedAt` — when the stored Salesforce token was last refreshed/used, if known. Because this reaches out to Salesforce, it is slightly slower than a purely local call. It never modifies anything. No parameters.
bookit_get_connection_info
Create a new pool from an existing count-based pool's configuration, under a new name. Mirrors "Copy" on the FuzzyMatcher Round Robin Pools page. Copies the source pool's settings (weighting, auto-calibration, product access, business unit, description) and, by default, its member roster with each member's weighting. **Counts and calibration are not copied.** The new pool's members all start at zero, exactly as if you had added them by hand — so the copy starts distributing evenly regardless of how lopsided the source pool's counts are. Set `autoCalibrateNewMembers` on the source first if you want a different starting point for future additions; it is copied along with the rest of the config. One caveat on that flag: it only functions when the org distributes by pool AND category. `bookit_create_pool` refuses to set it in category-only mode for that reason, but a copy inherits whatever the source holds — so copying a pool whose flag was set before the org switched modes reproduces an already-inert flag rather than creating a new one. The source must be a count-based meeting pool. Copying an order-based pool is rejected, since the result would be invisible to BookIt. The new name is subject to the same uniqueness rule as `bookit_create_pool`, so a second identical call is rejected rather than producing two copies — and as with create, recover from a partial failure by calling `bookit_edit_pool_members` with the new `poolId`, not by copying again.
bookit_copy_pool
Create a count-based round-robin pool for BookIt, optionally with members. Mirrors creating a pool on the FuzzyMatcher Round Robin Pools page. Only count-based meeting pools can be created here — that's the kind BookIt distributes meetings through. Order-based pools are a lead/contact routing concept that never reaches BookIt, so they're out of scope for this tool. **Pool names must be unique** across count-based *and* order-based pools with the same object type and business unit. A name that looks free in BookIt can still collide with an order-based pool you can't see from here; the tool checks Salesforce and tells you what it hit. Members are optional — a pool with no members is valid but has nobody to distribute to. Add them later with `bookit_edit_pool_members`. Resolve user IDs with `bookit_lookup type=users`; members must already be BookIt-authorized to receive meetings. Set `isWeighted` to distribute unevenly. Weightings are whole numbers from 1 to 100 and are **relative, not percentages** — each member's share is their weight over the sum of all weights, so 100/50 and 2/1 distribute identically. Any member without one defaults to 50, so leaving them all unset behaves the same as an unweighted pool. Idempotent: a second identical call is rejected as a duplicate name rather than silently making a second pool. So if this reports a partial failure — Salesforce written, BookIt sync incomplete — do **not** retry the create. Repair it instead by calling `bookit_edit_pool_members` with just the returned `poolId`.
bookit_create_pool
Revoke a user's BookIt access. Mirrors "Deauthorize from BookIt" and "Remove from BookIt" on the BookIt tab — one tool because those two actions are identical apart from the final status. **This is the most destructive tool here.** For every affected user it **permanently deletes their stored calendar tokens**, revokes conferencing tokens (Zoom/Teams), soft-deletes their booking links, and removes their BookIt product access. Existing booked meetings are not cancelled, but the user cannot host new ones. Always confirm with the user first, naming who will be affected. Recovery is not symmetric with `bookit_edit_product_access`. The calendar token is genuinely gone, so the user must re-authorize from scratch — and until they are authorized again, re-granting Links access does **not** bring their booking links back, because the restore only applies to users who are currently authorized. Their links also disappear from everyone's saved link library, which is never restored. `removeCompletely` picks between the two: - **false** (default) — Deauthorize. Status becomes `unauthorized`. - **true** — Remove from BookIt. Status is cleared, which is what makes the user appear in `bookit_lookup type=invitable_users` again so they can be re-invited. Everything destructive happens either way; the flag only decides whether the record keeps a status. `sendEmail` (default false) emails each affected user that they've been deauthorized. The users page makes this a per-action choice by the admin, so ask rather than assuming. **It can refuse.** If the org's Google Calendar for Vacations integration is on and one of these users is its admin, the call fails and nothing changes — deauthorizing them would break vacation sync for the whole org. Deauthorize that integration first. The users page refuses the same way. Users with no active BookIt authorization are skipped rather than erroring, and come back in `noActiveAuth`. Calling again is therefore safe: the second call finds nothing left to revoke and changes nothing. Note Microsoft calendar tokens cannot be revoked (no API for it) — access is blocked but the token itself isn't destroyed. Google tokens are revoked.
bookit_deauthorize_users
Permanently delete a count-based BookIt pool, along with its members and their meeting counts for that pool. **Refuses if anything still depends on the pool.** It will not delete a pool that is referenced by an active routing graph, on the roster of an active tradeshow, or holding routing audit logs whose metrics haven't been processed yet. There is no force option — if it refuses, resolve what it names and try again. It also refuses when it cannot *verify* those things, rather than assuming they're clear. Pools with past or upcoming booked meetings are **not** blocked. Those meetings live on the hosts' calendars independently and can still be viewed, rescheduled, and cancelled afterwards; only the pool's own routing counts go away. Only count-based meeting pools can be deleted here — the same set `bookit_create_pool` can make. Order-based pools are rejected. **This cannot be undone.** Meeting counts and calibration for the pool are hard-deleted, so recreating a pool with the same name and members starts everyone at zero. Confirm with the user before calling it. Idempotent: once the pool is gone, calling again reports that no such pool exists and changes nothing further.
bookit_delete_pool
Retrieve the exact form field input keys expected by a named BookIt for Forms trigger node in this org's routing graph. REQUIRED before calling bookit_route_and_fetch_availability — the field keys are customer-defined and vary by casing/format (e.g. 'FirstName', 'first_name', 'firstName'). Never guess these keys; always retrieve them here and pass them verbatim as formData keys to route_and_fetch_availability. The trigger node name itself is also customer-defined and varies per org. If the user has not told you which trigger node to use, ASK them — do not invent or guess a node name. There is no canonical default.
bookit_retrieve_inputs
Fetch alternate availability slots for an existing meeting — used to pick a new time before calling bookit_reschedule_meeting. Wraps POST /v1/scheduling/fetch-availability with the meeting's eventId. Bearoku branches internally: - Links / Routing Links bookings → returns availability based on the originating link's settings - BFF / non-Links bookings → returns availability based on the original meeting type Both branches return the same reschedule-relevant fields: `meeting`, `userIdToInfoMap`, `availability`, `calendarEvent`. The only divergence is inside `pageInfo` (Links has `nonSFDCUserIds`; BFF has `prefillFields`) — neither is reschedule-relevant. Pass the eventId from bookit_list_meetings (`calendarEvent.id`) or any other source — bearoku accepts calendar event IDs, bookit_event_uuids, and current_event_ids interchangeably.
bookit_get_availability_for_meeting
get calendar availability for a specified link id
bookit_get_availability_for_link
Get detailed information about your own BookIt user (the authenticated SF user). Returns the same shape as the admin `bookit_lookup` tool's user-detail response, but scoped to your own user automatically — no parameters needed. Includes: identity (name, email, calendarEmail, timezone), bookit auth status, product access (links/handoff/forms), pause status, profile picture, phone, first authorized date, links library, calendar token connection summary (provider, connectedEmail, status, expiresAt — never the token values themselves), working hours, upcoming vacations, and configured conferencing providers. Requires a Salesforce-authenticated connection. Machine (Agentforce) connections carry no user identity and will be rejected.
bookit_get_my_user_details
Email users the BookIt calendar-authorization invite and set their status to invited, optionally granting product access at the same time. **Use this for a first-time invite as well as a nudge** — it is the only invite path. On the FuzzyMatcher users page the equivalent action is labelled "Resend Invite to Authorize", but that same action is what invites someone initially, so don't read "resend" as requiring a previous invite. Setting product access here is usually what you want when onboarding someone: an invited user with no product access has nothing to use once they authorize. Doing both in one call also avoids the half-done state you get from inviting and granting separately. **This emails real people** and schedules a follow-up reminder sequence (3, 7 and 15 days). Confirm with the user before inviting anyone they didn't explicitly name. Product flags are optional and merged, exactly as in `bookit_edit_product_access`: omit a flag and it keeps its current value, so omitting all of them is a pure invite that changes no entitlements. Use `bookit_edit_product_access` when you're changing access for someone who is already set up and not being invited — that's the more common case and has nothing to do with inviting. Users invited within the last 2 minutes are **not re-emailed**, and reported in `skipped`. That's a guard against a duplicate send when a call times out and gets retried — it is not a general rate limit, and a genuine nudge days later goes through normally. **The window suppresses the email, not the product access.** If you set access flags for a user inside it, the access is still applied and `reason` is `"invited_recently_access_applied"`; if you set none, there was nothing to apply and `reason` is `"invited_recently"`. So calling this again to add a product moments after a first invite does what you asked — you just don't get a second email. Users with no email address on their Salesforce record are skipped with `reason: "no_email_address"`. Not idempotent in general: called again after the window, it sends another email and restarts the reminder sequence.
bookit_invite_users
List BookIt meetings for a specific prospect by email. Use this to find a meeting's eventId before calling bookit_get_availability_for_meeting, bookit_reschedule_meeting, or bookit_cancel_meeting. The eventId is the calendarEvent.id field on each result. Scoping: - User scope: returns only meetings where you are the main host (`meeting.main_host_id` = your SF user ID), filtered to the given prospectEmail. Requires a Salesforce-authenticated connection — machine (Agentforce) connections carry no user identity. The `userId` filter is ignored under user scope. - Admin scope: returns all org meetings for the prospect by default. Pass `userId` to filter to a specific host. Returns upcoming meetings by default (start window = now). Pass start/end (epoch ms or ISO strings) to widen the window. status filters on bearoku's meeting status (e.g. "Booked", "Canceled"). ## Returns `{ total, returned, results: [{ calendarEvent, bookIt: { status } }] }` Each result has: - `calendarEvent.id` — the eventId to pass into downstream cancel/reschedule/availability tools - `calendarEvent.scheduledTime` — { start_time, end_time } in epoch ms - `calendarEvent.title`, `location`, `attendees`, `organizer_email` - `bookIt.status` — bearoku-side status of the meeting
bookit_list_meetings
List individual meeting log records with filters. Use for drill-down questions about specific meetings (not aggregates — use bookit_meeting_stats for those). Scoping: - User scope: returns only meeting logs where you are the main host (`scheduled_with` = your SF user ID). Requires a Salesforce-authenticated connection — machine (Agentforce) connections carry no user identity. The `hostId` filter is ignored under user scope. - Admin scope: returns all org meeting logs by default. Pass `hostId` to filter to a specific host. Examples: - "Meetings booked last week that were later canceled" (status=Canceled; the date range filters booked/created date, not cancel date) - "What meetings did host X book this month?" (admin) - "Find meetings booked through BookIt for Forms" Use bookit_lookup to resolve names to IDs first if needed. ## Returns Each row has the fields below. Set `detail: true` to additionally include large/variable JSON payloads (eventInfoJson, mtdOverrides, leadCreationData, poolSnapshot). ### Identity & product - `type` — product label: "BookIt Links" / "BookIt for Forms" / "BookIt Handoff" / "BookIt Routing Links". Pairs with bookingMethod. - `meetingType` — { id, name, category } | null - `schedulingLink` — { id, name } | null. Populated for Links and Routing Links flows. ### Host & booking method - `scheduledWith` — SF user ID of the host - `scheduledBy` — SF user ID of who initiated/scheduled. Reliably set on Handoff; null/sparse on other products. - `meetingLinkOwner` — SF user ID of the link owner (Links / Routing Links). Hardcoded "N/A" on Dynamic Links. Never set for plain BFF. - `bookingMethod` — NOT normalized: may be a product name ("BookIt Links" / "BookIt for Forms" / "BookIt Handoff") OR a distribution strategy ("Pool Member" / "Specific User") OR null, depending on flow. Prefer `type` for the product question; use the pool fields below to determine distribution strategy. - `bookingChannel` — which client/surface created the booking: "mcp" (this MCP server), "api" (BookIt public API directly), "native" (scheduling page / handoff / other in-app flows), or null for historical rows predating this field. Distinct from `type` (product) and `bookingMethod` (distribution strategy). - `distributionMethod` — round-robin strategy used to pick the host - `isBookitInvite` — true if booked via BookIt Invite (email invite) - `singleUseLinkId` — populated for single-use scheduling links - `scheduledActionType` — Handoff-only: smart rep action type ### Status & timing - `status` — "Scheduled" | "Pending" | "Rescheduled" | "Canceled" | "Invalid" | null. "Pending" is Routing-Links-specific (routing in progress). Abandoned BFF routing → null + booked=false. "Invalid" = a credit request was filed; pair with creditBackStatus. - `booked` — boolean: was a calendar event actually created - `bookedDate` — when the row was booked (NOT when the meeting occurs) - `startTime` / `endTime` — ISO 8601 of the actual meeting start/end (derived post-query from event_info_json). Display-only — you CANNOT filter on these; the startDate/endDate params filter on `created_date` (booked/created time), not the meeting time. To find meetings *occurring* in a window (e.g. "what meetings does host X have next week"), pull a created_date range then post-filter on these. - `requiredHostIds` — SF user IDs required at the meeting - `schedulingPageShown` — was the calendar UI shown to the prospect - `meetingCounted` — does this count toward the org's meeting-count totals (used for usage tracking + meeting distribution). Does NOT affect meeting type daily/weekly limits. ### Pool / host selection - `poolId` — round-robin pool ID - `suggestedPoolMember` / `suggestedAs` — Handoff-only debug info - `allPoolMembers` — SF user IDs of every pool member at routing time - `poolMembersAvailabilityDisplayed` — which members were shown to the prospect - `poolMembersAvailableAtSelectedTime` — which members were available at the chosen slot ### Routing - `triggerNode` — which routing graph trigger node was used - `routingLogId` — FK to the structured routing log - `routingError` — error message from a failed routing (rare; BFF/Smart Links/Routing Links exceptions or email-send failures) - `redirectUrl` — populated when the BFF graph hit a "Redirect to URL" action ### Credit-back (set out-of-band when a credit request is filed, not by booking) - `creditBackStatus` — "pending" | "approved" | "denied" | "invalid" | null. Capitalized variants ("Pending", "Approved") also exist depending on write path — compare case-insensitively. - `creditBackReason` — freeform string, capped at 50 chars. Common values: "Canceled", "No Show", "Dupe Request". - `requestSentTime`, `requestReviewedTime`, `requestReviewerId` — credit-back review workflow ### External system linkage - `sfdcMeetingLogId` — SFDC Meeting_Log__c ID - `calendarEventId` — Google/O365 calendar event ID. The **original/stable** ID from the initial booking; does NOT change on reassignment. - `currentEventId` — the **live** calendar event ID. Equals `calendarEventId` at booking time, but if the meeting is reassigned to a new host the event is recreated on the new host's calendar and this updates to the new ID (while `calendarEventId` stays the original). Prefer this for the current event; the event tools (cancel/reschedule/availability) accept either ID. - `crmEventId` — SFDC Event ID - `bookitUniqueId` — shared correlation ID between bearoku's meeting_log and FuzzyMatcher's routing audit log (`Log__c`). FM's audit log holds the matched Lead/Contact/Account from BFF routing, so this ID is the join key between the booking row and the routing match results. Also serves as the upsert key on both sides for idempotency. ## Cross-product caveats (important) - **Dynamic Links rows** (SFDC-created, identified by `type='BookIt Links'` + `bookingMethod='Pool Member'`/`'Specific User'`) skip many fields normally always-set: bookedDate, calendarEventId, crmEventId, category. Filtering on those will silently exclude this flow. - **Routing Links rows in status='Pending'** are placeholder rows where routing is still in progress; ~80% of fields are null until the booking completes. - **Handoff-only fields** (`suggestedPoolMember`, `suggestedAs`, `scheduledActionType`) are always null for other products. - **Credit-back fields** are never set by booking flows; they're populated later by FuzzyMatcher when an admin files a credit request.
bookit_list_meeting_logs
List BookIt scheduling links. Scoping: - User scope: returns only "My Links" for the authenticated user. Requires a Salesforce-authenticated connection — machine (Agentforce) connections carry no user identity. A link is "mine" if the user owns it (top-level), is the assigned host on a child of a managed parent, or has explicitly added it from the Links Library. - Admin scope: returns all links in the org by default. Pass `myLinksFor` to apply the same My Links filter for a specific user, or `ownerUserId` for an owner-only filter. Embedded links are always excluded. Expired and deleted links are excluded by default. ## Returns Each link has: - `id`, `name`, `urlSlug`, `url` (full copyable scheduling URL — same as the copy-link button on the BookIt Links UI) - `linkType` — "default" | "multi_meeting_type" | "routing" - `isParent` / `parentId` — managed-parent + child relationship - `ownerUserId` — SF user ID of the link owner - `attendeeUserIds` — SF user IDs of hosts on the link - `meetingType` — { id, name } | null - `expirationDate`, `deletedDate`, `createdDate`, `lastModifiedDate`
bookit_list_links
Look up reference data by type. Supports fuzzy search by name or exact lookup by ID. Available types: - meeting_types: BookIt meeting type configurations (name, duration, category) - meeting_categories: Categories used to scope round-robin meeting counts. Returns id, name, meetingTypeCount, createdDate, lastModifiedDate. No detail mode. Use this to resolve a category ID for bookit_meeting_counts. - pools: Round-robin pools. Default response (search/list) returns name, type, isWeighted, memberCount (active members only), and productAccess. - users: BookIt users. Default response (search/list) returns identity, timezone, auth status, product access, isPaused, and `calendarEmail` (the BookIt-authorized calendar identity, may differ from the SFDC `email`). Use this to resolve names/emails to host IDs for bookit_preview_availability (hostIds) or bookit_list_meeting_logs (hostId). The `query` parameter matches case-insensitively against first_name, last_name, the SFDC email (`ld_user.email`), AND the calendar-authorized email (`customer_token.user_email` for type=calendar) — so searching by either email surface works. - invitable_users: Salesforce users who are eligible to be *added* to BookIt but don't have it yet. Returns `userId` (SF user ID), name, email, profile, `bookitStatus`, and `productAccess` ({ handoff, forms, links }). This is the candidate list to draw from when someone asks who can be given BookIt. Eligibility is active users holding a license the org has configured for BookIt, excluding anyone already fully set up. Filter with `status` to see where a candidate is in the invite lifecycle. For people who *already* have BookIt, use `type: users` instead — the two lists are disjoint. For pools, `detail: true` returns the pool config plus the active member roster (`{ userId, name, email, weighting }` per member) along with description, autoCalibrateNewMembers, audit timestamps, and lastModifiedBy. **Requires `id`** — cannot be combined with `query`. For users, `detail: true` returns a richer single-user view (calendar token connection, working hours, upcoming vacations, conferencing providers, links library, profile picture, phone, etc.) and **requires `id`** — it cannot be combined with `query`. `invitable_users` is answered by Salesforce rather than by BookIt, because a candidate has no BookIt record yet — whether they're eligible can only be judged from the CRM. Two consequences worth knowing: it is noticeably slower than the other types, and it needs a LeanData package version that includes the provisioning support. An org on an older package returns an explicit "does not support listing invitable users" error — that means the package needs upgrading, not that there are no candidates, so don't report it as an empty result. `id`, `detail`, and `includeInactive` do not apply to this type; `status` applies only to it. List responses include `{ total, returned, limit, offset, results }`. `limit` defaults to 50 and is capped at 500. Use `offset` to paginate when `total > returned + offset`. Narrowing `query` is usually a better strategy than paginating.
bookit_lookup
Aggregated meeting log analytics with flexible grouping. Use this for "how many", "what's the rate", "which X has the most" style questions. Returns counts (total, booked, canceled) and a booking_rate per group. Scoping: - User scope: aggregates only meeting logs where you are the main host. Requires a Salesforce-authenticated connection — machine (Agentforce) connections carry no user identity. The `hostId` filter is ignored under user scope (`groupBy=host` will return a single group — yourself). - Admin scope: aggregates all org meeting logs by default. Pass `hostId` to scope stats to a specific host. Examples: - "What's our booking rate this month?" → no groupBy needed (use summary) - "Which meeting type has the most cancellations?" → groupBy=meeting_type - "How are bookings trending week over week?" → groupBy=week - "Which host books the most meetings?" → groupBy=host (admin) For drill-down into specific meetings, use bookit_list_meeting_logs instead.
bookit_meeting_stats
Preview calendar availability for a meeting type without routing a prospect. Use this to check if a pool has enough slots, identify coverage gaps, or see which hosts are available. Specify the user set to compute over by providing **exactly one** of `poolId` or `hostIds`. Meeting types themselves don't dictate which — the choice reflects what you're previewing (combined availability across a pool vs. availability for a specific set of users). When `poolId` is provided, the response shows the combined availability of all pool members — each timeslot lists which pool member(s) are available. Meeting type limits (daily/weekly caps) and working hours are respected in both modes. Use bookit_lookup first to resolve names to a meeting type ID, pool ID, or user IDs as needed. **An empty `availability.timeSlots` does not mean nobody is free.** Read `searchRange` on the response before concluding that: it reports `horizonDays` (how far ahead was actually searched — `null` for meeting types on a custom date range, where the type's own `customRange` governs and `days` is ignored outright), `customRange`, `windowApplied`, and `daysParamIgnored`. A window sitting outside what the meeting type offers returns nothing no matter who is free, and `searchRange` is how you tell that apart from a full calendar. Each entry in `userIdToInfoMap` carries `hasReturnedSlots`. That map lists every host considered, including ones with no slots in the returned set, so do not read a host's presence in it as availability — check the flag. `hasReturnedSlots: false` means in scope but nothing free in the window.
bookit_preview_availability
Reassign a meeting to a new host, optionally at a new time. The source meeting can have been booked any way (pool, explicit user, links, etc.). Wraps POST /v1/event/:eventId/reassign-meeting, which runs the full reassign flow: calendar event update, count adjustments, reminders, Salesforce sync. The original host is removed and any additional hosts are preserved — promoting an existing additional host to main works and does not duplicate them. **Check availability first — whether the server does depends on whether you change the time:** - Keeping the time (no `newScheduledTime`): the backend conflict check is **skipped**, deliberately, because the event being updated would otherwise register as a conflict with itself. Nothing stops you double-booking the new host. Verify first with `bookit_preview_availability` using `hostIds: [candidate]` plus `startDate`/`endDate` set to this meeting's existing window — an empty result means that person is not free then. - Changing the time: the backend **does** check the new host's real calendar over the buffer-padded window and rejects a conflict with `time slot is booked`. Still cheaper to pick a slot from `bookit_preview_availability` than to guess. **Count behavior — two independent gates, not one:** - Credit-back to the original host requires the source meeting to have been counted (`meetingCounted=true`). - The new host's increment does **not** check that flag. It is evaluated independently against the org's counted-meetings setting and the destination pool. So a non-counted source can still increment the new host — the two are not symmetric. - `poolId` is what the increment is attributed to. Omit it and the source meeting's own pool is used. - The increment is an UPDATE of an existing count row, never an insert. A new host with no count row for that (pool, category) — i.e. someone who isn't a member of the pool — is silently **not** incremented, while the original host is still credited back. Reassigning outside the pool therefore loses a count org-wide. Verified live. **Behavior deltas from the internal handoff reassign UI:** - Pool membership is validated server-side when `poolId` is supplied (the UI relies on dropdown gating). - Additional-host editing, non-SFDC host editing, and calendar event overrides (title/description) are not exposed. Existing hosts and the existing description are preserved rather than being editable. Requires an SFDC-authenticated admin connection — machine (Agentforce) connections can't reassign because there's no SF user identity for the audit trail.
bookit_reassign_meeting
Remove users from every count-based BookIt pool they belong to. Mirrors "Remove from All BookIt Pools" on the users page BookIt tab. Only BookIt (`Object_Type__c = 'Meeting'`) pools are touched — routing pools are a separate action on the same page and are left alone. This does NOT deauthorize anyone or change product access; it only ends pool membership, so the user keeps BookIt and can still be booked directly or through links. Use `bookit_deauthorize_users` to revoke access entirely, or `bookit_edit_pool_members` to remove someone from one specific pool. **Meeting counts survive.** Removal leaves the `meeting_count` rows alone, so re-adding a user later restores their prior count rather than starting them at zero. Only deleting a whole pool clears counts. Note the round trip isn't perfectly lossless on a pool with `autoCalibrateNewMembers` on: the count comes back, but re-adding is a new-member event, so their calibration is recomputed against the pool average rather than restored. That's auto-calibration working as designed — just don't read "counts survive" as "nothing changes". `allowEmptyingPools` is a **deliberate delta from the UI**. The page warns that a removal will leave pools with no members and lets an admin click through; a pool with no members has nobody to distribute to, so anything pointing at it — a deployed graph, a scheduling link, a handoff — fails to assign. A warning in a tool response is not something an agent has to respect, so this refuses by default and names the pools that would be emptied. Pass true only after confirming with the user that emptying them is intended. Ordering is bearoku-first, then Salesforce, so a failure of the Salesforce half leaves the user unassignable rather than the reverse. A failure of the bearoku half aborts before anything is deleted. `idempotentHint: true` — a second call finds no memberships and reports every id under `notInAnyPool`.
bookit_remove_from_bookit_pools
Request credit-back for a meeting that has already happened or otherwise needs to be marked invalid (e.g. prospect no-show, wrong attendee, unqualified lead). Wraps POST /v1/mcp/event/:eventId/request-credit-back. Sets the meeting's status to Invalid, records the reason, and either auto-approves the credit (if the org has `autoApproveNoShow` enabled) or marks it pending for admin review. Mirrors to Salesforce. **Scope behavior:** - User scope (SFDC-authed): hostId is forced server-side to the authenticated user's SF ID — you can only request credit-back for meetings you hosted. Machine (Agentforce) connections are rejected (no user identity). - Admin scope: hostId is omitted from the payload; bearoku resolves the host from the meeting itself and allows the request regardless of who's calling. **Finding candidates**: use bookit_list_meeting_logs({ creditBackStatus: "none", status: "Scheduled" }) to surface meetings that ran but haven't been credit-backed yet. The `calendarEventId` field on each returned row is the `eventId` to pass into this tool. bookit_list_meeting_logs also exposes `meetingCounted` and `categoryId` so you can see at a glance whether the credit-back will actually refund a count (it only refunds if `meetingCounted=true && categoryId` is set). Throws "This event has already been requested credit back for" if a credit back is already in flight for this meeting. Throws "Forbidden: caller is not the host" if a non-admin caller tries to request credit back for a meeting they didn't host. For canceling a future meeting (which also triggers credit-back as a side effect), use bookit_cancel_meeting instead.
bookit_request_credit_back
Reschedule an existing BookIt meeting to a new time. Wraps PATCH /v1/meeting/:eventId. Call bookit_get_availability_for_meeting first to pick a valid alternate slot — this tool will throw "Validation Error" if the new time is outside the meeting type's allowed window or conflicts with host availability. Throws "Meeting has already been canceled" if the meeting was previously canceled.
bookit_reschedule_meeting
Inspect round-robin meeting counts for a (pool, category) — the per-member load that drives BookIt's "next up" routing decisions. Use this to debug "why is X getting more meetings than Y?" or "who's next in line for category Z in pool P?". Required: `categoryId`. Whether `poolId` is required depends on the org's distribution mode (returned as `countingMethod`): - `category` mode (default) — `poolId` is **optional**. Provide it to scope the member roster to a single pool; omit to see all valid bookit-authorized users in the org. Counts are aggregated across all pools per (user, category) regardless. - `poolAndCategory` mode — `poolId` is **required**. Counts are per (user, pool, category) and values are pool-scoped. Use `bookit_lookup` (`type=pools` and `type=meeting_categories`) to resolve names to IDs first. Each result row carries the raw fields used by the routing query plus a precomputed `netCount`: `netCount = count + calibration + automated_calibration + pool_automated_calibration - total_credits` (divided by weight_percent when a weighted pool is queried). Rows are sorted by `netCount` ascending then `lastAssignedDate` ascending — the top of the list is who BookIt would pick next. When no `poolId` is provided (category mode, org-wide view), each row omits `weighting` and the `pool` field on the response is `null`. `resetCadence` echoes the org's reset schedule so callers know the count window. Soft-deleted rows (members removed from the pool) are excluded. `detail: true` adds `editHistory` (audit trail of manual calibration edits), `lastReset`, `lastCalibrationDate`, `createdDate`, `lastModifiedDate`.
bookit_meeting_counts
Routes a prospect through LeanData's BookIt for Forms routing rules and, if a match is found, fetches available meeting timeslots for the matched owner(s) in a single call. REQUIRED PRECONDITION 1 — TRIGGER NODE: The `triggerNode` name is customer-defined and varies per org (admins name their own routing-graph nodes). The user must tell you which one to use. If they have not specified one, ASK — do not invent, guess, or default to a placeholder name like "New Webform Prospect". There is no canonical default. REQUIRED PRECONDITION 2 — FIELD KEYS: You MUST call bookit_retrieve_inputs first with the same triggerNode to discover the exact field keys this org's routing graph expects. Field names are configured per-customer and vary in casing/format (e.g. `FirstName`, `first_name`, `firstName`, `Email__c`) — do NOT guess them. Pass the prospect's data under the keys returned by retrieve_inputs, exactly as named. Mismatched keys will silently fail to route. REQUIRED INPUT — UID: You must supply `uid`, a unique correlation id for this routing request (see the `uid` field). It becomes the routing audit Log's join key in Salesforce and must be stamped onto the matched Lead/Contact by your downstream process to link them. Reusing a previously-used value overwrites the existing Salesforce Log — always use a fresh value. The response contains a routing object (who was matched) and a scheduling object (their availability) — scheduling will be null if no routing match was found or if the routing result was a redirect. The response also echoes back the `uid` you supplied. To complete the booking, pass the `routing.token` value from this response as the `params` argument to bookit_create_booking_forms — that token is the encrypted booking context (NOT the `routing.calendarLink` URL or its `link=` value).
bookit_route_and_fetch_availability
Route a prospect through a BookIt **Routing Link** and fetch availability for whoever they're routed to, in one call. Use this when you have a routing link. Use `bookit_route_and_fetch_availability` instead for BookIt for Forms routing, where an external system owns the prospect record. **No trigger node or field discovery needed.** The link already knows which routing-graph trigger node it enters and exactly which form fields it accepts, so unlike the Forms flow there is nothing to ask the user for and no preconditioning call. Resolve the link with `bookit_list_links` (routing links have type `routing`). **Pass `prospect` using the link's own field names.** Unknown field names are rejected rather than ignored — a silently dropped field would mean routing on incomplete data and looking successful. If you don't know the accepted names, call this once with a minimal `prospect` and the error will list them. **This can create or update Salesforce records.** Routing links commonly include a Create Record step that inserts a Lead as part of routing, and record-writing steps that are skipped for Forms routing are active here. Anything it writes follows that step's own field mapping, so the created record won't necessarily carry every field you passed. Treat it as a write against CRM data, not a lookup, and confirm with the user before routing a real person. **Multi-meeting-type routing links aren't supported here.** If the graph resolves to more than one meeting type the call fails with an explicit error; the product's own scheduler handles that case by handing off to a separate flow, which this API has no equivalent for. Not idempotent: each call routes afresh, mints a new correlation id, and round-robin may select a different host. There is no way to undo a route. Returns `routing` (who was matched, plus a `token` for booking), `scheduling` (their availability — null if no match or a redirect), and the `triggerNode`/`uid` that were resolved from the link.
bookit_route_link
How do I improve a ChatGPT Plugin's discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are LeanData MCP alternatives on ChatGPT?
As of 2026-09-29, LeanData MCP competes with Apptoto, Book with Schedulo, Cal.com, Calendesk, Calendly, Jicoo, OnceHub, Schemon in ChatGPT Meeting Scheduling & Booking, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.