MCP App Store
by KeenEthics

Overview

The Levitate app gives you natural language access to your relationship marketing platform. Search contacts and companies, view full profiles and activity timelines, add contacts, update details, and tag in bulk — all through conversation. Stay on top of your day: create, update, and complete action items, add and search notes, look up meetings on your connected calendar, and get AI summaries of your Zoom meetings. Work your inbox from Claude: search and read messages in your connected email account, draft or send replies, and organize messages into folders and categories. Run your marketing: find email templates, estimate audiences, and create, schedule, or cancel email campaigns. Draft and schedule social media posts to your connected accounts, and write, schedule, and publish blog posts. Collect and act on client information: create surveys, add questions, and review responses and event registrations. Upload files and analyze documents, browse shared files, and track client document checklists. Industry tools are available where your account uses them: track donations and fundraising campaigns, manage sales opportunities across pipeline stages, and review insurance policies by carrier and line of business.

Tools

action_items_complete

ChatGPT
Mark an action item as completed. Once completed, the action item's completion date is set to the current time. To reopen a completed action item, call action_items_update with isCompleted=false. Examples: - "Mark my follow-up call task as done" → provide the actionItemId - "Complete the proposal task" → provide the actionItemId Use action_items_search to find the action item ID first.

action_items_create

ChatGPT
Create a new action item (task, to-do, reminder, or follow-up) that can be assigned to users and associated with contacts. IMPORTANT: The assigneeId parameter and the response fields AssigneeId/CreatorId contain user IDs, not names. - To assign to yourself, omit assigneeId (defaults to current user) or call users_get_self first to get your user ID. - To assign to someone else, call users_search to find their user ID first. Examples: - "Create a task to call John next Friday" → provide description, contactId (from contacts_search), and dueDate - "Remind me to send a proposal by end of week" → provide description and dueDate - "Add an urgent follow-up task for the team lead" → provide description, assigneeId, and priority=High - "Log that I called Sarah yesterday" → provide description and a past dueDate, then call action_items_complete Due dates are normally in the future; a past date is accepted so completed work can be logged after the fact. Set hasDueTime=true only when the user named a specific time; otherwise the due date is treated as all-day. Priority is one of None, Low, Medium, High and defaults to None.

action_items_delete

ChatGPT
Permanently delete an action item. Prefer action_items_complete when the work was done; delete only when the item was created by mistake or is no longer relevant. Keep-in-touch reminders cannot be deleted. Use action_items_search to find the action item ID first.

action_items_get

ChatGPT
Get a single action item by ID, including its text, due date, priority, assignee, completion state, and referenced contacts. Use action_items_search to find the ID first when you only know what the task is about.

action_items_update

ChatGPT
Update an existing action item. Any combination of description, due date, assignee, priority, and completion state can change in one call; at least one field must be provided. Fields you omit are left unchanged. Examples: - "Move the follow-up task to next Friday" → provide actionItemId and dueDate - "Update the task description to include meeting notes" → provide actionItemId and description - "Hand this task to Sarah" → provide actionItemId and assigneeId (from users_search) - "Make the renewal task high priority" → provide actionItemId and priority=High - "Reopen the task I completed by mistake" → provide actionItemId and isCompleted=false - "Remove the due date" → provide actionItemId and clearDueDate=true Priority is one of None, Low, Medium, High. Past due dates are accepted. Use action_items_search to find the action item ID first.

blogs_cancel

ChatGPT
Cancel a blog post so it does not publish: an unscheduled draft, a scheduled post, or one held for compliance approval. A post that has already published cannot be taken down through this tool — do that in Levitate. Use blogs_search to find the blog ID.

blogs_create_draft

ChatGPT
Create a DRAFT blog post. The draft is never published by this tool: it stays unscheduled until blogs_schedule is called, and the account's compliance review still applies at that point. Read the levitate://blog-post-creation guide before using this tool. Content — pass the body as HTML (<h2>/<h3> subheadings, <p> paragraphs, <ul>/<ol> lists). Do NOT include the title as an <h1> in the body; the title is a separate field and the site renders it. ALWAYS show the user the title and the body and get their confirmation before creating the draft. Images — optionally attach one main/hero image: upload it with files_create_upload first, then pass its fileId as mainImage. Images inside the body must be added in Levitate.

blogs_get

ChatGPT
Get a single blog post by ID, including its status, schedule, slug, compliance state, and full HTML body. Use blogs_search to find blog IDs.

blogs_schedule

ChatGPT
Schedule a draft blog post to publish at the given future date, or reschedule one that has not published yet. ALWAYS confirm the exact date with the user before calling this tool — once the date arrives the post is published publicly on the account's blog. Leave confirm unset and the user is prompted to approve the post and date where the client supports it; re-issue the call unchanged with their answer. Pass confirm=true only when they have already agreed to this exact post and date. A response noting the user declined leaves any existing schedule untouched — do not retry it. Constraints: - The date must be at least ~15 minutes in the future, leaving a window to review and cancel. - Immediate publishing is not available through this tool. - On accounts with compliance review enabled, the post is routed through approval instead of being scheduled directly: it lands in Pending status and only publishes once the review is answered. Usually the approval goes to YOU (the caller), or to the account's compliance reviewer address where one is configured. A round raised on a broker-dealer account set up for officer filing is emailed to the firm's compliance officer instead, who submits it to the broker-dealer themselves, and a decline rejects the post; a post already pending with a Levitate approver before the account moved to officer filing stays with them. complianceReviewedByOfficer on the result says which holds this post. The recorded Levitate approver is a fallback for a filing that stalls or whose link expires, not the normal route — so a held post is not guaranteed to publish on its date. You cannot choose the reviewer from here; read the returned note for who holds it. - A Rejected, Cancelled, or Failed post cannot be revived here — handle those in Levitate. Use blogs_cancel to stop a scheduled or pending post before it publishes.

