Skip to content

Tools reference

The Formule MCP server exposes 33 tools. Every one of them runs as you: the server resolves your identity first and then queries the database under row-level security, so a tool can only ever return what you could see by signing into the app yourself. A real estate agent asking search_leads gets their own leads; a manager asking the same question gets the agency’s.

These answer questions. They never modify anything.

Who this call acts for: the person, their agency (or agencies), their agent profile if any, whether you can write (can_write) and whether this chat is linked. Also work: the agency they work for and their role there (the Formule workspace is not always that agency), with how_to_talk to them, or ask when it is not known yet. Call it first. If user is null, explain the linking steps in scoping and do nothing else (on WhatsApp, scoping also says how someone new signs up with start_signup).

Takes no parameters.

What you (Really) did for this person lately, in every channel (the app, WhatsApp, calls): posts, Facebook Page posts, adverts, listings created or changed, WhatsApp messages sent, designs, reels, leads added. Each line has when, the channel, what and where, and the link when there is one. Read it before saying something was not done (“did you post the garage on Facebook?”), and when they ask what you did.

Parameter Type What it does
days integer How far back (default 30, max 90).
limit integer Most lines (default 20, max 50).

The agencies this person belongs to (all agencies for a super admin), with how they belong (via) and which one is active. Use the slugs with select_company or company_slug.

Takes no parameters.

Find leads (the people this person already has in Formule) by free text (name, surname, property, email, phone), by what an agent wrote in the lead’s notes, by status or by assignment. Returns the most recent first. Only leads this person may see in Formule. Not for finding homes: ‘what do we have for a client with 4 million in Marsascala’ or ‘my buyer wants a 3-bed in Sliema’ asks for properties for that client, which is search_listings.

Parameter Type What it does
query string Text to match against name, surname, property, email and the lead’s notes; a phone number is matched exactly. A lead matched on its notes carries matched_note, the part of the note that matched.
status string Filter by crm_status.
unassigned_only boolean —
limit integer Max results (default 20, max 100).

Full details for one lead, including comments, its open property matches (from the agency’s external listing catalogue, when connected) and open reminders. A lead with awaiting_your_acceptance: true was offered to this agent by a manager and is not accepted yet: its contact details come back masked and its notes are left out until they accept it in Formule.

Parameter Type What it does
lead_key (required) string —

Leads that still need attention (UNCLEAR / ATTEMPTED_NO_RESPONSE / NURTURE) with no comment in the last N days. The raw material for a follow-up digest.

Parameter Type What it does
days integer Default 7.
limit integer —

Saved property matches between this person’s leads and the agency’s external listing catalogue, best score first. Default: ‘new’ matches only; matches found on a person’s request (find_matches_for_lead) are saved as ‘shown’. A catalogue: “none” answer means no catalogue is connected: relay that, never ‘no matches’. A matching: “not_available” answer means this person is not on the matching list: say so, then search the catalogue with search_listings instead.

Parameter Type What it does
status string —
since string ISO timestamp; only matches created after this.
limit integer —

Search property listings (active, newest first). The tool for ‘what do we have for a client with 4 million in Marsascala’, ‘anything for a buyer with 2M in Attard’: a client’s budget and place are max_price (with min_price near it) and locality. Searches the agency’s own catalogue (its portal feed, or its own website once connected with connect_agency_website) by default, or the whole market with scope “market”: every agency catalogue Formule holds (portal feeds and agencies’ own websites), each listing with listed_by naming the agency. An agency without a catalogue of its own always searches the market. Pass agency to search one agency’s listings by its name. Covers homes and commercial property (shops, Class 4B retail, offices, Class 4A, restaurants and food & drink, showrooms, warehouses, hotels, land, garages), for sale and for rent. Always pass property_type when the person names a kind: plain words work (‘retail’, ‘shop’, ‘office’, ‘commercial’, ‘restaurant’, ‘land’). Pass sale_or_rent when they say buy or rent. With a locality, listings in that place itself come first and the rest of its wider region after them; several places can be given at once (‘Sliema, Gzira’); in_locality says how many are in the places themselves, so say when the others are nearby rather than in them. A rental’s price is per month unless price_basis says otherwise (e.g. ‘Yearly Price Per Square Meter’). When nothing matches, kinds_available lists what the same search does have: offer those instead of saying there is nothing. Pass ref to look up one listing by its reference (the code at the end of its link). The catalogue knows no distances (schools, the sea): say so, and give the listings with their links so the agent can check. When the agency’s own search finds nothing, try the market (try_market says so). For agencies and portals outside Formule’s catalogue, use web_search and preview_listing_from_url (beyond says how). A still_reading answer means a website is still being read: say the results cover only the listings read so far. A catalogue: “none” answer means no agency has any catalogue yet.

