resumen_cuentaReturns the asking account's own data: display name and when it was created. Use it at the start of a conversation to know who you are talking to, or when asked "who am I?".
No parameters.
Everything modellus can do is available through code. The same actions the app uses internally can be called from your program or from another AI.
Create a key from the app and send it with every request:
curl https://modellus-app.vercel.app/api/v1/resumen_cuenta \
-H "Authorization: Bearer mll_your_key" \
-H "Content-Type: application/json" \
-d '{}'Connect Claude, ChatGPT, or any MCP-compatible client to this address, with the same key:
https://modellus-app.vercel.app/api/mcpThe full OpenAPI spec, with every parameter and response, lives at /api/v1/openapi.json.
resumen_cuentaReturns the asking account's own data: display name and when it was created. Use it at the start of a conversation to know who you are talking to, or when asked "who am I?".
No parameters.
export_dataExports this account's data as JSON: contacts, loans and pre-quals, the people on each file, financial items, the document checklist, tasks and messages. Use it when the user wants a backup, wants to take their data somewhere else, or asks for "everything on the Martinez file" in one piece. Ask for one table with `que` when they only need part of it. Uploaded files themselves are not included — their paths and status are.
quearraylimiteintegersearchSearches the whole account at once — contacts, loans, pre-quals and tasks — and returns the top matches per group. Use it when the user searches for something and it is not clear what kind of thing it is ("search Robert Miller", "anything on 412 Elm?", "find insurance"). If you already know it is a loan or pre-qual, use find_loan; if you know it is a person, use find_contact — those return the full record. Accepts a name, an email, a phone fragment, a property address, a loan number or a task title.
querystringrequiredadjust_viewAdjusts the list screens: the pre-qual pipeline, the loan pipeline, or the contacts list. Shows or hides columns ("show the loan number in the pipeline"), REORDERS a column ("put the amount column first", "move closing date before created"), expands or collapses COLUMN GROUPS (file, loan, rate, contacts, property, title, dates, docs — "expand the property columns"; Loan, Rate, Property and Title exist only on the loan pipeline, since a pre-qual has no property or rate yet), turns a WHOLE GROUP of columns on or off at once ("show me all the title columns", "hide every date"), REORDERS THE GROUPS themselves ("put the documents block first", "move dates before property"), PINS a column to the left or right edge so it stays in view while scrolling sideways ("keep the loan amount visible", "pin the closing date to the right", "unpin the rate"), switches the LIST LAYOUT between the table of rows and the grid of cards ("show the loans as cards", "back to the table view") — each list remembers its own, and on a phone it is always cards — changes row density (compact/standard/comfortable), SORTS the list by a column ("sort the loans by amount, biggest first") and FILTERS it by the values of a column ("only show FHA loans", "just the ones assigned to Ana", "clear the filters"). The sort and the filters are what the column header menus do, and they stick for next time. Everything here is PER PERSON: it changes how the caller sees the list, never how their teammates see it. To read the pipeline itself use view_pipeline; to change the stage of one file use move_stage.
vistastringrequiredmostrararrayrequiredocultararrayrequiredmoveranyrequireddensidadanyrequiredformaanyrequiredexpandir_gruposarrayrequiredcolapsar_gruposarrayrequiredmostrar_gruposarrayrequiredocultar_gruposarrayrequiredmover_grupoanyrequiredordenanyrequiredquitar_ordenbooleanrequiredfiltrosarrayrequiredquitar_filtrosbooleanrequiredfijararrayrequiredcambiar_nombreChanges the account's display name. Use it only when explicitly asked to change or correct how the user is called.
nombrestringrequiredview_profileReturns the profile of the person asking: their display name, email, phone, photo, NMLS number, whether their email is verified, whether an email change is still waiting to be confirmed, and their role in this account (owner, loan officer, or assistant). Use it when the user asks "what is my name here", "what email am I signed in with", "is my email verified", "did my email change go through", "what can I do in this account", or before changing any of it with update_profile or change_email.
No parameters.
update_profileChanges the asking person's own profile: display name, phone number, NMLS number, or profile photo. Use it when the user says "change my name to...", "my phone is...", "update my NMLS", "remove my profile picture". Only the fields given are touched; the rest stay as they were. To see what they are now, use view_profile.
namestringphoneanynmlsanyphoto_urlanyreset_passwordEmails the signed-in person a link to set a new password. Use it when the user says "I want to change my password", "reset my password", "I forgot my password". Never ask them to type the new password here — the link is where they set it.
No parameters.
resend_email_verificationResends the email that confirms the signed-in person's address. Use it when the user says "I never got the confirmation email", "resend the verification", or after view_profile shows their email is not verified yet.
No parameters.
change_emailStarts changing the email address the signed-in person uses to sign in. Use it when the user says "change my email to...", "I lost access to my email", "I want to sign in with another address", or "update my login email". It does not change anything on its own: it sends a confirmation link to the new address and to the current one, and the change only takes effect once both are opened. Calling it again with the same address sends the links again. To see whether a change is still waiting, use view_profile.
emailstringrequiredview_integrationsShows what this account has connected — Arive (the loan origination system) and the user's own email account (Gmail/Outlook) — and whether each one is actually working: its status, when it last worked, and what the last failure said. Use it when the user asks what is connected, where their messages are sent from, why their emails are not going out from their own address, or right after they finish an email authorization to confirm it worked. To test a connection right now use check_integration; to change any of it, use connect_arive, connect_email or disconnect_email. It also shows the Arive cutoff date — from when loans get imported — which set_arive_cutoff changes, and whether Arive live updates are on.
No parameters.
check_integrationTests a connection right now and reports whether it works: Arive (it authenticates and reads a loan) or the connected email account. Use it when the user suspects something is down ("is Arive working?", "my emails are not going out from my address", "check the connection"), or after fixing credentials. If it comes back expired or denied, the fix is connecting it again with connect_arive or connect_email — retrying will not help.
integrationstringrequiredconnect_emailStarts connecting the user's own email account (Gmail or Outlook) so their messages go out from their real address instead of the generic Modellus one, and so their address book can be imported. Use it when the user asks to connect their email, or when they want to import their contacts and no email account is connected yet. It returns an authorization link — show it to the user and tell them to open it, sign in, and come back; then check view_integrations to confirm it worked.
providerstringrequireddisconnect_emailDisconnects the user's own email account, so messages go back out through the generic Modellus sender and their address book is no longer reachable. Use it when the user asks to disconnect, unlink or remove their Gmail/Outlook connection. Messages already in the queue are not affected — they will simply leave from the generic sender.
No parameters.
view_google_contactsShows the Google Contacts connection: which Google account is linked (name and email), whether it is working, how many contacts already exist on both sides, how many are still only in Modellus, how many are waiting because Google could not be reached, and when it last ran. Use it when the user asks whether Google is connected, why their contacts are not syncing, how the sync is going, or right after they finish the Google authorization. To change any of it: connect_google to connect or reconnect, sync_google_contacts to run a sync now, preview_google_push / push_contacts_to_google to put Modellus contacts into Google, disconnect_google to stop syncing.
No parameters.
connect_googleStarts connecting the user's Google account so their contacts stay in sync between Modellus and contacts.google.com, in both directions. Use it when the user asks to connect Google, sync their Google contacts, bring their Google address book in, or when they ask for contact sync and no Google account is connected yet. It returns an authorization link — show it to the user and tell them to open it, sign in, and accept the permission to manage their contacts; then call view_google_contacts to confirm it worked and to start the first import. This is NOT connect_email: that one is for sending mail from their own address and only reads the address book.
No parameters.
disconnect_googleDisconnects the Google account used for contact sync, so contacts stop flowing between Modellus and contacts.google.com. Use it when the user asks to disconnect, unlink or stop syncing Google contacts. Nothing is deleted on either side — the contacts already imported stay, and the ones already in Google stay too; they simply stop updating each other. This does not touch their Gmail sending connection (that one is disconnect_email).
No parameters.
sync_google_contactsRuns a Google contact sync right now: brings in contacts from contacts.google.com that Modellus does not have, matches the ones it already has instead of duplicating them, and — only if the user already allowed it with push_contacts_to_google — sends changes the other way too. Use it when the user asks to sync, refresh or update their Google contacts, when they just connected Google, or when they say a contact they changed has not shown up on the other side. It NEVER deletes anything on either side. Large address books are done in batches: if it says more is left, just call it again.
No parameters.
preview_google_pushSays how many Modellus contacts would be CREATED in the user's Google address book, without creating anything. Use it BEFORE push_contacts_to_google, and whenever the user asks how many of their contacts are missing from Google or what would happen if they turned the sync both ways. Always show the number to the user and let them decide — this writes into their personal address book, so it is their call, not a side effect of connecting.
No parameters.
push_contacts_to_googleCreates the Modellus contacts that are missing from the user's Google address book and keeps changes flowing that way from then on, writing the Modellus contact id into a Google custom field so nothing is ever duplicated. Call preview_google_push FIRST and only call this once the user has SEEN how many contacts would be created and said yes — it writes into their personal address book. It never deletes anything in Google. Large books go in batches: if it says more is left, call it again, or let the scheduled sync finish it. Use stop=true when the user asks to stop writing to Google (what is already there stays).
stopbooleanrequiredfind_contactSearch the rolodex by anything the user says: a name (even partial or misspelled), a phone number or its last digits, an email, a tag, or a role like "realtor" or "title company". Use it whenever the user asks about a person ("what is Maria's number?", "show me my appraisers"), before saving someone you are not sure exists, and to get the contact details other actions need. Returns matching contacts with their roles, tags and key data; when few match, it includes their latest activity.
querystringrolestringtagstringlimitintegersave_contactCreate a new contact or update an existing one. Use it when the user introduces someone new ("add Maria Torres, she's a realtor, 704-555-0142") or changes someone's details ("John has a new email"). Updates when given an id or when the email/phone matches an existing contact exactly; if the new person looks like a probable duplicate it does NOT create — it returns the candidates so you can confirm with the user and either update/merge them (merge_contacts) or retry with create_anyway. When provided, roles and tags REPLACE the existing lists — to remove one ("she is not the listing agent anymore", "drop the vip tag") send the list without it, and send an empty list to clear them all. Any other field takes an empty string to clear it ("he has no company"). What you do not send stays as it was. When someone works through an assistant ("her assistant is Dana, dana@titleco.com"), save assistant_name, assistant_email and assistant_phone: from then on every email, text or WhatsApp sent to that contact is copied to their assistant.
idintegernamestringemailstringphonestringrolesarraytagsarrayaddressstringcompanystringnmls_licensestringpreferred_languagestringreferral_sourcestringnotesstringwork_phonestringhome_phonestringphone_extensionstringoccupationstringbirth_datestringfrequencyanylast_contactedstringassistant_namestringassistant_emailstringassistant_phonestringcreate_anywaybooleanmerge_contactsMerge two contacts that are the same person into one. Use it after save_contact or the import reported a probable duplicate and the user confirmed they are indeed the same, or when the user says "these two are the same person". Takes the two ids (find_contact gives them). The FIRST contact wins on conflicting fields; roles, tags and data are combined, and a non-null email/phone is never lost. The second contact is deleted. Never call it without the user confirming which two to merge.
keep_idintegerrequiredmerge_idintegerrequiredreview_contact_importFIRST step of importing contacts from a CSV (from another CRM, a phone export, a spreadsheet). Use it when the user pastes or uploads CSV data. It parses the text, auto-maps the columns by header name (pass mapping to correct it, e.g. {"Cell": "phone"}), normalizes every row, flags probable duplicates against the existing rolodex, and stages everything under a batch id WITHOUT touching the contact list. Show the user the summary and, once they confirm, run import_contacts with the batch id. Nothing is imported until then. To import from their connected Gmail or Outlook account instead, use review_email_contacts.
csv_textstringrequiredmappingobjectreview_email_contactsFIRST step of importing the user's contacts from their CONNECTED email account (Gmail or Outlook). Use it when the user asks to import or sync their contacts from their email, Google or Outlook. It reads the address book, normalizes every entry, flags probable duplicates against the existing rolodex, and stages everything under a batch id WITHOUT touching the contact list. Show the user the summary and, once they confirm, run import_contacts with the batch id. Needs the email connected first (connect_email); both providers include contacts in that same authorization.
No parameters.
import_contactsSECOND step of a contact import (CSV or connected email account): executes a batch that review_contact_import or review_email_contacts staged, after the user confirmed the summary. Creates the clean rows, merges the exact duplicates (matching email/phone) into their existing contact, and discards rows flagged for review. Pass treat_duplicates_as if the user decided differently for the flagged ones: "merge" folds them into their closest match, "create" imports them as new contacts anyway, "skip" leaves them out (the default for name-only matches).
batch_idstringrequiredtreat_duplicates_asstringlog_noteWrite a dated note on a contact's timeline. Use it whenever the user tells you something worth remembering about a person: "note that Maria prefers texts after 5pm", "log that I called John about his rate", or after a call/meeting they want recorded. The contact is whatever the user calls them — a name, email or phone fragment. Do NOT use it to change contact fields; that is save_contact.
contactstringrequirednotestringrequireddatestringset_communication_preferencesTurns email or SMS on or off for one person. Use it when someone asks not to be contacted on a channel ("don't email the Garcias", "Maria only wants texts"), or to undo it. Omitting a channel leaves it as it is. Note: a borrower who replies STOP to a text is opted out of SMS automatically and by law — do not turn that back on unless they ask.
contactostringrequiredemailbooleansmsbooleanset_contact_languageSets the language a contact gets their messages in: English or Spanish. Use it whenever the user says someone prefers Spanish ("the Garcias speak Spanish", "write to Maria in Spanish", "send her everything in English from now on"). Every template, reminder and automatic update to that person switches to that language from the next send on; messages already queued keep the language they were written in.
contactostringrequiredlanguagestringrequireddelete_contactPermanently deletes a person from the rolodex. Use it for duplicates or someone added by mistake. It refuses when the person is on a loan or pre-qual — merge them with merge_contacts instead. Ask the user to confirm before calling with confirmar: true.
contactostringrequiredconfirmarbooleanrequiredview_pipelineShows the pipeline: how many pre-quals and loans sit in each stage, who they belong to, how many days each has been in its current stage, and which ones are stalled (more than 7 days in an active stage). Use it when asked "how does my pipeline look", "what do I have going on", "what is stuck", or for any overview of current files. For one specific file use find_loan instead.
tipostringrequiredestadostringfind_loanFinds ONE loan or pre-qual and returns its full file: stage, amounts, property, borrowers, every other participant (realtor, title company…), the financial items collected so far, and the dated milestones. Use it whenever the user asks about a specific file — "how is the Garcia loan going", "what do we have on 412 Elm St", "show me loan 1002941". Accepts a borrower name, a property address, or a loan number.
prestamostringrequiredcreate_prequalCreates a new pre-qualification for a borrower and puts it in the pipeline at "To Be Contacted". Use it when a new lead comes in: "add a pre-qual for Maria Garcia", "new lead: John Smith, 555-0142". If the borrower is not a contact yet, pass their email or phone and the contact is created too. It also takes co-borrowers (up to 3 besides the main borrower: "a pre-qual for the Hassans, Ali and Noor"), priority, notes and who referred the lead. To move an existing file forward use move_stage, not this; to add a co-borrower to a file that already exists use assign_loan_contact.
borrowerstringrequiredemailanyrequiredtelefonostringnullrequiredco_borrowersanyrequiredprioridadanyrequirednotasstringnullrequiredreferralstringnullrequiredprequal_formOpens an interactive pre-qualification form right in the chat, pre-filled with whatever the user already said. Use it when the user wants to create a pre-qual but has not given the details yet ("I want to create a pre-qual", "new lead"), or asks for a form. If they already gave borrower plus phone or email, call create_prequal directly instead — do not make them fill a form they already dictated.
nombrestringnullrequiredemailstringnullrequiredtelefonostringnullrequiredprioridadanyrequirednotasstringnullrequiredcreate_loanCreates a loan directly in the pipeline, without going through a pre-qualification. Use it when a deal arrives already under contract: "create a loan for Robert Miller", "new loan: the Hassans, contract received". Takes up to 4 borrowers (the first is the main one), the initial status (defaults to Contract Received), notes, and the selling agent, listing agent or referral. If the borrower is not a contact yet, pass their email or phone and the contact is created too. To turn an existing pre-qual into a loan use convert_to_loan, not this.
borrowerstringrequiredemailanyrequiredtelefonostringnullrequiredco_borrowersanyrequiredestadostringnullrequirednotasstringnullrequiredselling_agentstringnullrequiredlisting_agentstringnullrequiredreferralstringnullrequiredloan_formOpens an interactive loan creation form right in the chat, pre-filled with whatever the user already said. Use it when the user wants to create a loan but has not given the details yet ("I want to create a loan", "new loan"), or asks for a form. If they already gave the borrower plus phone or email, call create_loan directly instead — do not make them fill a form they already dictated.
nombrestringnullrequiredemailstringnullrequiredtelefonostringnullrequiredestadostringnullrequirednotasstringnullrequiredcontact_formOpens an interactive new-contact form right in the chat, pre-filled with whatever the user already said. Use it when the user wants to add a contact but has not given the details yet ("add a new realtor", "I met someone new"), or asks for a form. If they already dictated name plus email or phone, call save_contact directly instead.
nombrestringnullrequiredemailstringnullrequiredtelefonostringnullrequiredrolstringnullrequiredempresastringnullrequirednotasstringnullrequiredcheck_duplicatesChecks whether a person is already in the rolodex before creating them, and says WHY each match looks like the same person (same email, same phone, similar name) with a 0-1 score. Use it when the user is about to add someone and you want to avoid a second copy, when they ask "do I already have X?", or before create_prequal / create_loan with a brand-new borrower. To create despite the matches, call save_contact with create_anyway.
nombrestringrequiredemailstringnullrequiredtelefonostringnullrequiredsolo_probablesbooleanrequiredtask_formOpens an interactive new-task form right in the chat, pre-filled with whatever the user already said. Use it when the user wants to add a task but has not given the details yet ("add a task", "remind me of something"), or asks for a form. If they already dictated the task ("remind me to call Maria tomorrow"), call save_task directly instead.
titulostringnullrequiredvencestringnullrequireddescripcionstringnullrequiredprestamostringnullrequiredasignadostringnullrequiredseccionstringnullrequiredcheck_missing_dataShows what DATA is still missing on a file — not documents, but facts: FICO score, income on file, purchase price, loan program, closing date… — for the current stage and the next one, with who owes each (borrower, loan officer, realtor, lender, title). Use it for "what is missing on the Garcia file?", "is this file ready to move?", "what do I need before review?". For missing DOCUMENTS use check_documents.
loanstringrequiredmove_stageMoves one or several loans or pre-quals to another pipeline stage and stamps the milestone date. Use it whenever the user reports progress: "the Garcia docs came in" → docs_received, "submitted Elm St to underwriting" → submitted_to_underwriting, "put it on hold", or a batch at once (pass them in prestamos) — with several it moves as many as it can and reports which ones failed, one by one. Some transitions notify the borrower or the realtor automatically: with preview=true it only answers WHAT would be sent, without moving anything — use that when the user asks "what happens if…". With skip_notifications=true it moves silently (e.g. correcting a mistake). The valid stages depend on whether the file is a pre-qual or a loan; if unsure, view_pipeline lists them. To turn a pre-qual into a loan use convert_to_loan instead.
prestamostringprestamosarrayestadostringrequiredpreviewbooleanskip_notificationsbooleanforcebooleanconvert_to_loanConverts a pre-qualification into an active loan, starting it at "Contract Received". Use it when a pre-qual borrower goes under contract: "Garcia got the house!", "we have a contract on Elm St", "convert Maria to a loan". Only works on pre-quals; an active loan moves with move_stage.
prestamostringrequiredupdate_loanUpdates fields on a loan or pre-qual: amount, closing date, tags, file data (address, program, purchase price, down payment, FICO, DTI, rates and lock terms, appraisal status/value, income verification, notes…) or a milestone date (disclosures, lock, appraisal, title, insurance, credit, contract, closing). Use it when the user gives new facts about a file: "the Garcia loan is for $420k", "rate locked at 6.5 until Sep 15", "appraisal came in at $510k", "closing moved to October 3", "tag it VIP". Only pass what changed. To change the pipeline stage use move_stage instead.
prestamostringrequiredmontoanyrequiredfecha_cierreanyrequiredetiquetasanyrequireddatosanyrequiredfechasanyrequiredset_custom_dateCreates, renames, dates or removes a date the loan file needs but the standard milestone catalog does not have. Use it when the user names a deadline that is not one of the built-in milestones: "add an HOA docs due date of Sep 15 to the Garcia file", "rename that date to Attorney Review", "drop the HOA docs date". For a milestone that already exists in the catalog (appraisal, lock, CD, closing…) use update_loan instead. To move a custom date that already exists, either tool works.
prestamostringrequirednombrestringrequiredfechaanyrenombraranyquitarbooleannullupdate_loan_itemsRecords or removes financial items and properties on a loan file: jobs (W2, 1099, VOE), other income (P&L, child support, IRS transcripts), bank accounts, retirement accounts, gift funds, asset depletion, liabilities (incl. IRS or government payment plans, child support payments), and real estate. Use it whenever the loan officer mentions a borrower's income, assets, debts, or properties — e.g. "she works at Amazon, W2, $85k" or "they have a checking account at Chase". For a property, proposed_status in datos says if it is retained, pending sale, or sold with this loan. The document checklist regenerates automatically from these items.
prestamostringrequiredagregaranyrequirededitaranyrequiredquitaranyrequiredarchive_loanArchives one or several loans or pre-quals, or brings archived ones back into the pipeline. Modellus already hides files with no activity for 39 days — use this to disagree with that in either direction: "bring the Garcia loan back", "unarchive 412 Elm", "this one is still alive", "archive the Miller file, it is dead", or a whole batch at once (pass them in prestamos). With several it archives as many as it can and reports which ones failed, one by one. Your choice sticks: the automatic rule will not undo it. This is NOT how you close a loan — to record that a loan closed or was cancelled use move_stage.
prestamostringprestamosarrayarchivarbooleanrequiredassign_loan_contactAdds or removes a participant on a loan or pre-qual by role: borrowers and co-borrowers (up to 4, ordered), realtor, listing agent, title company, appraiser, insurance company, account executive, HOA office, developer, or the file's alt contact — the extra person to call about it, with no particular role. Use it when the user connects people to a file: "the realtor on Elm St is Susan Chen", "add Carlos as co-borrower on the Garcia loan", "the second number on 412 Elm is his daughter", "remove the appraiser from 412 Elm". The person is usually already a contact; if they are not, pass their email or phone and the contact is created and attached in one go.
prestamostringrequiredcontactostringrequiredrolstringrequiredaccionstringrequiredemailstringnulltelefonostringnullassign_loanAssigns one or several loans or pre-quals to someone on the team — who owns the file and shows in the Assigned To column. Use it when the user hands files over: "give the Garcia loan to Ana", "assign 412 Elm to me", "take Ana off the Miller file" (pass asignado: null to leave it unassigned), "put all of these under Ana" (pass them in prestamos). With several files it does as many as it can and reports which ones failed, one by one. To attach a realtor, title company or any outside party use assign_loan_contact instead — that is about contacts, this is about your own team.
prestamostringprestamosarrayasignadostringnullrequiredupdate_conditionsManages the underwriting conditions of a loan: lists them, adds new ones, or marks one as received/approved/rejected/waived. Use it when the loan comes back approved with conditions ("UW wants 2023 tax returns and a gift letter"), when a condition clears ("the gift letter came in", "VOE approved"), or when asked what conditions are still open on a file. Marking one received stamps the day on its own, and if the condition asks for one of the six the office orders from third parties (title work, appraisal, HOA docs, HOI, payoff, LLC docs) it also shows up as received there — no need to mark it twice.
prestamostringrequiredaccionstringrequiredcondicionesanyrequiredcondicionstringnullrequiredasignadostringnullestadoanyrequireddocumento_origenstringresend_statusRe-sends the status messages the file already earned, without moving it. Use it when a borrower or realtor says they never got the update, or lost the link: "resend the status to Maria", "send the link again". It sends exactly what that stage sends — to write something different use send_message.
prestamostringrequiredview_logsShows the change history of one loan, pre-qual or contact: what changed, when, and what triggered it. Use it when the user asks "what happened with the Garcia file", "when did this move to underwriting", "history for Maria", "view logs". Name the record the way the user does — borrower name, address, loan number, person name.
prestamostringcontactostringlimiteintegerdelete_loanPermanently deletes a loan or pre-qualification and everything hanging off it: participants, documents, financial items and history. Use it ONLY for a file created by mistake or a duplicate. A file that did not close is NOT deleted — move it to Cancelled or Archived with move_stage so its history survives. Ask the user to confirm before calling with confirmar: true.
prestamostringrequiredconfirmarbooleanrequiredview_arive_loansLists loans that live in Arive, the external loan origination system where the team builds the lender package. Use it when the user asks what is in Arive, wants to search Arive by borrower name, email, phone or loan number, or wants to compare Arive against the files tracked here. Read-only: nothing in Modellus can change Arive. For files tracked in Modellus use view_pipeline or find_loan instead. For the full detail of one Arive loan use view_arive_loan.
searchstringlimitintegerview_arive_loanShows the full file of ONE loan as it stands in Arive, the external loan origination system: status, amounts, rate and lock, key dates, borrowers, loan team and business contacts (title, escrow…), plus the direct link to open it in Arive. Use it when the user asks how a specific loan looks in Arive, for a rate/lock/key-date that only Arive has, or to compare an Arive file against the one tracked here. Accepts a borrower name or an Arive loan number. Read-only: to change anything, the team edits it in Arive itself.
loanstringrequiredconnect_ariveConnects this account to Arive, the external loan origination system, using API credentials from Arive (client id, secret key and API key). Use it when the user pastes their Arive API credentials, asks to connect or reconnect Arive, or when an Arive action failed because Arive is not connected yet. It validates the credentials live against Arive before saving, so wrong keys never get stored. Never repeat the credentials back in chat.
client_idstringrequiredsecret_keystringrequiredapi_keystringrequiredset_arive_cutoffSets (or clears) the Arive cutoff date: loans CREATED in Arive before this date are never brought into Modellus, so a migration from the old system does not get duplicated by the sync. Loans already here keep being refreshed no matter how old they are. Use it when the user asks to only bring loans from a date onward, to change or remove that date, or when import_arive_loans reported older loans left out and they want them in from now on. Pass an empty string to remove the cutoff entirely (everything in Arive becomes importable). view_integrations shows the date currently in effect.
created_afterstringrequiredset_arive_liveTurns Arive live updates on or off. With them on, a change made in Arive shows up here within seconds instead of waiting for the sync that runs every 15 minutes (that sync keeps running either way, as a safety net). Use it when the user says Arive changes take too long to appear, asks for real-time or instant sync, or wants to stop the live updates. Pass action "status" to just report whether they are on.
actionstringrequiredimport_arive_loansImports the active/pending loans from Arive into the Modellus pipeline: creates each loan with its borrowers (deduplicated against existing contacts), mapped stage, amounts, key dates and the link back to Arive. Closed, cancelled, funded and archived loans stay in Arive. Safe to run again: a loan already imported is refreshed (stage, data, dates), never duplicated. Use it when the user asks to bring, sync or import their Arive loans or pipeline into Modellus. ALWAYS run it first with preview=true and show the user what would be imported; only run with preview=false after they confirm. Requires Arive to be connected on this account (connect_arive). What it brings in for the first time lands in the New Client inbox waiting to be reviewed (view_new_clients / review_new_client), not straight into the pipeline. By default it only brings what Arive created AFTER the account cutoff date; older_than_cutoff in the result says how many were left out, so tell the user "there are N older ones, want them too?" and re-run with include_older=true if they say yes (set_arive_cutoff changes the date for good).
previewbooleanrequiredlimitintegerinclude_olderbooleanresync_loanPulls ONE loan from Arive right now and applies what changed, instead of waiting for the sync that runs every 15 minutes. Use it when the user says something was just changed on the Arive side and they want it here: "refresh the Garcia loan from Arive", "the processor just updated 412 Elm, pull it", "this one looks out of date". Hand-edited fields are kept unless Arive changed that same field. To bring in loans that are not in Modellus yet, use import_arive_loans instead.
prestamostringrequiredview_new_clientsLists the New Client inbox: loans that came in from Arive and nobody has reviewed yet — each one still has to be accepted as a loan, accepted as a pre-qualification, or ignored. Use it when the user asks what came in from Arive, what is waiting for review, what is in the New Client list, or how many new clients are pending. Pass `query` to look for one of them by borrower, email, phone, address or loan number. Each row brings the borrower with their email, phone and property, the Arive id and link, and how many files that person already has here. To act on one of them use review_new_client. For the files already being worked use view_pipeline instead.
showstringquerystringlimitintegerreview_new_clientDecides what happens with one loan sitting in the New Client inbox (the ones imported from Arive that nobody has reviewed). Use it when the user says to accept, take, keep, convert or ignore something that came in from Arive: "keep the Garcia one as a loan", "that one is just a pre-qual", "ignore the 412 Elm file". decision=loan keeps it as an active loan, decision=prequal turns it into a pre-qualification, and decision=ignore DELETES it here and stops future imports from bringing it back — always confirm with the user before ignoring. decision=restore undoes an ignore (pass the Arive id) so the next import brings that loan again. List what is waiting with view_new_clients.
loanstringrequireddecisionstringrequiredcheck_documentsShows the document checklist. With a loan (a phrase like "the Martinez loan" or an address), it lists every document grouped by status and by who owes it. Without a loan, it gives a cross-pipeline report of every loan with pending documents and how many days they have been waiting. Use it whenever the user asks what is missing, what came in, or what is stuck.
loanstringrequest_documentsPrepares the document request for a loan: refreshes the checklist, groups what is missing by who owes it (borrower, realtor, title company, HOA), creates a secure upload portal link for each party, and queues a reminder message (email and text, whichever the contact has) with the link and the list of missing documents. Use it when the user wants to chase, collect or request the missing documents of a loan. The messages go out within a minute; the response says exactly what was queued to whom.
loanstringrequiredsoloarraymodostringconfirmarbooleanreview_documentCloses out a document that came in: approve it, reject it, or flag it as incomplete. Identify it by document id, or by loan plus document type ("reject the bank statement on the Martinez loan"). Use 'missing_information' when what arrived is right but partial (only page 1 of 4 came through) — it asks for the missing piece instead of the whole document again; use 'reject' when it is the wrong or unusable document. Both need a reason: it is what the borrower reads to fix it. Approving takes optional notes for the file. Use it when the user reviews paperwork from the chat instead of the review queue.
document_idintegerloanstringdocument_typestringdecisionstringrequiredreasonstringnotesstringupdate_documentSets what is expected of one document on a loan: the period it has to cover ("bank statements from January to March", "the 2024 tax return"), a note for whoever provides it, and where it stands: still pending, already requested and waiting on them (follow_up), already received by other means, or not applicable to this file. It is ALSO how you change WHO the document is asked from ("ask the realtor for the HOA questionnaire on this one", "the insurance binder goes to the insurance agent, not the borrower") — there is no rule per document type, the loan officer decides case by case, and the request messages follow whoever is set here. Use it when the user says "the statements should be Jan through Mar", "I already have the W-2, mark it in", "I just chased him for the paystub" (follow_up), "we do not need the survey here", or "ask Maria for that one instead". If the document is not on the loan’s checklist yet it gets added, so you can set a status on any document type without a second step. Every status change stamps its own date — you only pass status_date when the user names a different day. To approve or reject a file that came in, use review_document. For the six the office orders from third parties (title work, appraisal, HOA docs, HOI, payoff, LLC docs) order_docs says it in one word and covers the whole package.
document_idintegerloanstringdocument_typestringperiod_fromstringperiod_tostringnotestringrequest_fromstringstatusstringstatus_datestringorder_docsThe "Docs Ordered" board of a loan: the paperwork the office orders from third parties — Title Work, Appraisal, HOA Docs, HOI, Payoff, LLC Docs. Unlike the rest of the checklist, nobody chases these from the borrower: they are ordered from title, the appraiser, the HOA or the insurance agent, and what matters is WHAT DAY they went out, so someone can call when they take too long. Use it when the user says "I ordered the appraisal", "title work is out", "HOA docs came back today", "payoff received", "did we order HOI on the Miller file?", or "what is still not ordered". Ordering stamps the date on its own — only pass status_date when they name a different day ("I ordered it Monday"). Leave `document` out to see the whole board. HOA Docs and LLC Docs are packages: one word covers every paper in them. For any other document type use update_document, and for underwriting conditions use update_conditions — a condition that asks for one of these six already shows up here as received on its own.
loanstringrequireddocumentstringstatusstringstatus_datestringattach_documentFiles a document the user attached in the chat into a loan's document checklist. Use it when the user uploads a file and says what it is: "this is Robert's W2", "here's the signed contract for the Garcia loan". The file_path comes from the "[Attached document: … — path: …]" note in the conversation — never invent it, and never ask the user for it. Identify the checklist entry by loan plus document type (or by document id from check_documents). The document is marked as received, ready for review.
file_pathstringrequiredfile_namestringdocument_idintegerloanstringdocument_typestringdocument_versionsLists every version of one checklist document: each time it was sent in, who sent it, when, how it was closed out (approved, rejected, incomplete) and a link to open that exact file. Use it when the user asks about a resubmission — "what did he send the first time?", "show me the previous bank statement", "how many times have we asked for this?" Identify the document by id (from check_documents) or by loan plus document type.
document_idintegerloanstringdocument_typestringsend_portal_linkCreates (or renews) the secure upload portal link for one contact on one loan and returns the URL. Use it when the user asks for the link of a specific person — "resend the portal to Maria", "give me the upload link for the title company". Previous links for that person keep working until they expire (30 days).
loanstringrequiredcontactstringrequiredadjust_checklistAdjusts the checklist of ONE loan by hand: adds documents the rules did not derive ("also ask for a divorce decree") or marks documents as not applicable ("we do not need the survey on this one"). This is how you ask ONE borrower for their personal paperwork — their ID (driver's license, passport, social security card), their immigration documents (green card, visa, work permit, asylum documents), the VA ones (certificate of eligibility, DD-214) — and how you ask for a letter of explanation, which can be asked for several times on the same file, one per subject. For changing the office-wide rules use edit_checklist_rules instead.
loanstringrequiredaddarrayremovearrayview_checklist_rulesExplains the active document checklist rules of this office in plain English, including any per-account overrides (disabled types, how many bank statements or tax return years). With a loan, it also explains which rule generated each document on that checklist. Use it when the user asks why a document is being requested or how the checklist works.
loanstringedit_checklist_rulesChanges the office-wide checklist rules: disable a document type so it is never requested ("we never ask for surveys"), re-enable it, or change quantities ("ask for 3 bank statements", "1 year of tax returns"). Applies to every loan the next time its checklist syncs. For one specific loan use adjust_checklist instead.
disablearrayenablearraybank_statementsintegertax_return_yearsintegerw2_yearsintegerread_approval_conditionsReads a lender approval document — the PDF the bank sends when a loan is approved with conditions, or a photo or screenshot of it — and pulls out the underwriting conditions as a clean list: bank statements, mortgage statements, rental income, liability verifications, letters of explanation. Use it whenever the user attaches an approval, a conditional approval or a commitment letter ("here is the approval", "pull the conditions off this", "the bank sent this back"). The file_path comes from the "[Attached document: … — path: …]" note in the conversation — never invent it. This only READS: nothing is saved. Show the user the list, let them drop the ones that do not belong, and only then call update_conditions with accion 'add' to put them on the file.
file_pathstringrequiredfile_namestringloanstringsend_messageSends an email, text (SMS) or WhatsApp message to a contact, written free-form or from a template. IMPORTANT: it is a two-step action — call it first WITHOUT confirm to get the rendered draft, show that draft to the user and ask for their approval, and only when they approve call it again with confirm=true to actually send. Use it when the user wants to message, email or text someone: "text Maria that we are waiting on her W-2", "send the Garcias the welcome email". For reading past messages use view_conversation.
contactostringrequiredcanalstringmensajestringasuntostringplantillastringvariablesobjectconfirmbooleanview_conversationShows the message history (emails, texts, WhatsApp — sent and received) with a contact, or all the messages around a loan. Use it when the user asks "what have we sent Maria?", "did the reminder go out?", "show me the thread on the Garcia file". Give it a contact or a loan (at least one).
contactostringloanstringlimiteintegerview_templatesLists the message templates: their key, what each one says by default, whether the account customized them, and which pipeline transition triggers each one automatically. Every template exists in English and Spanish, for email and for text, and asking for one key returns all four bodies — each contact receives the language their profile says (set_contact_language changes it). Use it when the user asks what messages go out, wants to see a template before editing it, or before send_message with a template key. To change one, use edit_template.
clavestringedit_templateEdits a message template for this account: saves a draft (default) or publishes it (publish=true) so it replaces the stock wording in every future send. Use it when the user wants to change what a message says: "make the docs reminder friendlier", "add my calendly to the welcome email". Variables go in double braces — {{borrower_name}}, {{portal_link}}… — view_templates lists each template's variables. Every template exists in English and Spanish: pass idioma='es' to change the Spanish wording, which is what Spanish-speaking borrowers receive. It always returns a test render with sample data: show it to the user.
clavestringrequiredcanalstringrequiredidiomastringcuerpostringrequiredbloquesanyrequiredasuntostringpublishbooleanrestablecerbooleannullrequiredgenerate_preapproval_letterGenerates the official pre-approval letter (PDF) for a loan: amount, program, expiration and the standard disclaimers, signed by the loan officer. It uploads the PDF to the file's documents and returns a download link that lasts 7 days. Use it when the user asks for a pre-approval letter: "generate the pre-approval for Garcia", "make me a letter for 320k for the Elm St file". Amount and expiration are optional: without them it uses the loan amount on file and 60 days.
loanstringrequiredmontonumberexpirastringtasanumberview_automationsShows every automation of the account: which are on or off, their cadence in days, when the scheduled jobs run, and the two master switches (email and text messages) that sit above all of them. Use it when the user asks "what runs automatically", "is the document reminder on", "how often do borrowers get reminded", "why is nothing going out", or before changing one. To turn one automation on/off or change its cadence use set_automation; to turn a whole channel on or off use set_channel.
No parameters.
set_automationTurns an automation on or off, or changes its cadence in days. Use it when the user says "stop reminding borrowers", "turn the document reminder back on", "remind every 5 days instead", or any change to what runs automatically. The automation is whatever the user calls it ("the document reminder"); view_automations lists the exact keys.
automationstringrequiredenabledbooleancadence_daysintegerset_channelTurns a whole messaging channel on or off for the entire account: email, text messages (SMS and WhatsApp), or both at once. Use it when the user wants everything to stop or restart, not one automation and not one person: "stop all texts", "pause every email while I am out", "turn messaging back on". While a channel is off, nothing goes out through it — automations included — and whatever the app tries to send is held as blocked so it can be retried later with retry_message. To see how the switches are right now use view_automations; to stop just one automation use set_automation; to stop messaging one person use set_communication_preferences.
channelstringrequiredenabledbooleanrequiredview_deliveryShows the outgoing messages that did not make it: the ones the provider rejected after every retry, and the ones held back because the account had that channel turned off. Also reports how many are waiting in the queue and how the master switches are. Use it when the user asks "did that email go out", "why has Maria not heard from me", "is anything stuck", "what failed", or when a message they expected never arrived. To send one again use retry_message; to turn a channel back on use set_channel.
limiteintegerretry_messageSends a failed or blocked outgoing message again: it goes back into the queue and leaves within a minute. Use it after view_delivery shows something stuck and the user says "try again", "resend that", "send them all again". Pass the message id from view_delivery, or all=true to retry every stuck message at once. A message cancelled because the person opted out is never retried.
message_idintegerallbooleanview_calendarShows the calendar for a SPECIFIC period — one day, one week, one month — with the tasks and the critical loan dates that fall in it, grouped day by day, plus the link to that same view of the calendar screen. Use it when the user names a period instead of asking what is pending: "what does the week of the 15th look like", "show me October", "what do I have on Tuesday", "open the calendar on the week view", "how does next month look". For the plain to-do list ("what is overdue", "what is pending") use view_tasks; to create or close a task use save_task; to change a loan date use update_loan.
viewanyrequireddatestringnullrequiredview_tasksLists tasks AND the critical loan dates falling in the same window — closings, commitment dates, and rate lock, credit or pre-approval expirations. Use it when the user asks "what do I have today", "what is on my calendar this week", "what is overdue", "what is closing soon", "is any lock about to expire", or wants the to-dos of one loan, one contact, or one team member. Filters combine: due window, loan or contact as a phrase ("the Garcia file", "Maria"), assignee ("me", a name, an email). By default it shows pending tasks only; ask for done or cancelled explicitly. It also returns the sections the list is grouped into and which section each task is in. To create or change a task use save_task; to change the sections themselves use set_task_sections; to change a loan date use update_loan.
duestringstatusstringloanstringcontactstringassigneestringsectionstringloan_datesbooleansave_taskCreates or updates a task. Use it when the user wants to remember to do something ("remind me to call Maria on Friday"), completes one ("done with the CD review"), cancels one, edits its title, due date or details, adds or checks off subtasks, ties it to a loan or contact, assigns it to a team member, moves it into or out of a section, or reorders it — to the top or bottom of its list, or right above or below another task ("put the appraisal call under the CD review"), which is what dragging a card by its grip does. To create, give a title; to change an existing one, name it by its id or by words from its title. To list tasks use view_tasks; to delete one for good use delete_task; to create, rename or reorder the sections themselves use set_task_sections.
taskstringtitlestringdescriptionstringduestringstatusstringsubtasksarrayadd_subtasksarraycheck_subtaskstringloanstringcontactstringassigneestringsectionstringpositionstringafterstringbeforestringreviewedbooleandelete_taskPermanently deletes a task. Use it ONLY for one created by mistake or a duplicate. A task that was decided against is NOT deleted — set its status to 'cancelled' with save_task so it stays on the record. Ask the user to confirm before calling with confirmar: true.
taskstringrequiredconfirmarbooleanrequiredset_task_sectionsCreates, renames, deletes or reorders the sections that group the task list ("Follow-ups", "Closings this week"). Use it when the user wants to organise their tasks by category, says "add a section", "rename that group", "get rid of that section" or "move Closings to the top". Deleting a section does NOT delete its tasks: they go back to being unsectioned. To put a task into a section use save_task with section; to see the sections use view_tasks.
addarrayrenamearrayremovearrayorderarrayproduction_reportProduction report for a period: how many loans closed, total volume, and estimated commission, compared against the previous equivalent period. Use it when the user asks "how did I do this month", "what did I close in Q2", "my production last year", or any question about closings, volume, or commissions over time. For who referred the business use referral_report; for how long stages take use stage_timing_report.
periodstringreferral_reportReferral report for a period: which sources brought the business — deals, volume, and conversion per source. Use it when the user asks "who is sending me business", "which realtor referred the most this quarter", "where are my deals coming from", or wants to know whom to thank or nurture. For totals closed use production_report.
periodstringstage_timing_reportHow long each pipeline stage typically takes, averaged from this account's closed loans, and which active loans are currently taking longer than that typical time. Use it when the user asks "how long does underwriting take me", "where do my loans slow down", "which files are behind schedule", or wants process insights. For a plain list of stalled files (fixed 7-day flag) use view_pipeline.
No parameters.
weekly_summaryThe weekly summary email, generated on demand: what moved stages this week, which documents came in, what is stalled, what closes in the next two weeks, and overdue tasks — as ready-to-send text. Use it when the user asks "give me my weekly summary", "how was my week", "what happened this week", or wants a recap to forward. The same summary goes out automatically by email every week.
No parameters.
view_permissionsShows what each role in this account can do (read, edit files, send messages, delete, manage the account) and which columns each role cannot see. Use it when the user asks "what can my assistant do", "why can't I see the rate", "what is hidden from the processor", or before changing access with set_column_access.
No parameters.
set_column_accessHides or shows specific columns for a role (assistant or loan officer), across the lists and the loan file. Use it when the user says "assistants should not see the rate", "hide the credit score from my processor", "let loan officers see compensation again". Only the account owner can do this. To see what is hidden today, use view_permissions.
rolstringrequiredesconderarrayrequiredmostrararrayrequiredview_join_linkShows the public sign-up link of this account: the URL to put in an email signature or an Instagram bio, whether it is on, and what the page says. Use it when the user asks "what is my link", "give me my sign-up link", "is my public page on", or before changing it with set_join_link.
No parameters.
set_join_linkTurns the public sign-up link on or off, changes its name (the last part of the URL) and the words on the page. Use it when the user says "turn on my public link", "my link should be maria-garcia", "change the headline", "turn off the sign-up page". Only the account owner. To see the current link use view_join_link.
nombrestringnullrequiredactivobooleannullrequiredtitularstringnullrequiredsubtitulostringnullrequiredgraciasstringnullrequiredview_teamLists the team of this account: the owner plus every invited assistant, with name, email, and role. Use it when the user asks "who is on my team", "who has access to my account", or before inviting, removing, or changing the role of someone, to confirm who is already in. To change what someone is, use set_teammate_role.
No parameters.
invite_teammateInvites a person by email to join this account: they get full day-to-day access (contacts, pipeline, documents) but cannot manage the team or the settings. Only the account owner can do this. Use it when the user says "invite my assistant", "add maria@x.com to my team", "give my processor access", "invite John as a loan officer". Returns the invitation link too, in case the email does not arrive.
emailstringrequiredrolestringinvitation_linkLists the invitations that are still waiting for an answer and, for one person, issues a fresh invitation link to share by hand. Use it when the user says "the invitation email never arrived", "resend the invite to maria", "give me the link for my assistant", or asks who has not accepted yet. It also reports whether the account email channel is on: while it is off no invitation email goes out at all, and the link is the only way in — turn it back on with set_channel. Issuing a new link invalidates the previous one for that person. Only the account owner, signed in from their own session.
personstringset_teammate_roleChanges what someone already on the team is: an assistant (a processor or assistant helping with the book) or a loan officer (another originator working the same pipeline). Only the account owner can do this. Use it when the user says "make Maria a loan officer", "John is my assistant, not an LO", "change Ana's role". The owner's own role cannot be changed.
memberstringrequiredrolestringrequiredremove_teammateRemoves an assistant from this account by email or name, revoking their access immediately. Only the account owner can do this. Use it when the user says "remove maria from my team", "revoke access for x@y.com", "my assistant left". The owner cannot be removed.
memberstringrequired