blogs_update

ChatGPT
Update the title, body, or main image of a blog post that has not published yet. Only the fields you pass are changed; omitted fields are left as they are (this tool cannot clear the main image — do that in Levitate). Editable only while the post is an unscheduled draft or a scheduled post that has not been through compliance review. A post that a reviewer has already approved or rejected, or that is currently awaiting review, must be edited in Levitate so it can be re-reviewed — this tool refuses it rather than quietly publishing unreviewed changes. Read the post with blogs_get first so you change only what the user asked for.

calendar_provider_get_meeting

ChatGPT
Fetch full details for a single meeting by provider meeting ID. Returns description, attendees with RSVP status and resolved Levitate contact IDs (when matchable), conferencing URL, and deep links. Use this after calendar_provider_search when you need attendee details or description content beyond the lightweight search result. When the meeting is not found or cannot be fetched, the response has Found=false and Meeting=null.

companies_get_timeline

ChatGPT
Return a company's activity timeline — notes, meetings, sent emails, phone calls, text messages, deals, and follow-ups — most recent first (up to 100 events). Use after companies_search to understand the history of interactions with a company. This is the company-level counterpart to contacts_get_timeline: it aggregates activity across the company (including its associated contacts), whereas the contact timeline is scoped to a single person. Each event includes its type, timestamp, a human-readable summary, and type-specific details (e.g. email subject and recipients, an action item's due/completion dates).

contacts_add_email

ChatGPT
Add an email address to an existing contact. Get the contactId from contacts_search or contacts_get_profile first. The contact's existing email addresses are always kept — this only adds. Set makePrimary to true when the new address should become the contact's main email (for example, when correcting a wrong primary address; the old one is retained as a secondary). If the email already belongs to a different contact this returns an error rather than creating a conflict.

contacts_add_phone

ChatGPT
Add a phone number to an existing contact. Get the contactId from contacts_search or contacts_get_profile first. The contact's existing phone numbers are always kept — this only adds. Optionally pass a label such as "Cell", "Work", or "Home".

contacts_add_tags

ChatGPT
Add one or more tags to a list of contacts. Use after searching to apply tags to matching contacts. Tag names that don't already exist are created automatically — this is how new tags come into existence, so use this tool to satisfy requests to "create a tag" or "make a new tag group" (there is no separate create-tag tool). Call tags_search first when you intend to reuse an existing tag, to avoid near-duplicates. Examples: - After searching donations, tag all donors with "2025 Gala Donor" - After finding contacts in a specific company, tag them with "Key Account" Returns a summary of how many contacts were successfully tagged and any failures.

contacts_create

ChatGPT
Create a new contact. Supply either both a first and last name, or an email address (at minimum one of those). The company is inferred from the email domain and visibility defaults to your account's default — do not pass them. To tag the contact, pass tags (maximum 10). Ground tag names with tags_search first so you reuse the account's existing tags (e.g. "VIP") instead of creating near-duplicates. Unknown tags are created automatically. If a contact with the given email already exists, this returns an error instead of creating a duplicate — fall back to contacts_search to find the existing contact and contacts_add_tags to tag it.

contacts_get_profile

ChatGPT
Return the full profile for a known contact — identity, key dates, tags, custom properties, and communication metadata.

contacts_get_timeline

ChatGPT
Return a contact's activity timeline — meetings, sent emails, notes, phone calls, text messages, action items, survey responses, e-signature activity (a document sent for signature, signed, declined, voided or expired, with the document title and any reason), and more — most recent first (up to 100 events). Use after contacts_search or contacts_get_profile to understand the history of interactions with a contact. Each event includes its type, timestamp, a human-readable summary, and type-specific details (e.g. email subject and recipients, an action item's due/completion dates).

contacts_update_details

ChatGPT
Update an existing contact's core details: first name, last name, and/or job title. Get the contactId from contacts_search or contacts_get_profile first. This is a targeted edit — only the fields you pass are changed; every field you omit (or leave blank) is left exactly as it was. This tool cannot clear a field; pass at least one non-blank value. Use it to correct a misspelled name or fill in a job title, not to change email or phone (use contacts_add_email / contacts_add_phone for those).

document_checklist_archive

ChatGPT
Archive a checklist item that should not have been on the list. It disappears from lists and summaries (unless includeArchived is requested) and can no longer be matched. To mark a document as not expected this period, prefer document_checklist_update with status Waived.

document_checklist_list