Parameter Type What it does
ref string Listing reference, e.g. SAPT670357. The other filters are ignored when it is given.
scope string agency (default): the agency’s own catalogue. market: every agency catalogue Formule holds.
agency string Only this agency’s listings, by its name or website. Implies the market.
locality string Locality or region name, any spelling (St Julians, San Giljan, Gżira); several separated by commas.
min_price number Lowest asking price (or monthly rent).
max_price number Highest asking price (or monthly rent).
min_bedrooms integer Fewest bedrooms.
property_type string The kind of property in plain words, e.g. Apartment, Penthouse, Villa, retail, shop, office, commercial, restaurant, warehouse, land, garage.
sale_or_rent string For sale or for rent.
limit integer Max results (default 20, max 100).

Active agents of the agency (names and contact details, as shown in the app).

Takes no parameters.

This person’s numbers over the leads they may see: leads by status, new in the last 7 and 30 days, leads with no note yet, leads still open but quiet for 7+ days, last activity, open reminders. Admins see their agency-wide view.

Takes no parameters.

Which of this person’s leads would want a given property, e.g. “which clients fit a 2-bed in the centre?”. Pass listing_key for one of the agency’s own listings, a listing reference from the agency’s external listing catalogue, or describe the property (locality, price, bedrooms, property_type, sale_or_rent) with whatever the person said. Reads every lead’s stated preferences, the wishes typed on the lead, and what agents wrote in its notes; place names match whatever the case, accents, a known short form or a typo. Returns the best few with the reason each fits; a fit read from the notes carries matched_note, the note it came from.

Parameter Type What it does
listing_key string One of the agency’s own listings, as list_my_listings or get_listing returned it.
ref string Listing reference in the agency’s external catalogue.
locality string Town or area, as the person wrote it (misspellings are fine).
price number —
bedrooms integer —
property_type string e.g. Apartment, Penthouse, Villa
sale_or_rent string —
limit integer Default 10.

Open reminders due up to a point in time (default: end of today on the agency’s clock) plus any overdue ones, soonest first. Your own reminders; admins also see their agency’s.

Parameter Type What it does
until string ISO 8601 timestamp; default the end of the current day in the agency’s time zone.
include_future boolean Also list reminders due after until.
limit integer —

What the assistant remembers about one lead’s WhatsApp conversation: last contact, counts, listings already shared, warmth, and the latest messages (text kept 30 days). Only for leads whose agent enabled WhatsApp reading in Formule.

Parameter Type What it does
lead_key (required) string —
limit integer Messages to return, default 20.

What the assistant should tell this person now: follow-ups due, leads gone quiet, new property matches, next steps after a conversation. Each has a ready-to-send draft. Pure read: call acknowledge_nudges after showing them.

Parameter Type What it does
include_delivered boolean Also return nudges already shown (default true).
limit integer —

Free-text search across this agency’s leads and its external listing catalogue. Returns lightweight {id, title, url} hits; pass an id to fetch for the whole record. Scoped by Formule’s own permissions, so it returns only what this person can already see. (ChatGPT deep research and company knowledge require a tool named exactly search.)

Parameter Type What it does
query (required) string Free text, matched against lead name, surname, property and email, and against listing title, locality and region.
limit integer Max results (default 10, max 50).

Return one whole record as readable text, given an id from a search result. Ids look like lead:<lead_key> or listing:<ref>. (ChatGPT deep research and company knowledge require a tool named exactly fetch.)

Parameter Type What it does
id (required) string An id exactly as returned by search.

These write. Expect your client to confirm before running one.

Add a new lead (a client) to the agency, as the app’s New lead form does: assigned to this person when they are an agent. Needs the first name and a phone number; pass the surname, email, what they came for (property) and a note only when the person said them, never invented. A national phone number gets the agency’s calling code. If one of this person’s leads already has that phone or email, nothing is added and that lead comes back with duplicate: true.

Parameter Type What it does
name (required) string First name.
surname string —
telephone (required) string As the person gave it.
email string —
property string The listing or source they came from, e.g. “seafront penthouse” or “walk-in”.
note string Anything else the person said about them; saved as the lead’s notes.
from_whatsapp_chat boolean true when the person forwarded you this contact card or chat from their own WhatsApp (they already talk to this client): the lead is filed under WhatsApp and gets no automatic welcome message.

Add up to ${MAX_BULK_LEADS} leads at once from a list the person pasted, each exactly as create_lead adds one, after one approval. Every person needs a first name and a phone number from the list itself, never invented; leave out anyone without a phone and say so. The result gives each row: created, already_a_lead (same phone or email as one of this person’s leads), or skipped with the reason.

