Findings on what compounds and supplements do in the body, with evidence strength, quote and paper.
- Passed: Handshake
- Passed: Tools listed
- Passed: Updated recently
Median latency 699 ms · Last checked
Explore
Evidence for your next connection.
Independent measurements of remote MCP servers. Every observation has a timestamp.
Read-only probesMCP server · Other
Make sure nothing falls through the cracks in your cleaning business, even when you're not watching.
3 failed · 8 not measured
Median of successful probes over 7 days
Share of countable probes over 30 days, including daily rollups. Auth challenges are excluded.
Tool definitions returned by this server
Independent monitoring
Responded
The server completed its last measured handshake. This is an observation, not a guarantee.
Last checked| Test area | Passed | Failed | Unmeasured |
|---|---|---|---|
ConnectionCan a client connect and discover tools? | 5 | 0 | 0 |
Reliability & speedDoes it respond consistently and quickly? | 0 | 0 | 4 |
Access & authenticationWhat is required to use this server? | 1 | 0 | 2 |
Tool qualityAre the tool definitions usable by an agent? | 3 | 1 | 0 |
Publisher identityCan the publisher be traced to its source? | 2 | 2 | 2 |
Unmeasured means there is not enough evidence to decide. How these checks work
Start using Sergio by Serviche
Choose your client, copy the configuration, then enable the server in your client’s MCP settings.
Run this command in your terminal, then restart Claude Code.
Claude Code
claude mcp add --transport http sergio-by-serviche https://sergio.serviche.com/api/agent/mcpCapabilities
Showing 100 of 109 tools.
Applies a booking sync Sergio held back for returning far fewer bookings than it holds, once, and makes that size the new normal, as Accept this smaller sync on Data sources does. job_id is the held sync's import job. Pass the same idempotency_key when retrying. An owner-level change: Sergio tells the owner after it is made.
DiscoveredAccepts a Sergio suggestion card, as the card's accept does. action "accept" commits it as a task (optionally with your edited title, details or due, ISO 8601 or null); "accept_no_task" resolves it without a task when the work already happened. A card whose move would send a message, move money, open to the public or grant access is refused with where the owner does it; draft instead (create_draft, or run_suggestion_now on a draft card). Pass the same idempotency_key when retrying; a repeat returns the first answer.
DiscoveredAdds an office note to a client's record (category general, access, preference, alert or scheduling; pinned keeps it surfaced). Only the team sees it; nothing is sent. Pass the same idempotency_key when retrying; a repeat returns the original note.
DiscoveredTo rename someone already on the roster, pass rename_staff_id with the new name; the old spelling keeps pointing at them. Otherwise adds a field worker to the roster, as the staff page's Add staff does: name (a profile with that name is reused, never duplicated), optional employment_type (employee or contractor), or client_id to make an existing contact staff (a name clash comes back as name_conflict; call again with link_to_staff_id to link instead). This gives them no sign-in; inviting someone to Sergio is the owner's. Nothing is sent. Pass the same idempotency_key when retrying.
DiscoveredAdds a plain-English scheduling rule for one field worker (staff_id), as Add rule on their Rules tab does, e.g. "Won't work Tuesdays" or "Only mornings in Brooklyn". hardness hard (default: never scheduled against it) or soft (avoided when possible). The same wording again updates the same rule. Answers the worker's rules with their ids. Remove one with remove_staff_scheduling_rule; read every rule with read staff_scheduling_rules. Pass the same idempotency_key when retrying. An owner-level change: Sergio tells the owner after it is made.
DiscoveredAdds a hand-written quiz question to one atom (sop_id) of a module, as Add question does (owner or admin seats only): question_text, two or more choices ({ key, text, is_correct }, one correct), explanation, optional image_url. A quiz question tests a lesson; it is not how to add new content to training: "add this to training" puts the text in a handbook article in the module (edit_training_module). Before adding anything to the handbook, search the sops read entity by the topic (search finds by meaning): when an article already covers it, put the new text into that article (edit_handbook_article with its full content_md, the new lines placed where they belong, or draft_handbook_edit) instead of a new one; create a new article only when none fits, and say which closest article you found and why it did not fit. Audience comes from the person's words: cleaner SOPs, cleaning standards or staff = cleaner; policies, office or VA = va; when the words do not say, ask in one line. Ask which place, in one line naming both, when two places fit the person's words equally well: two articles, or two training modules that both match (two new-hire modules are a tie whatever their status, draft or published); a place the person named outright is never a tie. The proposed change is the confirmation, so never ask "should I add this?" first. Pass the same idempotency_key when retrying; a repeat returns the same question.
DiscoveredSays which client wrote a Google review, as Contacts > Needs review does: client_id links it (also moving a review linked to the wrong client), client_id null says no client wrote it (unlinking a linked review). A link closes that client's review requests. Find reviews and their ids with read google_reviews. Nothing is sent or posted to Google. Pass the same idempotency_key when retrying.
DiscoveredAnswers or files a logged question (question_id from read entity sop_questions), as Handbook > Admin > Questions does: answer, status (open, answered, needs_new_sop, sop_updated, dismissed), sop_id it belongs to, notes. save_as_sop: true has Sergio write the answer into the handbook (the matching article, or a new one). Pass the same idempotency_key when retrying; a repeat does not save it to the handbook twice.
DiscoveredRecords the owner's approval of the lead journeys drafted from how the business follows up today, as Get started's follow-up step does. The journeys must already be saved as the answers draw them (answers: firstChannel, speed, followUpChannel, tries, overDays, giveUpDays; sources: the journeys approved, as lead sources such as site_thumbtack or web_form; Get started's lead sources map to them). Save the journeys first through the lead follow-up journeys setting (settings.lead_pursuit_program), drawn from these answers; otherwise the route answers journeys_not_saved. Writes no journey and sends nothing. Pass the same idempotency_key when retrying. An owner-level change: Sergio tells the owner after it is made.
DiscoveredTakes an article out of the handbook as its Delete does: it is marked inactive and kept (edit_handbook_article cannot bring it back; a person can). Pass the same idempotency_key when retrying.
DiscoveredArchives a training module as its Delete does (owner or admin seats only); it is kept and edit_training_module status draft brings it back. Pass the same idempotency_key when retrying.
DiscoveredAssigns a conversation to a teammate, as the thread header's Assign menu does: assigned_member_id is the teammate's id (read entity org_members), or null to unassign; assigned_to (the teammate's exact name) is accepted instead. A name that is not exactly one current teammate is refused. Pass the same idempotency_key when retrying.
DiscoveredAssigns a task to a team member (their member id from read('team_members') or whoami), or unassigns it with null. Pass the same idempotency_key when retrying; a repeat returns the task, reports what the original call applied, and changes nothing if the task changed since.
DiscoveredClears every thread older than a cutoff at once, as the inbox's bulk Clear does (owner or admin seats only): mode date clears threads quiet for olderThanDays (default 14) or since cutoff (ISO date); mode leads clears threads a lead follow-up owns. includeTasks also closes their open tasks; includeReplyOwed also clears threads the customer wrote last in (date mode). The Quo inbox follows when the business's write setting allows. Pass the same idempotency_key when retrying.
DiscoveredCancels a running import (message history or a spreadsheet), as Cancel in the import drawer does; what it already brought in stays. job_id comes from start_history_import or the import list. Pass the same idempotency_key when retrying.
DiscoveredReturns `asks`, a short list of things a person can ask (give your user these when they ask what you can do), then lists every tool this seat can call right now, grouped by family, with whether each one changes anything, and under `held` the actions only a person can do (sending, money, access), each with the reason and where in the app the owner does it, and under `not_lent` every other app action agents cannot do yet, with where a person does it.
DiscoveredClears one field worker's schedule change on a date (YYYY-MM-DD), so their normal weekly hours apply again, as Clear on the staff calendar does. To set a change, use set_staff_availability. Nothing is sent. Pass the same idempotency_key when retrying.
DiscoveredMarks a conversation's flow done, as the flow chip's Mark done does. conversationFlowId names the flow when the thread has more than one. outcome (for example declined) closes it early without marking its steps done; close_note is optional. Pass the same idempotency_key when retrying.
DiscoveredMarks a task done, recorded as completed by this seat. A flow-step task also completes its step, as the check box does. Pass the same idempotency_key when retrying; a repeat returns the task, reports what the original call applied, and changes nothing if the task changed since.
DiscoveredMarks up to 200 tasks done at once, as the Tasks page's selection bar does; each closes exactly as its own check box would. Kinds that close only from their own screen (lead follow-ups, flow steps, questions, staff check-ins, rules) are refused per task and reported in results. action "reopen" is the Undo. Pass the same idempotency_key when retrying; a repeat returns the first answer and moves nothing again.
DiscoveredBuilds a campaign as the Campaigns page's New campaign does, always saved as a draft: name, the messages (steps: the opener first, each { template, delayDays?, channel? text | email | call }), offer, audience (audience_filter, or audience_source { kind: list | view | people | filter }), caps and send window. Templates use Sergio's merge tags ({{Client First Name}}, {{User Company}}, {{Offer}}, {{Offer Expiry Date}} and the rest listed on steps.template), never a hard-coded business or client name. audience_filter takes the builder's own keys (visits, days since last booking, last booking total, days since last contact, frequency, services); audience_mode rolling (default) keeps adding people as they qualify (evergreen), fixed freezes the audience at start. read campaigns returns this vocabulary and existing campaigns to copy from. Sergio's audience rules apply unless your person asks otherwise, so leave those fields out: it leaves out anyone with an upcoming booking (audience_filter.noUpcomingBooking) and anyone another campaign reached lately (contact_floor_days, the business's window, 30 days unless changed), and new matches join on their own (audience_mode rolling). The people a rule leaves out show in the campaign as Excluded by Sergio, where a person can include one anyway, so another campaign running over the same people is not something to warn about. The answer's audience_rules says all this in one sentence: tell your person that sentence when you report the draft. A credit your person names is the offer the message describes (see offer_text); never ask them to apply credits. Nobody is enrolled and nothing is sent until it starts: start_campaign (your person sees every message first and says yes), or Start campaign in the app; turning on automatic sending stays the owner's. Pass the same idempotency_key when retrying; a repeat returns the same draft.
DiscoveredAdds a contact as the Add contact form does: a name, a phone (with area code) or an email is enough. contact_type picks client (default), lead, applicant, staff or other. A phone or email that already belongs to a contact is refused with that contact (duplicate_contact, its id in the message); use it, or pass createAnyway: true only for a different person who shares it (a shared phone then stays with its owner). Look a person up first with findClientByIdentifier or read. Pass the same idempotency_key when retrying; a repeat returns the contact the first call made.
DiscoveredMakes a contact list on the Contacts page, or answers the live one with that name. Add people to it with edit_contacts (op add_to_list). Pass the same idempotency_key when retrying.
DiscoveredMakes a tag on the Contacts page, or answers the live one with that name. Tag people with edit_contacts (op add_tags). Pass the same idempotency_key when retrying.
DiscoveredWrites a message into a client conversation's draft box. It never sends: a person on the team reviews the exact text and presses Send in Sergio, where the organization's sending policy applies. Give conversationId, or clientId to use that client's conversation. Pass the same idempotency_key when retrying; a repeat returns the original draft.
DiscoveredAdds an article (SOP) to the handbook, as Handbook > Admin > New SOP does: title, content_md (markdown), optional category, tags, audience (cleaner = staff, va = office), bucket (A, B or C), licensed (from a franchise or licensed manual: never shared outside the business). Nothing is sent. Before adding anything to the handbook, search the sops read entity by the topic (search finds by meaning): when an article already covers it, put the new text into that article (edit_handbook_article with its full content_md, the new lines placed where they belong, or draft_handbook_edit) instead of a new one; create a new article only when none fits, and say which closest article you found and why it did not fit. Audience comes from the person's words: cleaner SOPs, cleaning standards or staff = cleaner; policies, office or VA = va; when the words do not say, ask in one line. Ask which place, in one line naming both, when two places fit the person's words equally well: two articles, or two training modules that both match (two new-hire modules are a tie whatever their status, draft or published); a place the person named outright is never a tie. The proposed change is the confirmation, so never ask "should I add this?" first. A new article meant for training (new-hire training, onboarding) is also added to that training module's atom_order with edit_training_module, set to run after this. Pass the same idempotency_key when retrying; a repeat returns the same article.
DiscoveredSaves a new Scanner, as Save on New Scanner does: question (required), and optionally name, inputs, look-again timing, who gets the task, due rule, destination, contact types, and enabled (on or off; there is no trial mode). Pass the same idempotency_key when retrying. An owner-level change: Sergio tells the owner after it is made.
DiscoveredAdds a task to the team's work queue, optionally tied to a client or conversation and due at a time (ISO 8601). Pass the same idempotency_key when retrying; a repeat returns the original task.
DiscoveredCreates a DRAFT training module as Training > New module does (owner or admin seats only): title, description, atom_order (handbook article ids in lesson order; omitted = every active staff article, sorted by bucket). Nobody sees it until it is published. When the person names existing training ("add to our new-hire training"), read training_modules and edit that module instead; create one only when none fits. Before adding anything to the handbook, search the sops read entity by the topic (search finds by meaning): when an article already covers it, put the new text into that article (edit_handbook_article with its full content_md, the new lines placed where they belong, or draft_handbook_edit) instead of a new one; create a new article only when none fits, and say which closest article you found and why it did not fit. Audience comes from the person's words: cleaner SOPs, cleaning standards or staff = cleaner; policies, office or VA = va; when the words do not say, ask in one line. Ask which place, in one line naming both, when two places fit the person's words equally well: two articles, or two training modules that both match (two new-hire modules are a tie whatever their status, draft or published); a place the person named outright is never a tie. The proposed change is the confirmation, so never ask "should I add this?" first. Pass the same idempotency_key when retrying; a repeat returns the same module.
DiscoveredDecides one suggestion Sergio read from an uploaded document (itemId from read_company_document or read entity company_documents), as the setup guide's taps do: approve creates the flow as a draft that is OFF or the recurring task PAUSED (nothing runs or sends until a person turns it on); edit rewrites its sentence; skip drops it. approve with sentence applies that edit first. A repeat returns the same created row.
DiscoveredRecords where the business gets its leads (keys from the setup guide list, for example thumbtack, google_lsa, yelp, website, other; other needs its words), as Get started's lead sources step does. An answer only: it opens and sends nothing. Pass the same idempotency_key when retrying. An owner-level change: Sergio tells the owner after it is made.
DiscoveredDeletes a campaign as Delete on its card does: its queued messages are pulled back first; messages already sent stay in their threads. It cannot be undone; to stop it for now, edit_campaign with status paused. Pass the same idempotency_key when retrying.
DiscoveredDeletes a note from a contact's card outright, as the note's Delete does. It cannot be undone (the activity log keeps what it said). Pass the same idempotency_key when retrying; a repeat after the note is gone answers success.
DiscoveredDeletes a Scanner, as Delete in its editor does; the tasks it already made stay. To pause it instead, use set_scanner_on with enabled false. Pass the same idempotency_key when retrying. An owner-level change: Sergio tells the owner after it is made.
DiscoveredDeletes a task outright, as the task menu's Delete does. It cannot be undone; to say a task is not needed, use skip_task instead. Deleting a Scanner's task tells that Scanner it was wrong. Pass the same idempotency_key when retrying; a repeat returns the first delete's answer.
DiscoveredDeletes a quiz question outright as its Delete does (owner or admin seats only); the activity log keeps its text. A repeat after it is gone answers success. Pass the same idempotency_key when retrying.
DiscoveredDismisses every open reminder on a conversation, as the bell's Dismiss does. Pass the same idempotency_key when retrying.
DiscoveredDismisses a notification card (action "dismiss"), snoozes it for its own snooze time ("snooze"), or marks it read ("read"), as the card's controls do. Pass the same idempotency_key when retrying.
DiscoveredDismisses a Sergio suggestion card, as the card's dismiss does. reason is optional ("Not needed" tells the Scanner that raised it that it was wrong). Pass the same idempotency_key when retrying; a repeat returns the first answer.
DiscoveredRecords why a quiet thread needs no reply, as the clear gate's picker does: spam (the contact becomes spam; its lead work stops and its Quo card is tagged when the business's write setting allows), lead (the contact becomes a lead), reengage (tags the contact for a later marketing touch) or no_action. It does not clear the thread. Pass the same idempotency_key when retrying.
DiscoveredAsks Sergio to draft an edit to an article, as the article's Ask Sergio does: with context, the smallest change that does what it says; without, a general cleanup. The draft waits as a pending version (review_handbook_edit approves or rejects it). When the person gave the exact words to add, edit_handbook_article with them is the direct change; use this when they asked for a rewrite or cleanup. Before adding anything to the handbook, search the sops read entity by the topic (search finds by meaning): when an article already covers it, put the new text into that article (edit_handbook_article with its full content_md, the new lines placed where they belong, or draft_handbook_edit) instead of a new one; create a new article only when none fits, and say which closest article you found and why it did not fit. Audience comes from the person's words: cleaner SOPs, cleaning standards or staff = cleaner; policies, office or VA = va; when the words do not say, ask in one line. Ask which place, in one line naming both, when two places fit the person's words equally well: two articles, or two training modules that both match (two new-hire modules are a tie whatever their status, draft or published); a place the person named outright is never a tie. The proposed change is the confirmation, so never ask "should I add this?" first. Pass the same idempotency_key when retrying; a repeat returns the same draft without asking the model again.
DiscoveredEdits a campaign as its builder does (the fields you pass change; the rest stay), or pauses (status paused, pulls back its queued sends) or archives it. Turning automatic sending off (auto_send false) is open. To start or resume one, use start_campaign (your person confirms first). Held for the owner, refused with where: starting it here, turning automatic sending on, and changing the messages, audience, caps or send window of a started campaign that sends automatically (turn auto_send off first, in the same call or before). Templates, offer and audience_filter follow the same rules as create_campaign (listed on each field). Pass the same idempotency_key when retrying.
DiscoveredEdits a contact as the contact card's pencil does: name, phone (with area code), email, company_name, address (keep its zip if it had one), access_notes, special_instructions, has_pets, pet_details, preferred_cleaner, preferences, availability_notes, contact_type. Send only the fields to change; a contact always keeps a name, phone or email. expected (field -> the value you read) refuses the save if someone changed it since (stale_write). A rename reaches the Quo card when the business's write setting allows. Pass the same idempotency_key when retrying.
DiscoveredRenames a contact list or archives it (archived: true; its people keep their other lists), as the Contacts page's list menu does. Pass the same idempotency_key when retrying.
DiscoveredRenames a Contacts tag or archives it (archived: true), as the Contacts page's tag menu does. Pass the same idempotency_key when retrying.
DiscoveredApplies one edit to up to 5000 contacts, as the Contacts page's selection bar does: op add_to_list / remove_from_list (listId), add_tags / remove_tags (tagIds), set_service_category (value residential, commercial, both or null), set_lead_source (value thumbtack, google_lsa, yelp, bark, website_form, google_business_profile, referral, booking_software, direct, web_chat, other or null), set_type (type client, lead, applicant, other), archive, mark_spam (at most 500 for the last three; a type change or spam tags or untags the Quo card when the business's write setting allows). Each contact answers succeeded, skipped (already so) or failed. Pass the same idempotency_key when retrying; every op is safe to repeat.
DiscoveredEdits a draft in a conversation's draft box, as a person typing in it does: body, subject (email), whyNote, isReady, or status 'discarded' to throw it away. Nothing is sent; a person still presses Send. draft_id comes from create_draft or read. Pass the same idempotency_key when retrying.
DiscoveredChanges a flow's name or description, as its editor on the Automations page does. Send only what changes. Its steps and how it starts are set in the editor (how it starts: set_flow_start). flow_id comes from read('flows'). Pass the same idempotency_key when retrying.
DiscoveredEdits a handbook article as its Edit page does: title, content_md, category, tags, audience, bucket, is_published, exclude_from_suggestions. Send only the fields to change (sop_id from read entity sops); content_md replaces the whole body, so read the article in full (read sops with id) and send all of it with the change in place. Saving supersedes pending suggestions on it. Before adding anything to the handbook, search the sops read entity by the topic (search finds by meaning): when an article already covers it, put the new text into that article (edit_handbook_article with its full content_md, the new lines placed where they belong, or draft_handbook_edit) instead of a new one; create a new article only when none fits, and say which closest article you found and why it did not fit. Audience comes from the person's words: cleaner SOPs, cleaning standards or staff = cleaner; policies, office or VA = va; when the words do not say, ask in one line. Ask which place, in one line naming both, when two places fit the person's words equally well: two articles, or two training modules that both match (two new-hire modules are a tie whatever their status, draft or published); a place the person named outright is never a tie. The proposed change is the confirmation, so never ask "should I add this?" first. If the article is in a training module with quiz questions, say in your answer that its questions may need regenerating (generate_training_questions with regenerate). Pass the same idempotency_key when retrying.
DiscoveredChanges one step of one lead's follow-ups, as the journey list does. Send one or more of: dueAt (ISO time, or null for the plan's timing; must stay after the step before it), channel ('message', 'email', 'call', 'reply', or null for the plan), removed (true takes it out, false puts it back), keep: true (its custom text is still right after the latest conversation). Or addAfter ('message', 'email', 'call' or 'reply') alone to add a step after it (the new step's id comes back). The step's words are your person's to change in the app. step_id comes from the lead's journey. Pass the same idempotency_key when retrying.
DiscoveredChanges a Scanner, as its editor on the Scanners page does: any of name, question, inputs, look-again timing, who gets the task, due rule, destination, contact types, enabled. scanner_id comes from read('scanners'). Pass the same idempotency_key when retrying. An owner-level change: Sergio tells the owner after it is made.
DiscoveredEdits a training module as its page does (owner or admin seats only): title, description, atom_order, context_position (before or after), status draft or published. Publishing puts it on the team's own training page (nothing is sent) and is refused until every atom has quiz questions (generate_training_questions). To add something to training ("add that to new-hire training"): read training_modules for the module the person means (by title and description), find or create the handbook article that holds the text (search sops first, as the handbook tools say), then send atom_order as the module's current order with that article id placed where it belongs; an article already in atom_order needs only its article edited. A module that gains an atom needs questions for it (generate_training_questions) before it can be published again. Before adding anything to the handbook, search the sops read entity by the topic (search finds by meaning): when an article already covers it, put the new text into that article (edit_handbook_article with its full content_md, the new lines placed where they belong, or draft_handbook_edit) instead of a new one; create a new article only when none fits, and say which closest article you found and why it did not fit. Audience comes from the person's words: cleaner SOPs, cleaning standards or staff = cleaner; policies, office or VA = va; when the words do not say, ask in one line. Ask which place, in one line naming both, when two places fit the person's words equally well: two articles, or two training modules that both match (two new-hire modules are a tie whatever their status, draft or published); a place the person named outright is never a tie. The proposed change is the confirmation, so never ask "should I add this?" first. Pass the same idempotency_key when retrying.
DiscoveredEdits a quiz question (question_id from read training_modules with module_id) as its Edit does (owner or admin seats only): question_text, choices, explanation, image_url. Pass the same idempotency_key when retrying.
DiscoveredStores `cursor` (a next_cursor you received) as this seat's high-water mark, so events_list with no cursor resumes after it. It only moves forward; an older cursor changes nothing.
DiscoveredReturns the next events for this seat, oldest first, after `cursor` (omit it to continue from your last ack). Each event names an arrival by id (a text, email, call, or booking change); fetch its detail with read(). Delivery is at-least-once: dedupe on event_id. Pass next_cursor to the next call, and ack it with events_ack once you have processed the page. An error cursor_expired (410) means events behind your cursor were trimmed (7-day retention or backlog cap): resync through read(), then events_subscribe with restart: true.
DiscoveredCreate or update this seat's one event subscription. inputs: which arrivals (omit for all: text_in, text_out, email_in, email_out, call_answered, call_missed, voicemail, booking_created, booking_changed, booking_cancelled, staff_clocked_in, staff_not_clocked_in, job_finished, visit_unconfirmed). contact_types: only arrivals for these contact types. A field you omit keeps its current value, so {paused:true} pauses without touching the filter; pass inputs:null or contact_types:null to go back to all. paused: true stops delivery without losing the cursor, paused: false resumes. restart: true moves your position to now and clears your ack (the resync after cursor_expired, once you have re-read current state). Delivery starts at the moment you first subscribe. Repeating the same call changes nothing.
DiscoveredLook up a client ID by a single identifier (phone or email). Returns the client ID or null. Simpler than resolveClient. No creation, no merge. Use for a quick check: "is this phone number already a client?".
DiscoveredStarts Sergio writing quiz questions for a module's atoms, as Generate questions does (owner or admin seats only). Atoms that already have questions are skipped unless regenerate: true (which replaces them); sop_ids limits it to some atoms. It runs in the background: read training_modules with module_id for generation_status and the questions. Pass the same idempotency_key when retrying; a repeat never starts a second run.
DiscoveredPuts a lap's automatic follow-ups on hold, as its Hold follow-ups switch does: lead follow-ups, a feedback check-in and a review request all obey the one hold. No step goes out on its own; each is drafted for a person. Turning them back on is your person's, in the app. Pass the same idempotency_key when retrying.
DiscoveredPuts a lap's automatic follow-ups on hold, as its Hold follow-ups switch does: lead follow-ups, a feedback check-in and a review request all obey the one hold. No step goes out on its own; each is drafted for a person. Turning them back on is your person's, in the app. Pass the same idempotency_key when retrying.
DiscoveredLinks a conversation to a contact, as the inbox's Link to a contact does: if the contact already has a one-to-one thread, it is folded into this one, and an email thread's address is saved to the contact. Sergio learns the correction for later emails. Pass the same idempotency_key when retrying.
DiscoveredLogs a phone call the team made outside the phone system (a cell phone, a desk phone) on a contact, as the contact pane's Log a call does. outcome: answered (someone picked up), no_answer, or voicemail (you left one). Optional note (what was said) and at (ISO time the call happened; now when left out, never in the future). The call joins the contact's history and moves their Lead status: an answered call reads In discussion; no answer or a voicemail, with nothing back from them, reads Contacted (a quote, a booking or a status a person set still wins). The answer carries leadStatus, where they stand now. Calls made through the connected phone system are recorded already; do not log those. Nothing is sent. Pass the same idempotency_key when retrying; a repeat returns the original call.
DiscoveredLogs a question the handbook does not answer, as Handbook's Ask a question does (optional sop_id of the article it is about, asked_by_name, channel app, sms, call or in-person). Pass the same idempotency_key when retrying; a repeat returns the same question.
DiscoveredMoves everything in conversation_id (messages, calls, emails, tasks) into target_conversation_id and removes the empty one, as the thread menu's Merge does. It cannot be split back. Pass the same idempotency_key when retrying; the same pair merges once.
DiscoveredMoves a lead to another follow-up journey (segmentId, as Settings > Lead follow-ups names them: read the lead program), at the same place in the sequence, as the lead's journey tag does. Pass the same idempotency_key when retrying.
DiscoveredOpens (or finds) the one conversation for a phone number nobody is saved under, as the inbox search's Text <number> does. Nothing is sent. Pass the same idempotency_key when retrying.
DiscoveredPins a note to the top of a contact's card (pinned: true) or unpins it (false), as the note's pin on the contact card does. noteId comes from read (entity client notes). Pass the same idempotency_key when retrying.
DiscoveredRun a read-only SQL SELECT over the business database and get rows back. It is the FALLBACK, not the first move: when a read(entity) answers the question (leads, clients, conversations, bookings and the rest of read's catalog), use read, which carries the business's own definitions (e.g. open leads = read lead_pursuits active:true) that raw tables do not. Use query only when read cannot express the question (a count, a GROUP BY, a JOIN across tables, filtering on a column read() does not expose, a discount a customer used, an arbitrary aggregate). SCHEMA: query the org-scoped view schema `soul_read` (NOT public). Every table you can read is a view there, already filtered to THIS business. You never write a WHERE organization_id clause and never pass an org id. START with `client_timeline` for any question about one person or booking: every SMS, call (with AI summary), email, booking and human action in one feed (columns: channel, direction, actor, at, text, ai_summary, sentiment, category, client_id, conversation_id, booking_id). Filter client_id, ORDER BY at DESC, LIMIT. Read `SELECT * FROM schema_notes` once for column semantics (event-time columns, value meanings, columns that lie: e.g. use sent_at not created_at; contact_type = client means a real client). Never guess a column name: before you name a column of any other table you have not listed in this conversation, list THAT table's columns first (one table, never the whole schema): `SELECT column_name FROM information_schema.columns WHERE table_schema='soul_read' AND table_name='<table>'`. Reference tables unqualified (e.g. `FROM bookings`). Search_path is already soul_read. RULES: exactly ONE SELECT statement (a second statement, SET, INSERT/UPDATE/DELETE or DDL is refused). Results cap at 100 rows; the response is {rows, returned, truncated}. When truncated is true, add your OWN aggregation (COUNT/GROUP BY) or a tighter WHERE rather than paging blindly. Dates are stored as the business's local calendar; compare bare dates directly (e.g. scheduled_date BETWEEN '2026-07-01' AND '2026-07-31'). Prefer one precise aggregate query over many row dumps. YOUR ROLE reads only these views here (every other view returns no rows): activity_log, booking_assignments, booking_events, booking_notes, booking_series, bookings, call_transcripts, calls, campaign_recipients, campaigns, checks, claims, client_checkins, client_identifiers, client_pinned_notes, client_relationships, client_staff_relationships, clients, company_documents, contact_list_members, contact_lists, contact_tag_members, contact_tags, conversation_flows, conversation_reads, conversations, emails, flows, import_jobs, leads, messages, org_email_config, org_holidays, organizations, outbound_gate_verdicts, payments, scheduling_rules, sop_categories, sop_question_log, sops, soul_findings, staff_availability_overrides, staff_default_availability, staff_earnings, staff_events, staff_profiles, tasks, team_members, training_assignments, training_modules, training_questions.
DiscoveredRead ANYTHING about the business: read(entity, filters). ENTITIES (key: purpose [main filters]): conversations: The inbox list of conversations [status, from, to, needs_reply, conversation_id, ...] | conversation_transcript: A client's whole history in one timeline [conversation_id, client_ref, from, to, search] | communications: Every text, email and call across the business in ONE read [from, to, direction, channel, contact_type, ...] | calls: Call log [conversation_id, client_ref, from, to, direction, ...] | bookings: Bookings by status/date/client/cleaner [status, frequency, from, to, date_axis, ...] | booking_time_logs: Cleaner clock-in/out records as a SET read [from, to, staff, client_ref, booking_id, ...] | booking_notes: Tiered booking notes + the flat booking note [booking_id] | clients: Look up contacts by id [id, name, name_words, phone, email, ...] | contact_groups: The business's live Contacts tags and lists, as the Contacts page's side nav shows them [kind] | client_standing: Visit count + last visit per client, with the client name [client_ref, client_ids] | client_case_file: Full context for a client's thread [conversation_id, client_ref, question, as_of] | owner_directives: Standing asks the owner gave the team in the team channel [status, from, to] | tasks: Tasks [status, task_id, client_ref, conversation_id, flow, ...] | cockpit_queue: The Sergio cockpit / Needs-Attention queue | activity_log: Audit trail of changes [days, from, to, search, actor, ...] | scheduling_decisions: The scheduling decision log [booking_id, days] | chat_turns: Each Sergio chat turn's AI cost and time, newest first, read from the AI usage log [turn_id, days] | staff_roster: The cleaner/staff roster, counted in code | staff_detail: Detail for one staff member [staff, kind, from, to] | staff_events: Every logged staff event org-wide [from, to, kind, staff, sentiment, ...] | client_checkins: Every client check-in / feedback record org-wide [from, to, client_ref, staff, outcome, ...] | google_reviews: The business's Google reviews as Sergio stores them [match_status, from, to, client_ref, stars, ...] | staff_signals: Clustered staff signals/feedback over a window [days] | staff_scheduling_rules: Per-staff scheduling rules/availability constraints | sops: The business's handbook [search, slug, id, audience] | sop_versions: Versions of ONE handbook article [sop_id] | sop_questions: Questions the team asked that the handbook did not answer [status] | training_modules: Training modules [status, module_id] | training_assignments: Who is assigned which training module, with status and deadline [module_id] | company_documents: SOP files the business uploaded, with the Flows and recurring tasks Sergio suggested... | findings: Product gaps / bugs filed on the /development board | financial_reports: Org-wide money rollups [from, to] | lead_pursuits: The Leads ledger [from, to, active, owed_by, task_status, ...] | campaigns: The Growth campaigns list [status, campaign] | campaign_recipients: Who each campaign reached [campaign, state, client_ref, from, to, ...] | flows: The business's flows as the Automations page lists them [flow, active] | scanners: The business's Scanners as the Scanners page lists them [scanner, enabled] | import_jobs: Imports as the Imports page and Data sources list them [status, source] | conversation_flows: Each time a flow or program [flow, status, outcome, client_ref, from, ...] | settings: Every setting of this business, from the one settings registry [area]. read('catalog') gives each entity's full description, every filter and field, and which this caller may read. E.g. read("bookings",{status:"cancelled"}), read("conversation_transcript",{client_ref:"Maria Lopez"}), read("cockpit_queue"), read("settings",{area:"ai"}) to learn which model powers you and where to switch it. A client_ref is a FULL name or an id (a bare first name may need disambiguation. Answer a needs_disambiguation result by re-reading with the candidate's id). from/to dates are the business's local calendar days. A value-set filter (each entity's setFilters in read('catalog'): status, state, outcome…) takes one value, a list (["completed","scheduled"] or "completed,scheduled"), a negation ("!cancelled"), or exclude_<key> (e.g. exclude_status:"cancelled"); an unknown value is an error naming the valid ones. A ref filter (each entity's refFilters in read('catalog'): client_ref, staff) takes one ref, a JSON array of refs (matches any; a single string is always ONE ref, commas included), "!ref" or exclude_<key> to drop, up to 25 refs per read; a ref in the set that matches no one or several people returns that ref's no_match / needs_disambiguation. SEVERAL AT ONCE: conversations (conversation_id or client_ref, up to 10); conversation_transcript (conversation_id or client_ref, up to 10); client_case_file (conversation_id or client_ref, up to 5); staff_detail (staff, up to 10) take a list of values and answer every one in ONE call (items[] in the order asked); never loop one read per person. Everything is org-scoped and read-only; you never pass an organization id. List reads carry returned/total/truncated: when truncated is true you saw only the most recent `returned` of `total` (or of more). Say so plainly and narrow with filters (a date range from/to, a status, a client). TO RETRIEVE A SET COMPLETELY: if truncated, page with options.limit = N (up to 100) and options.offset = 0, N, 2N … until returned < N or offset >= total. Pages are stable (ties break on id), so paging never repeats or skips a row. A group_by read pages its GROUPS the same way: groups_total says how many exist and next_offset (with paging_hint) is the options.offset of the next page. TO COUNT ("how many X", "bookings per status"): read with the filter and use `total`. Issue one filtered read per value and read each `total`; NEVER eyeball or tally a capped page of rows.
DiscoveredHas Sergio read one uploaded company document (document_id from read entity company_documents) for Flows and recurring tasks it describes, as the setup guide's Your SOPs step does. Creates nothing; returns the suggestions (decide each with decide_company_document_suggestion). A document already read returns its list without a second read.
DiscoveredRecords the tools the business uses today and whether Serviche was given access to each, as Get started's Your tools step does: action pick (tools: [{ id } or { name }]), none, mark (tool, provided, note) or unmark (tool). Nothing leaves Sergio. Pass the same idempotency_key when retrying. An owner-level change: Sergio tells the owner after it is made.
DiscoveredRewrites the text of a lead's upcoming step that a person sends, from the conversation so far, as the journey's Update draft does (one AI draft, billed like the composer's Draft). Refused for a call step, a step Sergio sends on its own, or a step already past. Nothing is sent. task_id is the lead (read entity tasks); step_id is the step's id from the lead's journey. Pass the same idempotency_key when retrying.
DiscoveredTakes one flow off a conversation, as the flow chip's Remove does; its open step tasks are removed. conversationFlowId names the flow. reason is optional. Pass the same idempotency_key when retrying.
DiscoveredRemoves one plain-English scheduling rule (ruleId, from add_staff_scheduling_rule or read staff_scheduling_rules) from a field worker (staff_id), as remove on their Rules tab does. Answers the rules left. Pass the same idempotency_key when retrying. An owner-level change: Sergio tells the owner after it is made.
DiscoveredRemoves one person's assignment to a module (id from read entity training_assignments), as Assign's Remove does (owner or admin seats only). Assigning training stays a person's (it creates a sign-in). A repeat after it is gone answers success. Pass the same idempotency_key when retrying.
DiscoveredReopens a done or dismissed task, clearing its completion. A lead follow-up (pursuit) task is refused: reopening it can queue a message, so a person does it. Pass the same idempotency_key when retrying; a repeat returns the task, reports what the original call applied, and changes nothing if the task changed since.
DiscoveredFiles a bug report or feature request with the Sergio team. It lands in the team's one Feedback inbox, the same place the in-app help bubble's reports go, tagged with this agent seat, and the team is notified the moment it is filed. There is no other feedback channel to try. Check with your user first unless they have already told you that you may report without asking; afterwards, tell your user in one line what you sent. Never include passwords, API keys, or card numbers.
DiscoveredSorts one cleaner name found on bookings, as the Get started card's Review your cleaner roster does: action add (adds them to the roster and links their past jobs), not_staff (this name is not one of our cleaners), or link (it is staffId under another spelling; links their past jobs). Nothing is sent. Pass the same idempotency_key when retrying.
DiscoveredApproves (the draft becomes the article's text) or rejects a pending drafted version of an article (version_id from draft_handbook_edit or read entity sop_versions), as the article's Approve and Reject do. The same decision again answers success; the other decision on a reviewed version is refused. Pass the same idempotency_key when retrying.
DiscoveredSettles an import waiting at the column review, as its review card does: decision approve (the import runs with the confident columns plus keepFields; keepValues and assignValues teach status words) or discard (nothing is written). Pass the same idempotency_key when retrying. An owner-level change: Sergio tells the owner after it is made.
DiscoveredRuns a Sergio card's move now, as the card's "Run this now" does. action_type is the card's action type (for example create_draft). A move that sends, moves money, opens to the public or grants access is refused with where the owner does it; a move that writes to an outside system (booking changes) is not lent to agents yet. Pass the same idempotency_key when retrying; the move keys on the card, so it never runs twice.
DiscoveredSends a started campaign's drafted messages that are ready, on your person's order, as Send in its Ready to send does, as Manual sends under the business's Sending setting, spread over the campaign's send window. First call without confirm_token: nothing is sent; you get a preview (each person and the exact finished text they get, up to 50 at a time) and a confirm_token. Show your person the preview word for word, and only after they say yes, call again with the same arguments and the SAME idempotency_key, plus confirm_token: exactly the messages shown are sent. If Sending is switched off the answer says so with the link; only the owner turns it on, in Sergio. Never send something nobody asked for.
DiscoveredEmails a client from the business mailbox on your person's order, as a Manual send under the business's Sending setting. First call without confirm_token: nothing is sent; you get a preview (to, subject and the exact text) and a confirm_token. Show your person the preview word for word, and only after they say yes, call again with the same arguments and the SAME idempotency_key, plus confirm_token. replyToEmailId threads it as a reply to that inbound email.
DiscoveredTexts a client or teammate on your person's order, from the business number, as a Manual send under the business's Sending setting. Use it whenever your person asks you to text someone now, with their words or words you wrote for them ("text today's cleaners about the weather"); create_draft leaves it for someone else to send later. First call without confirm_token: nothing is sent; you get a preview (who it goes to and the exact text) and a confirm_token. Show your person the preview word for word, and only after they say yes, call again with the same arguments and the SAME idempotency_key, plus confirm_token. Several people: one preview each, shown together, one yes covers the ones they approve. Never send something nobody asked for, or while nobody is watching; that is a draft (create_draft). Give conversationId (one-to-one: to defaults to the conversation's number); for a cleaner or contact without one, read clients (contact_type 'staff' for cleaners) for the phone, then open_conversation_by_phone.
DiscoveredAdds a reminder on a conversation, as the thread's bell does: remind_at (ISO 8601) and an optional note become a task due then. hide_until_due: true also tucks the thread away until the reminder is due (a reply from the person brings it back). Pass the same idempotency_key when retrying; a repeat returns the first reminder.
DiscoveredMarks a thread done (status resolved) or reopens it (status new), as the inbox's Done and Reopen do; the Quo inbox follows when the business's write setting allows. A thread that still owes the customer a reply is refused unless replyOwedOverride is true (say why to your person first). Pass the same idempotency_key when retrying.
DiscoveredArchives a flow as its Archive on the Automations page does (archived true): it leaves the flow pickers and the router but is kept, and runs in progress are unaffected. archived false un-archives it. flow_id comes from read('flows'); archive several by calling once per flow. Pass the same idempotency_key when retrying.
DiscoveredTurns a flow on or off, as its On switch on the Automations page does. Turning it on runs the same publish check (a refusal says what is missing); turning it off ends its runs in progress. flow_id comes from read('flows'). Pass the same idempotency_key when retrying.
DiscoveredChanges how one of this business's flows starts ("Starts when" in Automations) and whether it is on, exactly as the Automations editor's save does. starts_when "contact" means "You add it to a contact": nothing starts the flow by itself. Any other value starts it automatically on that booking event. Switching a start off ("contact") or turning a flow off (active false; its runs in progress end) is open to this seat. Starting a flow on an event or turning a flow on is owner-level: available only when the owner turned on "Let this agent change owner settings" for this seat; the owner is told about each such change. A flow that starts on every upcoming job (starts_when_words says so) turns on only after a person confirms how many jobs it covers, which this tool cannot do: it comes back refused with that count, and the owner turns it on in Automations. Picking a booking event here makes a flow start only on jobs from then on. read("flows") shows each flow and its current start. Events: booking_created (New job booked); booking_changed (Job changed); booking_cancelled (Job cancelled); staff_clocked_in (Cleaner clocked in); staff_not_clocked_in (Cleaner hasn't clocked in); job_finished (Job finished); visit_unconfirmed (Past job not marked done in the booking platform); card_declined (Card declined); review_received (Review received); review_low_rating (Low-star Google review); staff_on_the_way (Cleaner tapped On the way); staff_clocked_out (Cleaner clocked out); staff_running_late (Cleaner says they are running late); staff_not_on_the_way (Cleaner hasn't tapped On the way); staff_not_clocked_out (Cleaner hasn't clocked out); staff_clocked_in_twice (Cleaner clocked in on two jobs at once); staff_schedule_request (Cleaner asked to change their schedule). Pass the same idempotency_key when retrying; a repeat returns the original result.
DiscoveredExcludes one handbook article from Toolshed sharing (its shared rules are withdrawn) or includes it again, as the article's Toolshed sharing line does. Shared rules are generalized so no one can tell which business they came from. Pass the same idempotency_key when retrying. An owner-level change: Sergio tells the owner after it is made.
DiscoveredRecords what happened with a lead, as the lead card's Close menu and taps do. tap: quoted (they have a price); booked (closes it won, on the booking when one for them exists, else on your word); confirmed_booked (the same as booked); call_back_on (date YYYY-MM-DD, or at as an ISO time: pauses the lead until then; the pause ends by itself on that date, when a message goes either way, or when a step's date is changed); not_interested (lost; lostReason is one of "Timing / availability", "Price", "Went elsewhere / not needed", "Out of scope / area", or their own words for Other; a lead that just went quiet is not lost, it goes cold on its own); keep_pursuing; acknowledge_reply (their last message needs no answer: follow-ups resume); tracked_by_mistake; dismiss_plan; replied_on_site (stepKey: the Reply step answered on a lead site); undo_close (reopens a lead Sergio closed on its own, so the same evidence never closes it again; a contact made not-a-lead becomes a lead again, and Quo follows when the business's write setting allows). Nothing is sent. Pass the same idempotency_key when retrying.
DiscoveredTurns one of the business's Scanners on or off, as the On switch in Automations > Scanners does. A Scanner is only ever on or off (never a trial mode). scanner_id comes from read('scanners'). Pass the same idempotency_key when retrying. An owner-level change: Sergio tells the owner after it is made.
DiscoveredSets one field worker's availability for a date, or a date range (end_date, up to 92 days): a day off (day_off: true), one shift (available_from + available_until, HH:MM), or split shifts (windows). It replaces that day's override; hours equal to the weekly default clear it. Nothing is sent to anyone. Returns the override ids and any booking conflicts the change creates, for a person to resolve. Pass the same idempotency_key when retrying; a repeat returns the original override ids.
DiscoveredReplaces the regular weekly hours of the workers named in staffNames with exactly the windows in entries (day_of_week 0 = Sunday to 6 = Saturday, HH:MM times; several windows a day allowed; a named worker with no entries has no regular hours). Workers not in staffNames are untouched. Omit entries to leave hours alone and only save profiles (the worker's details: email, phone, allergies, and venmo / zelle, which change only for a seat allowed to change payment handles). For one date only, use set_staff_availability. If the new hours no longer cover a worker's upcoming Sergio visits, those visits are released and a task is filed for a person. Nothing is sent. Pass the same idempotency_key when retrying.
DiscoveredDismisses a task as not needed (terminal, distinct from done). A client check-in needs a skip_reason. Pass the same idempotency_key when retrying; a repeat returns the task, reports what the original call applied, and changes nothing if the task changed since.
DiscoveredMutes a conversation until snoozed_until (ISO 8601, in the future), at most 10 minutes from now (a later time is cut to 10 minutes), as the inbox's Mute does while someone is on a call. note is optional. For a later follow-up, use set_conversation_reminder. Pass the same idempotency_key when retrying.
DiscoveredMoves a task's due time (ISO 8601 with offset). A flow-step task shifts its later steps by the same gap, as in the app. Pass the same idempotency_key when retrying; a repeat returns the task, reports what the original call applied, and changes nothing if the task changed since.
DiscoveredStarts a draft or paused campaign on your person's order, as Start campaign does: it enrolls the people waiting and drafts their first message; starting sends nothing by itself. First call without confirm_token: nothing changes; you get a preview (every message's exact words, how many people it reaches now, the audience rules, and whether the business's Sending lets a person's messages go out) and a confirm_token. Show your person the preview word for word, and only after they say yes, call again with the same arguments and the SAME idempotency_key, plus confirm_token. If the preview says Sending is switched off, tell your person that plainly with the link; only the owner turns it on, in Sergio, and you never change it. A campaign with a message Sergio sends on its own is the owner's to start, in the app. To send the drafted messages once it has started, use send_campaign_messages.
DiscoveredStarts a flow on a conversation, as the thread's flow picker does: flowId names an active flow (read entity flows); its steps become tasks with deadlines. label is optional. Pass the same idempotency_key when retrying.
DiscoveredOpens the one group text thread for 2 to 9 contacts who each have a phone, as the inbox's New conversation with several people checked does (an existing group for the same people is reused). Nothing is sent; texting it is send_conversational_message, which shows your person the words first. Pass the same idempotency_key when retrying.
DiscoveredRecent measurements
| Checked | Result | Response | Tools |
|---|---|---|---|
| Connected | 9677 ms | 109 |