ChatGPT
List a contact's expected documents with their status: Open (still owed), Satisfied (a received file matched it, or a person confirmed it), Flagged (a received file probably matches; needs review — see matchedSharedFileId and shared_files_list), or Waived (no longer expected). Further files that match a resolved item outright (a second copy, the next invoice) are in additionalFiles. When the file is a bundle of several documents, matchedDocumentIndex (and additionalFiles[].documentIndex) names the document inside it: its index in that file's classification documents (see shared_files_list). Each file's revision (matchedRevision, additionalFiles[].revision) is Original, Corrected or Amended, or absent when unknown (a file recorded by hand, or one with no recorded revision — check shared_files_list before calling it an original); a corrected or amended copy arriving after the item was resolved puts it back to Flagged, because the figures changed — point the reviewer at that file. A voided form never matches an item. Optionally narrow to one period. Counts by status come back alongside the items, so this is also the per-contact progress check. Archived items are excluded unless includeArchived is true.

document_checklist_seed

ChatGPT
Record the documents a contact is expected to provide for a period (for example the tax year "2025"), typically seeded from what they provided last time. Each item names the document family (matched first), optionally the specific type and the issuer (matched second), and a label people will read. Items that duplicate a non-archived item (same family, type and issuer) are skipped and counted. Pass replaceOpen: true to archive the contact's still-open items for the period first, so the new list replaces the old one; satisfied, flagged and waived items are always kept. Once seeded, inbound files the contact uploads are classified (when the account has file classification on) and matched against these items automatically: a confident match marks the item Satisfied, a weaker or ambiguous one marks it Flagged for review. Use contacts_search to find the contact id.

document_checklist_summary

ChatGPT
For every contact carrying a tag (for example "Tax-Prep"), report where their checklist stands for a period: counts of Open, Satisfied, Flagged and Waived items plus the labels still open and the labels flagged for review. Contacts with hasChecklist: false have never been seeded. This is the daily progress view and the input for reminder outreach: open labels are what to ask for. Pagination: up to 100 contacts per page, sorted by name. Pass nextCursor back as cursor.

document_checklist_update

ChatGPT
Change an expected document: fix its label, family, type, issuer or period; add notes; or set its status by hand — Satisfied (confirm a flagged match or record a document received outside Levitate), Waived (no longer expected), Open (reopen; clears any match), or Flagged. Pass matchedSharedFileId to record which shared file satisfied it. At least one field is required. Use document_checklist_list to find the item id.

email_campaigns_cancel

ChatGPT
Cancel a queued or scheduled email campaign so it does not send (emails already sent are unaffected). Use email_campaigns_search to find the campaign ID.

email_campaigns_create