Parameter Type What it does
leads array First name.

Append a dated note to a lead’s comments (the same log agents write in the CRM).

Parameter Type What it does
lead_key (required) string —
note (required) string —

Remind this person about a lead at a given time (‘remind me to call Maria on Friday’). Reminders belong to the person asking; they can only be set in an agency they are a member of.

Parameter Type What it does
lead_key (required) string —
due_at (required) string ISO 8601 timestamp with the agency’s UTC offset (whoami gives its time_zone and local_time), e.g. 2026-09-11T09:00:00+02:00.
note string What to do, in the person’s words.

Finish the one-time account link: the person got a code from Formule and sent it in this WhatsApp chat (8 characters, in the message LINK CODE that Profile → Really on WhatsApp and by phone, or the page that finishes signing up on WhatsApp, writes for them). Pass the code; the chat identity comes from the assistant runtime. From then on this chat acts as that person.

Parameter Type What it does
code (required) string —
chat_id string The chat the code was sent from. Set by the assistant runtime; do not fill in by hand.
platform string Default whatsapp.

For an estate agent who is new to Formule, messages you on WhatsApp and wants to start: emails them a link that creates their Formule account. Only in a WhatsApp chat that is not linked yet (whoami: user null); never for a linked chat.

Parameter Type What it does
full_name (required) string Their first and last name, as they gave it.
agency_name string The agency they work for; leave it out when they work independently.
email (required) string Their email address, exactly as they confirmed it.
language string The language you are chatting in, as a code such as it or de. The email is written in it when Formule speaks it (en, de, fr, es, it, pl), else in English.

For the WhatsApp sender who asked for a sign-up (start_signup) and sends back the 6-digit code from that email. Only in a WhatsApp chat that is not linked yet, only from the number that asked.

Parameter Type What it does
code (required) string The 6 digits from the email, as sent (spaces are fine).

Save which agency the person works for and their role there (whoami shows it as work). Call it as soon as they say it, in any words (“I’m the CEO of …”, “agent at …”), and when they correct it; only the fields given change.

Parameter Type What it does
agency_name string The agency they work for, as they name it.
agency_website string The agency’s website, e.g. agency.com.
job_role string —
job_title string Their title in their own words, e.g. CEO, Branch manager.

Switch the active agency for a person who belongs to several (see whoami). Pass the agency’s slug: map the agency name the person used to a slug yourself, never ask them for a slug. In a chat the choice sticks for later calls.

Parameter Type What it does
company_slug (required) string —

Set a lead’s crm_status.

Parameter Type What it does
lead_key (required) string —
status (required) string —

Mark a property match as shown, sent (the listing was sent to the client) or dismissed.

Parameter Type What it does
match_id (required) string —
status (required) string —

When the person asks for it: read this lead’s notes, work out what the client wants (area, budget, bedrooms, type, buy or rent) and match that against the agency’s external listing catalogue. Saves those wishes and the matches on the lead (as ‘shown’) and returns the best matches with the reasons. Every call is one AI read of the notes, so only call it when the person asks. A matching: “not_available” answer means this person is not on the property matching list: say so. A reason: “no_wishes” answer means the notes do not say what the client wants yet: say what is missing.

Parameter Type What it does
lead_key (required) string —

Mark a reminder as done (optionally logging what happened as a note on the lead).

Parameter Type What it does
followup_id (required) string —
outcome_note string If given, appended to the lead’s comments.

Mark nudges as delivered after showing them to the person (list_nudges is a pure read). Only pending nudges change.

Parameter Type What it does
nudge_ids (required) array nudge_id values from list_nudges (max 100).

The person does not want this nudge (e.g. already handled it elsewhere).

Parameter Type What it does
nudge_id (required) string —

Bring this nudge back later (default 24 hours).

Parameter Type What it does
nudge_id (required) string —
hours number —

Send ONE message to a lead from the agent’s own WhatsApp number, only after the agent explicitly approved this exact text in this conversation. Logs it on the lead in the CRM, closes the nudge it answers, and sets the next reminder (default 3 days; 0 for none). Repeating a call with the same idempotency_key within 24 hours returns the first result and sends nothing. Never claim a message was sent unless sent is true.

Parameter Type What it does
lead_key (required) string —
text (required) string The exact text the agent approved.
idempotency_key (required) string A value unique to this approval (e.g. the chat message id of the approval). Reuse it if you retry.
nudge_id string The nudge this send answers, if any.
next_follow_up_days integer Default 3. 0 = no reminder.

This page is generated from the server source. If a tool here looks wrong, the source is the truth — see supabase/functions/mcp/server.ts.