ChatGPT
Create an email campaign AND schedule it to start sending after startDate, in one step. There is no unscheduled "draft" state: a campaign created here is committed to send (subject to the lead time below, and to compliance approval when the account requires it). Use email_campaigns_cancel to stop it before it starts. ALWAYS confirm the subject, body, audience, AND the exact start date with the user before calling this tool — once the start date arrives it sends real email to real contacts. The required lead time guarantees the creator gets Levitate's day-before reminder and a window to cancel, but that is a safety net, not a substitute for confirming first. This is the DEFAULT way to email contacts through Levitate: sends are logged on each contact's timeline, tracked (opens, replies, clicks), and honor the account's compliance, approval, and unsubscribe rules. Do NOT use email_provider_send / email_provider_create_draft for contact outreach — those bypass Levitate entirely and are reserved for when the user explicitly asks to send directly from their own mailbox. Read the levitate://email-campaign-creation guide before using this tool. Start date (required, ISO 8601, e.g. '2026-06-10T14:00:00Z'): - Immediate sends are not available; the date must be in the future. - Self-sends require ~25 hours of lead time (so the creator receives the day-before reminder and can cancel). - On-behalf sends require the account's send-on-behalf wait time (default 2 days). - A too-early date is rejected with the earliest allowed value. To preview the projected send window for a large audience before committing, you can create it, then call email_campaigns_estimate / email_campaigns_get, and email_campaigns_cancel if the user changes their mind (the lead time leaves ample room). Audience — provide exactly one of: - recipients: an explicit list of contacts (max 500), each {contactId, optional subject, optional htmlBody}. Use contacts_search to find IDs. - filter parameters (tags / companyName / location / lastCommunicatedDateRange): resolved the same way as contacts_search. Use contacts_search with the same parameters first to preview who will be targeted. Content — provide htmlBody, or templateId to start from an existing template (htmlBody then overrides the template body if both are given). Signature — optional, and never added unless asked for. signatureTemplateId is exactly one of "default" (the sender's default Levitate signature), an id from email_signatures_list, or "none". Unset means no signature. A value that doesn't resolve to one of the user's signatures is rejected, never swapped for another. Exceptions: an on-behalf campaign always carries the on-behalf sender's default (accepts only "default" or unset), and an HTML newsletter never carries one (accepts only "none" or unset). Never write a signature into htmlBody. Attachments — optionally attach files (PDFs, images, etc.). Upload each with files_create_upload first, then pass its fileId in attachments; the bytes never pass through this tool. Combined size must stay within the user's email provider per-message limit. To make an image appear inline in the body, embed it in the HTML instead — attachments are sent as downloadable files. Per-contact customization — the campaign-level subject/htmlBody are the default for everyone. To tailor a specific recipient (a bespoke sentence for a VIP, a different opening), set subject and/or htmlBody on that entry in recipients; it overrides the default for that contact only. This is for variation that ISN'T expressible as a merge placeholder — for "insert each person's first name", use a {{placeholder}} in the default body instead of customizing every recipient. Per-contact customization is only available with the explicit recipients audience, not the filter audience. Personalization — you may insert merge placeholders in the subject and body (campaign-level OR per-contact) using {{placeholder}} syntax, written as plain text (e.g. "Hi {{first name}},"); each is filled in per recipient at send time. Call email_placeholders_list for th…

email_campaigns_estimate

ChatGPT
Dry-run a campaign send to preview the audience size and the projected send window before scheduling. The projection accounts for the account's daily send limits (large campaigns are spread across days), business hours, and holidays. ALWAYS call this before email_campaigns_schedule: the response includes minimumAllowedStartDate, the earliest start date the schedule tool will accept for this campaign, so you can propose a valid date the first time. Nothing is sent or scheduled by this tool.

email_campaigns_get

ChatGPT
Get a single email campaign by ID, including its status, schedule, audience size, engagement stats, the campaign-level HTML body, and which contacts have per-contact overrides. Use email_campaigns_search to find campaign IDs.

email_campaigns_schedule

ChatGPT
Reschedule an existing email campaign that has not started sending yet — move its start date earlier or later. New campaigns are created already-scheduled by email_campaigns_create; use this only to change the start date of a campaign that is already queued (or to (re)apply a date to a campaign created in the Levitate UI). ALWAYS confirm the exact start date with the user before calling this tool — once the start date arrives the campaign sends real emails to real contacts. Leave confirm unset and the user is prompted to approve the campaign and start date where the client supports it; re-issue the call unchanged with their answer. Pass confirm=true only when they have already agreed to this exact campaign and date. A response noting the user declined leaves the existing schedule untouched — do not retry it. Constraints (also returned by email_campaigns_estimate as minimumAllowedStartDate): - Immediate sends are not available through this tool. - Campaigns the current user sends themselves require at least ~25 hours of lead time, which guarantees the creator receives Levitate's day-before reminder notification and has a window to cancel. - On-behalf campaigns require the account's send-on-behalf wait time (default 2 days). - Campaigns pending compliance approval keep their hold; the schedule takes effect once approved. When complianceReviewedByOfficer is true on the result, that approval is the firm's compliance officer's and no Levitate user holds one; when false, a Levitate approver holds it — including a campaign raised before the account moved to officer filing. Relay the returned note. Use email_campaigns_cancel to stop a scheduled campaign before its start date.

email_placeholders_list

ChatGPT
List the merge placeholders you can use in an email subject or body (including per-contact overrides). Each is replaced per recipient at send time. Write them as plain text (e.g. "Hi {{first name}},") — do not hand-author placeholder HTML. Any {{...}} not in this list, or malformed, is rejected when you create a campaign, so check here rather than guessing.

email_provider_create_draft

ChatGPT
Create a draft email in the user's connected email provider. The draft lands in their Drafts folder — it is NOT sent. The user must review and send it themselves from their email client. Returns the provider draft id and a web link (when available). Note — drafts created here live only in the user's mailbox and are not logged or tracked in Levitate. For outreach to contacts that should appear on their Levitate timeline (with open/reply tracking and compliance handling), use email_campaigns_create instead; reserve this tool for when the user explicitly wants a draft in their own email client. Supported on Gmail, Microsoft 365 (Outlook), and on-prem Exchange (EWS); IMAP and SMTP-only providers return an error. WebLink: Outlook links directly to the draft. Gmail links to the Drafts folder of the user's default Google account in their browser — Gmail's API has no per-draft URL, and the link can land on the wrong account if the user has multiple Google accounts signed in. Exchange returns no web link. Provide at least one of: a recipient (to/cc/bcc), a subject, or a body. Optional inline attachments (base64) may be supplied; combined size is capped at the maximum message size the user's email provider allows. They are passed through to the provider with this draft only and are NOT persisted to Levitate. Signature — optional, and never added unless asked for (the mailbox does not add one either). signatureTemplateId is exactly one of "default" (the user's default Levitate signature), an id from email_signatures_list, or "none". Unset means no signature. A value that doesn't resolve to one of the user's signatures is rejected, never swapped for another. Never write a signature into the body. Citations — when the email is written from a Levitate template (email_templates_get), pass its id as templateId: a {{citations}} merge field in the body or signature is then filled with that template's vetted citations. Without templateId, or when the template has none, the field is removed. Never write citations yourself.

email_provider_draft_reply

ChatGPT
Saves a threaded reply as a DRAFT in the user's mailbox without sending it, so they can read it over and send it themselves. Prefer this over email_provider_reply whenever the user has not clearly asked for the reply to go out immediately. Replies cannot add the user's Levitate signature. Do not write one into the body; tell the user instead. Pass a providerMessageId from email_provider_search or email_provider_get_message. Recipients are derived from that message exactly as with email_provider_reply: replying to a message the user SENT addresses the people it was sent to, as following up on it in a mail client would. Not every mailbox can do this: IMAP and SMTP connections have no drafts at all, and Microsoft 365 needs the user to have granted mailbox write access. Call email_provider_reply_capability first when unsure; a refusal here explains which of the two applies.

email_provider_get_message

ChatGPT
Fetch full email message details (including body content) from the user's connected email provider. Primary usage: Pass providerMessageIds from email_provider_search results for direct message retrieval. Fallback usage: Pass contactId with a date range to search for messages (slower, less precise). This retrieves content directly from the provider (Gmail, Outlook, Exchange), NOT from Levitate bulk emails or campaigns.

email_provider_list_categories

ChatGPT
List the categories defined in the user's Outlook mailbox — the valid names to pass to email_provider_set_categories, and the ones their existing Outlook rules can match on. MICROSOFT 365 / OUTLOOK ONLY; other providers return an error. Reading the category list needs its own mailbox permission, granted by the same one-time reconnect email_provider_set_categories describes — if the user has not granted it, the error says so and names the link. Treat that as a permission problem to report, NOT as "this mailbox has no categories". Call this before setting categories rather than guessing a name. An empty list from a successful call means the user has genuinely defined no categories yet.

email_provider_list_folders

ChatGPT
List every folder in the user's Outlook mailbox that email_provider_move_message can move mail into, nested folders included, each with its id and full path (e.g. "Inbox/Clients"). Deleted Items and Outbox are left out because they cannot be move targets. MICROSOFT 365 / OUTLOOK ONLY; other providers return an error. Needs no extra permission beyond the user's existing email connection. Call this before moving rather than guessing a folder name, and pass the path or id it returns.

email_provider_move_message

ChatGPT
Move a message in the user's mailbox into another existing folder — how a triage classification gets mail that has already arrived filed. Outlook rules only run on delivery, so setting a category on mail already in the mailbox does not move it; this does. MICROSOFT 365 / OUTLOOK ONLY. Gmail, on-prem Exchange, and IMAP/SMTP mailboxes return an error. Requires the same one-time reconnect for mailbox write permission as email_provider_create_draft — if the user has not granted it, the error says so and names the link. Pass providerMessageId from email_provider_search or email_provider_get_message, and destinationFolder as a folder id or full path from email_provider_list_folders (e.g. "Inbox/Clients"). Prefer the id, especially when filing many messages: it resolves directly, while a path or name re-reads the whole folder list on every call. A bare folder name works only when no other folder shares it. The folder must already exist; this never creates one, and Deleted Items and Outbox cannot be targeted. The moved message gets a NEW providerMessageId, returned here — use it for any later call on that message. A NotFound error can mean the message was already moved, including by an earlier attempt of this same call.

email_provider_reply

ChatGPT
Replies to a message in the user's connected mailbox, INSIDE the conversation it belongs to. Use this, not email_provider_send, whenever answering a message the user received. email_provider_send starts a brand new conversation, so a reply sent that way reaches the recipient detached from the thread they started. Replies cannot add the user's Levitate signature. Do not write one into the body; tell the user instead. Pass a providerMessageId from email_provider_search or email_provider_get_message. Recipients are derived from that message rather than supplied: replyAll=false (the default) answers the sender alone, and replyAll=true also copies everyone on the original's To and Cc, minus the user themselves. Following up on a message the user SENT addresses the people it was sent to rather than the user, so the default is the right setting there too. Mailbox differences, which email_provider_reply_capability reports up front: - Microsoft 365 / Outlook quotes the original itself and cannot attach files to a reply. - Gmail, Exchange and IMAP send the body as composed and can attach files. The user is asked to confirm before anything is sent, and the prompt names the resolved recipients, because on a reply they come from the message rather than from this call.

email_provider_reply_capability

ChatGPT
Reports whether the user's connected mailbox can reply inside an existing conversation, and what a reply can carry there. Call this before promising a reply with an attachment or exact formatting. Supported=false means email_provider_reply will refuse for this mailbox; say so rather than falling back to email_provider_send, which would reach the recipient as a detached new message.

email_provider_send

ChatGPT
Send an email immediately from the user's connected email provider (Gmail, Microsoft 365 / Outlook, Exchange, IMAP/SMTP). The message is sent on the user's behalf from their own mailbox and CANNOT be unsent. IMPORTANT — this BYPASSES Levitate: the send is not logged to any contact timeline, gets no open/reply tracking, and skips Levitate's compliance, approval, and unsubscribe handling. Default to the email_campaigns_* tools for any outreach to contacts; use this tool ONLY when the user EXPLICITLY asks to send directly through their email provider (e.g. "send it straight from my Outlook", "don't log this in Levitate"). When in doubt, ask the user which they want. Prefer email_provider_create_draft when the user should review the message before it goes out; only send directly when the user has clearly asked for the email to be sent. Confirmation: leave confirm unset and the user is prompted to approve this exact send where the client supports it — re-issue the call unchanged with their answer. Pass confirm=true only when the user has already agreed to these exact recipients and subject. A response with sent=false means they declined; do not retry it. Requires at least one recipient (to, cc, or bcc) and a subject or body. A single send is limited to 10 recipients across to, cc, and bcc — this tool is for individual messages, not bulk mail. For multiple contacts or any campaign-style outreach, use email_campaigns_create instead. Optional inline attachments (base64) may be supplied; combined size is capped at the maximum message size the user's email provider allows. They are passed through to the provider with this send only and are NOT persisted to Levitate. Signature — optional, and never added unless asked for (the mailbox does not add one either). signatureTemplateId is exactly one of "default" (the user's default Levitate signature), an id from email_signatures_list, or "none". Unset means no signature. A value that doesn't resolve to one of the user's signatures is rejected, never swapped for another. Never write a signature into the body. Citations — when the email is written from a Levitate template (email_templates_get), pass its id as templateId: a {{citations}} merge field in the body or signature is then filled with that template's vetted citations. Without templateId, or when the template has none, the field is removed. Never write citations yourself. Returns the RFC message id and provider message id when the provider reports them. The sent message lands in the user's Sent folder, so it appears in email_provider_search results like any other sent mail.

email_provider_set_categories

ChatGPT
Add, remove, or replace Outlook categories on a message already in the user's mailbox. Categories are the hook the user's own Outlook rules match on ("assigned to category"). This tool never moves or deletes anything, and the routing map stays in Outlook where the user can edit it. Outlook rules only run when mail arrives, so a category set on mail already in the mailbox will not trigger a rule; to file that mail, use email_provider_move_message. MICROSOFT 365 / OUTLOOK ONLY. Gmail, on-prem Exchange, and IMAP/SMTP mailboxes return an error; there is no Gmail-label equivalent. Requires a one-time reconnect to grant mailbox write permission — if the user has not granted it, the error says so and they reconnect at the link given, then the call can be retried. Pass providerMessageId from email_provider_search or email_provider_get_message. Prefer names from email_provider_list_categories. A name that is not in that list still applies to the message, but Outlook shows it unstyled and no existing rule will match it, so a typo silently does nothing useful. Returns the message's FULL category set after the update, which for add/remove includes categories that were already there.

email_signatures_list

ChatGPT
List the email signatures the current user has set up in Levitate, with their HTML and which one is the default. Signatures are optional: email_campaigns_create, email_provider_create_draft and email_provider_send add one only when signatureTemplateId is an id from this list or "default" (the entry marked IsDefault); "none" or unset adds none. An empty list means the user has no signature, so "default" would be rejected — leave signatureTemplateId unset.

email_templates_get

ChatGPT
Get a single email template by ID, including its full HTML content. Use email_templates_search to find template IDs.

files_analyze

ChatGPT
Read an uploaded file and answer a question about it — classify it, describe it, extract what it is about — without the file's contents ever passing through this conversation. Upload the file with files_create_upload first, POST its bytes, then pass the fileId here. How it works: the file's text is extracted server-side (PDF text layer, with OCR for scanned pages; OCR for images; Word .docx; Excel .xlsx/.xls; plain text, CSV, TSV, Markdown and JSON), sensitive values are redacted before any model sees it, a model answers the prompt, and the upload is deleted. maxPages limits how many pages of a PDF or sheets of a workbook are read: with a prompt the default is 3 and the most is 10, and the text is capped at the first 20,000 characters; without one (classification) the default and the most are 100, and every page is read. pagesRead and totalPages report the coverage, truncated is true whenever part of the document went unread, and unreadablePages lists PDF pages OCR could not read at all. totalPages is null for Word files, which have no fixed pages until rendered. The answer is all that comes back — never the document text. Redaction always runs and removes Social Security and tax id numbers, account, card and routing numbers, credentials, email addresses, and every other number except tax years, tax-form names (W-2, 1099-INT, K-1) and one- or two-digit box/line numbers; names and postal addresses are not redacted. Markers [REDACTED] and [NUMBER] show where. So this tool can say what a document is and who issued it, but it cannot report amounts or account numbers. Omit prompt for the built-in classification. A file often holds several documents (a client's whole year of tax forms scanned into one PDF), so the answer is a JSON object {"documents": [...]} with one entry per document in page order, each with startPage and endPage (null for files without pages), documentType, documentFamily, issuer, period, description, suggestedFileName (YYYY-MM-DD <description>), confidence, and revision (Original, Corrected, Amended or Void — read from the form's CORRECTED/VOID box, a W-2c, or an Amended K-1; Original when there is no mark or it can't be read). An entry whose documentType is null covers pages too garbled to identify. Otherwise prompt is free-form (up to 4,000 characters) and responseFormat chooses text (default) or json. deleteAfter (default true) removes the upload once analyzed, so reuse the fileId only when you passed false. Files over 25 MB, and types other than those listed, are rejected. Requires the account's AI features to be enabled.

files_create_upload

ChatGPT
Begin uploading a file. Returns an uploadUrl and a single-use uploadToken. Upload the raw file bytes with a single HTTP POST to uploadUrl, sending header Authorization: Bearer <uploadToken> (and optionally X-Content-Sha256: <hex sha256> for an integrity check). The body must be the file's raw bytes: set Content-Type to the file's MIME type, application/octet-stream, or omit it. Never send multipart/form-data; it is rejected. The bytes travel over ordinary HTTP — never paste file contents into this tool. On success the file is identified by the returned fileId, which you pass to file-aware tools — an email attachment (email_provider_* / email_campaigns_create_draft), an image on a social post (social_posts_create_draft), or a blog post's main/hero image (blogs_create_draft / blogs_update). Uploads are transient and expire automatically, so create the upload shortly before referencing it. The token is good for one upload and then expires.

files_get

ChatGPT
Return metadata for an uploaded file by id, including a short-lived signed download URL for ready files. Does not return the file bytes.

notes_create

ChatGPT
Create a new text note associated with a specific contact. Use this tool to: - Add notes, observations, or comments about a contact - Record meeting notes, phone call summaries, or conversation details - Log follow-up reminders or next steps - Document interactions, touchpoints, or relationship history The note is automatically linked to the specified contact and appears in their timeline.

notes_update

ChatGPT
Update the text content of an existing note while preserving all associated contacts and metadata. Use this tool to: - Update note content with new information or corrections - Modify existing observations or meeting notes - Edit follow-up details or action items within notes - Add additional context to existing notes Only the text content is modified - creation date, referenced contacts, and relationships remain unchanged.

opportunities_boards_list

ChatGPT
List all opportunity boards and their stages. Call this first to discover board IDs and stage names before searching opportunities. Returns all boards with their stages, including deal size rollup data (total and average) per stage.

shared_files_list

ChatGPT
List the files exchanged with a contact through Levitate: documents the contact uploaded via a file request, survey or text (direction Received) and files sent to them (Sent). An executed e-signature document is filed as Received with origin SigningRequest: it is the sealed copy of a document the contact signed, not something they uploaded. Origin Upload means a staff member added the file to the contact directly; it has direction None, so filtering by either direction leaves it out. Origin ClientPortal means the contact uploaded the file through their client portal on their own, not in answer to a file request; it is Received. Each entry carries the file name and size, how it arrived (origin), and — when the account has automatic file classification enabled — a classification for inbound files: status (Classified, Skipped, Failed), documentType, documentFamily, issuer, period, a one-line description, a suggested file name, a confidence, and a revision: Original, Corrected (a 1099 with its CORRECTED box checked, or a W-2c), Amended (a K-1 marked Amended) or Void (a 1099 the issuer voided; it never satisfies a checklist item); absent when unknown (not classified, or classified before revisions were recorded). A file that holds several documents (a scanned bundle of tax forms) also carries documents: one entry per document with its index, startPage/endPage and the same fields, plus Skipped entries (with a reason) for pages that could not be read or lay past the 100-page limit; pagesRead/totalPages give the coverage, and the top-level fields then describe the first document. Classification is always produced from redacted text, so it carries no identifiers or figures from the document (names can appear). Use direction to see only what the contact sent. Pagination: up to 50 files per page, newest first. Pass the response's nextCursor back as cursor to get the next page; the cursor is opaque, not an offset. Use contacts_search to find the contact id.

social_connections_list

ChatGPT
List the current user's connected social media accounts/pages (Facebook, Instagram, LinkedIn). Call this BEFORE social_posts_create_draft: each entry's pageId is what you pass as a target's pageId. Only accounts with state Connected can publish. An account that is Disconnected, NoTarget, or whose token has expired must be reconnected by the user in Levitate first — surface that to the user rather than trying to post to it. A Facebook/Instagram account with an authFailureReason is being rejected by Meta even if it still shows Connected: tell the user what to fix (for CheckpointRequired/AccountUnconfirmed, log in at facebook.com first; otherwise reconnect in Levitate) before drafting a post to it.

social_posts_cancel

ChatGPT
Cancel a scheduled or pending social post so it does not publish. An unscheduled draft is deleted; a scheduled or pending post is marked Cancelled. Posts that have already started or finished publishing cannot be cancelled. Use social_posts_search to find the post ID.

social_posts_create_draft

ChatGPT
Create a DRAFT social media post. The draft is never published by this tool: it stays unscheduled until social_posts_schedule is called, and account rules (compliance review) still apply at that point. Read the levitate://social-post-creation guide before using this tool. Targets — provide one or more pages from social_connections_list, each {provider, pageId}. Every target must be a Connected account the current user owns; an unknown or disconnected page is rejected. Content — plain text. The limit depends on the platforms targeted: Instagram 2,200, LinkedIn 3,000, Facebook 63,206; a post going to several is bound by the strictest of them. Do NOT include the user's social signature or any required disclosure; those are appended automatically at publish time. ALWAYS show the user the content and the target pages and get their confirmation before creating the draft. A Facebook Page mention is written inline as {{@Page Name|PAGE_ID}}; only Facebook tags the Page, Instagram and LinkedIn publish the name. Images — optionally attach images, up to 10 for Facebook and Instagram and 20 for LinkedIn, a post going to several being bound by the strictest (no video; add video in Levitate). Upload each image with files_create_upload first, then pass its fileId here. Instagram REQUIRES at least one image: an Instagram target with no image is created as a draft but is rejected at schedule time, so attach an image here (or in Levitate) before scheduling it.

social_posts_get

ChatGPT
Get a single social media post by ID, including its status, schedule, target pages with per-platform publish state, the post body, and engagement stats. Use social_posts_search to find post IDs.

social_posts_schedule

ChatGPT
Schedule a draft social post to publish at the given future date, or reschedule one that has not published yet. ALWAYS confirm the exact date and the target pages with the user before calling this tool — once the date arrives the post is published publicly to the connected accounts. Constraints: - The start date must be at least ~15 minutes in the future, leaving a window to review and cancel. - Immediate publishing is not available through this tool. - On accounts with compliance review enabled, the post is routed through approval instead of being scheduled directly: it lands in Pending status and only publishes once the review is answered. - Who reviews it depends on the post's review round. Usually a Levitate user approves it in the app. A round raised on a broker-dealer account configured for officer filing is emailed to the firm's compliance officer instead — they submit it to the broker-dealer themselves, no Levitate user holds an approval, and if they decline the post is cancelled rather than published. A post already pending with a Levitate approver before the account moved to officer filing stays with that approver. complianceReviewedByOfficer on the returned post says which holds it; relay it rather than assuming an in-app approval. Use social_posts_cancel to stop a scheduled or pending post before it publishes.

surveys_custom_create

ChatGPT
Create a new custom survey shell with branding, an optional date window, and per-field contact-info requirements. This creates the survey but does not add any questions — use surveys_question_add for that, in the order they should appear. Read the custom_survey_creation resource (levitate://custom-survey-creation) before calling — it explains the two-phase create-then-add-questions flow, the three-state contact-info model, and how to wire question-visibility branching using IDs returned from prior calls. Returns the newly created survey's ID. Hold on to it — every surveys_question_add call needs it. The new survey emails its creator on every response. That is on by default and no parameter here changes it — say so once when you confirm the survey is created, and point anyone who wants it off at the survey's settings in the Levitate web app. Requires the account's Surveys feature. If it is off, this fails with "Surveys aren't enabled on this account" — relay that to the user rather than retrying or working around it, and do not start the question-design conversation until it is on.

surveys_question_add

ChatGPT
Add a single question to a custom survey. Call once per question, in the order the questions should appear — there is no reordering tool. Read the custom_survey_creation resource (levitate://custom-survey-creation) before calling. Key rules: - DropDown and CheckBoxes questions REQUIRE the options parameter (the choices, in display order). - All other types (ShortAnswer, LongAnswer, YesNo, FileUpload, LinearScale, Nps) MUST NOT pass options. - LongAnswer is a multi-line free-text answer (use it instead of ShortAnswer when a paragraph is expected). - YesNo renders a single yes/no choice; it takes no options. - LinearScale is a numeric scale question (Google-Forms style, e.g. 1–5); Nps is the standard 0–10 Net Promoter Score question. Both render as a numeric scale with no options — the scale bounds/end-labels use standard defaults and are not configurable from this tool. - visibleWhen makes the question conditional on an earlier DropDown or CheckBoxes question's answer. Source the controllingQuestionId and optionIds from the response of an earlier surveys_question_add call — never guess them. Returns the new questionId and, for DropDown/CheckBoxes, the persisted option labels and their optionIds. Hold on to those — later surveys_question_add calls reference them when wiring visibleWhen branching.

users_get

ChatGPT
Return a user's profile by their ID. Use this to resolve user IDs (e.g. AssigneeId, CreatorId from action items) into display names.

users_get_self

ChatGPT
Return the current authenticated user's profile (ID, name, email, role). Call this FIRST when the user refers to themselves with "my", "me", "I", "mine". Use the returned ID as assignedTo in action_items_search.

zoom_summarize_meeting

ChatGPT
Generate an AI summary of a recorded Zoom meeting the user held with a specific contact, and return a link to the source Zoom recording. It finds the meeting with the contact on the user's calendar and pulls that meeting's Zoom transcript: directly when the calendar event used a unique (per-booking) Zoom link, or — for a generic/personal link — from the recording closest in time to the calendar event. Requires the user to have connected Zoom AND granted the optional recording/transcript permissions; otherwise the call fails with a message explaining how to enable it.

action_items_complete

Claude

action_items_create

Claude

action_items_delete

Claude

action_items_get

Claude

action_items_update

Claude

blogs_cancel

Claude

blogs_create_draft

Claude

blogs_get

Claude

blogs_schedule

Claude

blogs_update

Claude

calendar_provider_get_meeting

Claude

companies_get_timeline

Claude

contacts_add_email

Claude

contacts_add_phone

Claude

contacts_add_tags

Claude

contacts_create

Claude

contacts_get_profile

Claude

contacts_get_timeline

Claude

contacts_update_details

Claude

document_checklist_archive

Claude

document_checklist_list

Claude

document_checklist_seed

Claude

document_checklist_summary

Claude

document_checklist_update

Claude

email_campaigns_cancel

Claude

email_campaigns_create

Claude

email_campaigns_estimate

Claude

email_campaigns_get

Claude

email_campaigns_schedule

Claude

email_placeholders_list

Claude

email_provider_create_draft

Claude

email_provider_draft_reply

Claude

email_provider_get_message

Claude

email_provider_list_categories

Claude

email_provider_list_folders

Claude

email_provider_move_message

Claude

email_provider_reply

Claude

email_provider_reply_capability

Claude

email_provider_send

Claude

email_provider_set_categories

Claude

email_signatures_list

Claude

email_templates_get

Claude

files_analyze

Claude

files_create_upload

Claude

files_get

Claude

notes_create

Claude

notes_update

Claude

opportunities_boards_list

Claude

shared_files_list

Claude

social_connections_list

Claude

social_posts_cancel

Claude

social_posts_create_draft

Claude

social_posts_get

Claude

social_posts_schedule

Claude

surveys_custom_create

Claude

surveys_question_add

Claude

users_get

Claude

users_get_self

Claude

zoom_summarize_meeting

Claude

Similar Apps