acknowledge_activity_alerts
ChatGPTMark activity alerts as seen (by id from list_activity_alerts) — administrators.
activity_summary
ChatGPTThe busiest tables, sources and people in the audit trail over the last N days (administrators), and how far back the trail goes.
add_ai_memory
ChatGPTGive Command Center a standing instruction it applies to every answer from now on (one line, at most 500 characters). scope 'user' (default) is just for you; 'tenant' applies to everyone in the workspace and is for administrators.
add_column
ChatGPTPropose adding one column to an existing business table. Existing columns and rows are untouched. Where AI tools are given that table column by column, the new column is added to their lists. Nothing changes yet: this returns a proposal (pending_id). Show it to the user; only after they agree, call confirm_action with the pending_id.
add_dashboard_tile
ChatGPTPropose adding a tile to a dashboard: a name and ONE read-only SELECT (tables from describe_schema; {{user_id}}, {{today}}, {{week_start}}, {{month_start}} allowed), optionally how to display it ({tool, args, map} — display_table/list/chart…). The query is test-run first; added on confirm_action.
agent_task_detail
ChatGPTOne personal-agent task in full: goal, linked records, status, the agent's notebook, the owner's notes, the current proposal and draft message, and its timeline of checks and updates (newest first).
agent_updates
ChatGPTWhat the user's personal agents reported recently: every update and proposal across their tasks in the last N hours, newest first.
ai_activity_log
ChatGPTWhat AI connections did in this workspace, newest first (administrators): each tool call and record read, with the key, its owner, the tool, whether it worked (and the error), how long it took, and a summary of its arguments.
ai_usage_summary
ChatGPTAI connection use over the last N days (administrators): calls and errors per key, per person and per tool.
analyze_funnel
ChatGPTQuote-to-close funnel over a date range: quotes created, sent/pending, accepted, and the accepted rate. Use for 'conversion rate' / 'pipeline funnel'.
apply_late_fee
ChatGPTApply the configured late fee to an overdue invoice (adds late_fee_amount to balance_due, sets late_fee_applied). (writes — confirm-gated). Nothing is saved until confirm_write applies the pending_id it returns when it stages the change.
apply_schedule
ChatGPTPrepare a schedule change for jobs: technician and/or date and/or start time per job (e.g. the assignments a planner returned). Dry-runs it and returns a before→after preview and a pending_id; nothing changes until confirm_write (allow_bulk over 5 jobs), and undo_write reverses it. At most 200 jobs.
ar_aging
ChatGPTAccounts-receivable aging: unpaid invoices with how many days past due. Use for 'AR aging', 'overdue invoices', 'who owes us'.
broken_promises
ChatGPTLists every tech note that says 'follow up', 'revisit', 'call back', 'next week' etc., cross-referenced against whether the SPECIFIC promised action actually happened (invoice on that job, follow-up job created, payment received against that job's invoice, or communication sent about that job). Shows ONLY the promises that were never fulfilled.
bulk_reschedule_jobs
ChatGPTMove every open job on one date to another date (e.g. weather day, tech on leave). Optionally limit to one technician. Use for "reschedule all of Friday to Monday", "push tomorrow due to storms". (writes — confirm-gated). Nothing is saved until confirm_write applies the pending_id it returns when it stages the change.
calculate_route
ChatGPTThe best order to visit up to 50 stops by road, as a round trip: the stops in visiting order with how long after the start each is reached, and the total drive time and distance. Each stop is {lat, lng} (from a record) or an address (at most 10 addresses a call), with an optional label, id and on-site minutes. Without home_base the trip starts and ends at the first stop. Traffic isn't included. Nothing is saved or assigned — to plan technicians' days, use plan_day_routes.
cancel_action
ChatGPTDrop a proposed action without doing it.
cancel_email_followup
ChatGPTCancel your follow-up reminder on a thread.
cancel_write
ChatGPTDiscard something prepared but not yet applied — a change from propose_write or a message from draft_email/draft_sms.
change_alert
ChatGPTPause, resume or delete one of your alerts, or check its current value now (check_now sends nothing).
change_scheduled_report
ChatGPTPause, resume or delete (unschedule — the saved question stays) one of your scheduled reports, or run it now to see its row count (sends nothing).
churn_risk
ChatGPTScans customer feedback (satisfaction ratings + written feedback), and both job-level and customer-level notes for churn risk signals. Returns each flagged customer with the exact sentence that flagged them and the full context.
close_agent_task
ChatGPTClose one personal-agent task: mark it done (with what was achieved) or stopped (the user no longer wants it pursued). The agent stops checking it. (writes — confirm-gated). Nothing is saved until confirm_write applies the pending_id it returns when it stages the change.
compare_record
ChatGPTHow a record's fields differ between an earlier time and now (or between two times) — for "what changed on job 42 since Monday?". The table must have history switched on.
complete_job_task
ChatGPTTick off a job checklist item (sets done=true). (writes — confirm-gated). Nothing is saved until confirm_write applies the pending_id it returns when it stages the change.
confirm_action
ChatGPTCarry out an action another tool proposed (it returned a pending_id): only after the user has seen the proposal and agreed. Runs it once; a second confirm is refused.
confirm_promotion
ChatGPTApply a promotion prepared by plan_promotion, after the user has agreed. Tables are added first, then apps are saved as DRAFT versions (publish_app makes them live), automations and agents are saved switched OFF.
confirm_send
ChatGPTSend messages prepared by draft_email or draft_sms. Call ONLY after the user has read the drafts and agreed — these reach real people and can't be recalled. Returns a result per recipient: queued, skipped (opted out, outside allowed hours) or failed.
confirm_write
ChatGPTApply a change prepared by propose_write (or a custom action). Call ONLY after the user has seen the preview and agreed. Returns the rows changed and an undo_id. Set allow_bulk: true only when the proposal said requires_bulk_confirmation and the user agreed to change that many rows.
convert_quote_to_invoice
ChatGPTTurn an accepted quote into an invoice, copying its line items across. Use for "convert this quote to an invoice", "invoice quote 842". (writes — confirm-gated). Nothing is saved until confirm_write applies the pending_id it returns when it stages the change.
create_activity_alert_rule
ChatGPTPropose an activity alert rule (administrators). kind: bulk_delete, bulk_change, off_hours, field_change, new_actor_table. config — bulk_delete / bulk_change: {threshold (default 25), window_minutes (default 5), tables?}; off_hours: {timezone, start_hour, end_hour, days ([1..5] = Mon–Fri), tables?}; field_change: {table, field, to?, from?}; new_actor_table: {tables?, actor_types?}. It is dry-run against the last day of activity first; confirm_action saves it (it only alerts on what happens next).
create_alert
ChatGPTPropose a data alert. Three kinds: preset (new_customers, new_leads, new_requests, new_jobs, overdue_invoices, unassigned_jobs, unaccepted_quotes); new_rows — notify when a row is ADDED to a table (optionally matching a condition); threshold — a SELECT returning one number, compared to a threshold. It is test-run now and created only by confirm_action. Tell the user what it watches and where it notifies — not the SQL.
create_app
ChatGPTCreate a NEW app from complete compiled_data. It is saved as version 1, not live — publish it with publish_app. Read get_widget_docs('app') and ('view') first (platform 'mobile' for a mobile app). Set type: "web" for a web app; omit it for a mobile app. Like every save it is checked: lint, every SQL statement against this workspace's tables, and navigation targets. Apps are private: never set is_public, visibility: "public" or auth_table — people outside the company get a public form or portal-user logins.
create_customer_with_contacts
ChatGPTCreate a customer with contacts and/or locations in one confirm. params: company_name?, first_name?, email?, phone?, contacts(json array {first_name,last_name?,email?,phone?}), locations(json array {location_name,address_line1?}). (writes — confirm-gated). Nothing is saved until confirm_write applies the pending_id it returns when it stages the change.
create_dashboard
ChatGPTPropose a new, UNPUBLISHED dashboard (only you see it until you publish it in the app). Created on confirm_action.
create_job_signoff_link
ChatGPTMake a sign-off link for one job, for a subcontractor (no login needed): they see the job and can record completion. Returns the URL and how long it lasts.
create_job_with_tasks
ChatGPTCreate a job for a customer with a checklist of tasks in one confirm. params: customer_id, title, service_type?, tasks(json array of task labels). (writes — confirm-gated). Nothing is saved until confirm_write applies the pending_id it returns when it stages the change.
create_purchase_order
ChatGPTCreate a purchase order with line items. params: supplier_id?, job_id?, notes?, items(json array {description,quantity,unit_cost}). (writes — confirm-gated). Nothing is saved until confirm_write applies the pending_id it returns when it stages the change.
create_recurring_visits
ChatGPTSet up a recurring weekly visit schedule AND generate the first N visit jobs in one confirm. Use for "set up weekly Tuesday maintenance for X", "recurring visits every Friday for a month". params: customer_id, title, weekday(name or 0-6), occurrences(default 4), service_type?, start_date?, technician_userid?. (writes — confirm-gated). Nothing is saved until confirm_write applies the pending_id it returns when it stages the change.
create_sandbox
ChatGPTMake a private copy of this workspace to build and test in. The copy's automations and mailbox sync are off, it can send no email, texts or calls, and it is deleted after 7 days unless extended. IMPORTANT: making the copy disconnects everyone using the LIVE workspace for a few seconds, and a save in progress at that moment can fail — ask the user first. One sandbox at a time, one new sandbox a day. Returns a new MCP key and URL for the copy: add it to the AI client as a second connection.
create_service_contract_with_lines
ChatGPTCreate a service contract with its covered-service line items. params: customer_id, title, start_date, end_date, lines(json array {service_name,description?}). (writes — confirm-gated). Nothing is saved until confirm_write applies the pending_id it returns when it stages the change.
create_sold_hour_quote
ChatGPTCreate a labour/sold-hour quote (header + labour line item) in one confirm. Use for rate-based estimates like "quote 6 hours at our sold-hour rate". (writes — confirm-gated). Nothing is saved until confirm_write applies the pending_id it returns when it stages the change.
create_stock_transfer
ChatGPTCreate a stock transfer between two technicians with items. params: from_technician_userid, to_technician_userid, notes?, items(json array {item_master_id,quantity_requested}). (writes — confirm-gated). Nothing is saved until confirm_write applies the pending_id it returns when it stages the change.
create_table
ChatGPTPropose a new business table. id, created_at and updated_at are added automatically. Name it in plural snake_case (e.g. site_visits). Read get_widget_docs('tenant-schema') for the conventions first. Once confirmed, the table exists and AI tools may read, insert and update it (it is added to Command Center's settings; deleting rows stays off until an administrator turns it on). Nothing changes yet: this returns a proposal (pending_id). Show it to the user; only after they agree, call confirm_action with the pending_id.
customer_churn_feedback_flags
ChatGPTFinds customers whose job feedback contains churn-risk language or a low satisfaction rating, and returns the exact sentence that triggered each written-feedback flag (or the rating evidence when no sentence matches).
customer_churn_sentence_flags
ChatGPTFinds customer feedback sentences with explicit dissatisfaction or churn signals and returns the customer, related job, rating, and the exact sentence that triggered the flag.
decide_approval
ChatGPTPropose approving or rejecting a waiting automation step (by approval_id from list_pending_approvals). The automation continues (or stops) right after confirm_action; once approved, its next steps run as written, and they may send email or texts or call outside services.
delete_sandbox
ChatGPTDelete a sandbox and everything in it, now. The live workspace is not touched. Ask the user first.
delete_saved_view
ChatGPTDelete a saved filter preset: your own, or (administrators) a shared one.
delete_service_zone
ChatGPTPropose deleting a service zone for good (administrators); confirm_action does it. Its membership goes with it, and automations watching only this zone stop firing.
describe_schema
ChatGPTDescribe the workspace's data tables you may read. With no tables, returns every readable table on one line each (name, description, first columns). With tables, returns their full column lists, types, foreign keys and notes. Call this before writing SQL.
dismiss_failed_run
ChatGPTPropose marking a failure as handled so it leaves the worklist (the run stays failed in history). Pass run_id, or outbox_event_id for a failed record-change event. Applied with confirm_action.
dispatch_query
ChatGPTPer-technician capacity in ONE call. mode='availability' (date): booked minutes + job count per tech on that day, lightest first. mode='workload' (from_date,to_date): booked minutes + job count per tech over a range. Use this instead of looping find_jobs per tech.
draft_sms
ChatGPTPrepare one or more text messages WITHOUT sending them. Returns the drafts and a pending_id; nothing is sent until confirm_send. At most 20 per draft and per hour. Opted-out numbers are skipped at send time.
drive_time
ChatGPTRoad drive time (minutes) and distance (km), one way, from one place to another. Each place is an address or {lat, lng}. Traffic isn't included. Places outside the routing network's coverage are refused with the region named.
drop_column
ChatGPTPropose deleting a column that was added through MCP (add_column, or any column of a table made with create_table) — with its values; it can't be undone. id, created_at and updated_at stay. Nothing changes yet: this returns a proposal (pending_id). Show it to the user; only after they agree, call confirm_action with the pending_id.
drop_table
ChatGPTPropose deleting a table that was created through MCP (create_table) — with every row in it; it can't be undone. Tables the workspace already had can't be dropped here, nor one that another table links to (drop that link first). The proposal shows how many rows would go and which screens, automations and tools mention the table. Nothing changes yet: this returns a proposal (pending_id). Show it to the user; only after they agree, call confirm_action with the pending_id.
edit_view
ChatGPTChange part of one screen without resending it, saved as a new DRAFT exactly like save_draft (same checks; nobody sees it until publish_app). Each op targets a widget by element_id and/or a JSON Pointer path (relative to that widget when both are given): set (replace a value or add a key), remove, insert (into an array: /children/2 before item 2, /children/- at the end). Find targets with get_view outline: true. base_hash is required (from get_view / get_app, or from your previous save — use that one to make several edits in a row; they stack in one draft).
explain_change
ChatGPTExplain WHY a number changed between two periods: the change split by a dimension (status, technician, service type, customer…), biggest movers first, with values that appeared or disappeared flagged. Give the table, the metric (a count, or the sum or average of a numeric column), the dimension, the date column that places each row in a period, and the baseline (period_a) and comparison (period_b) windows. Try another dimension when the first doesn't explain it.
export_csv
ChatGPTRun one SELECT and save the result as a CSV file (up to 10000 rows); returns a download link. The link is public — anyone who has it can open the file — so share it only where the user intends.
extend_sandbox
ChatGPTKeep a sandbox longer: push its expiry out by 1–30 days (at most 90 days from when it was made).
find_communications
ChatGPTFind SENT emails/SMS from the communications log (distinct from drafts awaiting a Send click). Filter by channel and/or customer.
find_contracts
ChatGPTFind service contracts, optionally expiring soon. Returns id (DB pk), customer name, status, end_date.
find_customers
ChatGPTFind customers / leads by name or company. Returns id (DB pk), name, email, phone, city, lead_status. For geo filters (within N km, by city) use search_freeform.
find_invoices
ChatGPTFind invoices. filter='overdue' (due_date<today AND balance_due>0 AND not paid/cancelled/refunded), 'outstanding' (balance_due>0 regardless of due date), 'paid'. Returns id (DB pk), invoice_number, totals, balance_due, due_date, status, customer name.
find_jobs
ChatGPTFind jobs with common filters. Returns id (DB pk, use for navigation), job_number, title, status, schedule, technician + customer names, and service coordinates. Use search_freeform for filters this tool lacks (e.g. by city).
find_quotes
ChatGPTFind quotes, optionally by status, customer, or expiring soon. Returns id (DB pk), quote_number, status, total, valid_until, customer name.
find_technicians
ChatGPTList technicians (fp_users). Returns userid (use for assignment), username, mobile. Optionally filter to active only or search by name.
generate_document
ChatGPTFill one of the workspace's document templates (by name or id) for a record, e.g. {job_id: 42}, and get a PDF link. The link is public — anyone with it can open the file — so share it only where the user intends.
generate_estimate
ChatGPTPrice a job with a published estimate template: pass measurements (e.g. {roof_area_m2: 120, pitch_deg: 30}) and get the line items (product, quantity, unit price) the template produces from the workspace's product list. Nothing is saved, and it makes no quote document. Only works with a template from list_estimate_templates. Call without measurements to see which fields the template uses.
generate_pdf
ChatGPTTurn a report or document you write as HTML into a PDF and get a link to it (a quote, job report, statement, summary). This is the in-app copilot's generate_pdf: when the workspace's instructions or an action's answer say to call generate_pdf, this is it. Write the BODY as clean semantic HTML in html (h1/h2/h3, p, tables, lists) and it gets a branded letterhead with the title and today's date; or pass a COMPLETE document (<!DOCTYPE html><html><head><style>…</style></head><body>…) to control the whole layout (a customer's own letterhead, page size, colours) — it is used as-is, with no letterhead added. No <script>. The answer has the link, a summary of what was rendered and a picture of page 1: look at the picture and fix the HTML before you tell the user it's ready. The link is public — anyone with it can open the file. The PDF isn't put on any record: to attach it, use the workspace's own action for that, or propose_write.
geocode_address
ChatGPTCoordinates for up to 10 addresses (lat, lng, how confident, from cache or a fresh lookup). An address that can't be found says so instead of guessing.
get_agent
ChatGPTRead one agent's full configuration (instructions, tools, allowed data, hours, knowledge base) and its agent_hash, which save_agent needs to edit it.
get_app
ChatGPTRead one app: its settings (everything except the screens), the list of screens, and base_hash — pass it to save_draft / edit_view. Defaults to the version edits build on: the newest unpublished draft saved here on top of the live version, else the live version (live_version says which is live).
get_ar_aging
ChatGPTAccounts-receivable aging: total outstanding balance bucketed by how overdue it is (current, 1-30, 31-60, 61-90, 90+). Use for 'how much are we owed by buckets'.
get_automation
ChatGPTRead one automation's full definition (trigger and steps) and its updated_at, which save_automation needs to edit it.
get_automation_docs
ChatGPTRead Fieldproxy's automation reference. Topics: 'overview' (rule anatomy), 'triggers' (every trigger type and the {{trigger.*}} data it provides), 'steps' (the step library), 'recipes' (complete working automations). 'steps' and 'recipes' are large: call without section to get their section list, then ask for one section.
get_call
ChatGPTOne call in full: transcript (who said what), outcome, summary, objective and the agent's tool use.
get_document_template
ChatGPTOne PDF document template's full definition (pdf_json) — the current version, or version — with its kind and every version (for rollback_document_template). Find templates with list_document_templates.
get_email_template
ChatGPTOne saved email template in full — subject, plain and HTML body, category, /shortcut, shared or not, and whether you can edit it (your own, or a shared one as an administrator). Find ids with list_email_templates.
get_insight_result
ChatGPTThe latest result of an insight: its summary and ranked items with the evidence for each.
get_proposal_link
ChatGPTA fresh link to an existing, still-open proposal (from list_proposals), valid until the proposal expires.
get_tables
ChatGPTList the workspace's business tables (everything app screens can query, excluding the platform's own fp_as_* tables), or with tables, their columns, types, defaults and links. created_through_mcp marks what drop_table / drop_column may remove. Use this before writing screen SQL or creating a table.
get_tech_performance
ChatGPTPer-technician performance over a date range: jobs scheduled, completed, and completion rate. Optionally restrict to one technician.
get_view
ChatGPTRead one screen. Defaults to the version edits build on (like get_app) and returns the base_hash edit_view / save_draft need. Screens can be 100–600 KB, so to change part of one don't read it whole: find widgets by id, label, text or field; outline: true maps every widget's element_id, type, label and path (add path / element_id to outline just that part); or read one part with element_id or a JSON Pointer path (e.g. /ui/3). Then change it with edit_view.
get_widget_docs
ChatGPTRead Fieldproxy's app-building reference. topic='index' lists every guide and widget. Guides: 'app' (app JSON), 'view' (screen JSON), 'actions' (onclick/onchange/navigation), 'schema' and 'tenant-schema' (data tables), 'theming', 'design', 'dashboards', and more. Any widget type name (e.g. 'table', 'form', 'map_widget') returns that widget's full syntax. Read the relevant doc before writing any app or screen JSON — it is more reliable than memory. Web and mobile apps have DIFFERENT references: pass platform 'mobile' for a mobile app (no type: "web").
get_workspace_instructions
ChatGPTRead the instructions this workspace wrote for its AI assistant (house rules, which of its actions to use for what, what not to show whom) and its playbooks. Read them before changing data. Where the workspace has more than one in-app copilot, pass copilot to read another one's.
get_workspace_tool
ChatGPTOne workspace tool's full definition (SQL, params, when to use it).
import_job_phase_list
ChatGPT★ IMPORT A JOB / PHASE LIST INTO THE SYSTEM. Use when someone attaches a contractor-style job or phase export (columns like Job and phase, Organisation, Organisation contact / site, Region, Number of Engineers, Days Required, Phase type, Start date, Due, Stage) and wants those rows to BECOME real jobs. Unlike the generic import, this one is quote-aware (a real export quotes every field), resolves the UK postcode on each row to coordinates via fp_geo_outcodes so the jobs can be ROUTED afterwards, carries the per-phase earliest/due window onto the job, records the on-site duration, and CREATES any customer it cannot find rather than leaving the row unlinked. Rows whose job number already exists are skipped, not duplicated. Call with NO commit first for a preview grid; then commit:true to stage one atomic statement that creates the customers and the jobs together. AFTER it commits, route the work with plan_field_tour(source:"db"). Params: commit. (writes — confirm-gated). Nothing is saved until confirm_write applies the pending_id it returns when it stages the change.
import_jobs_from_upload
ChatGPTParse an uploaded CSV of jobs (columns like customer, title, service, date), match each to a customer, and stage the job inserts for review. Use when the user attaches a spreadsheet of jobs to load. (writes — confirm-gated). Nothing is saved until confirm_write applies the pending_id it returns when it stages the change.
import_records
ChatGPTPrepare an import of up to 1000 rows into a table, from CSV / tab-separated text (header row first) or a spreadsheet or CSV file already stored in the workspace (file_url, e.g. from list_record_files or an email attachment). Columns are matched by header; values are parsed to the column types; where the table has an import profile, existing rows are updated instead of duplicated. Nothing is saved: it returns what would be added / updated and any rows it flagged. Show the user, then confirm_write.
import_service_requests
ChatGPTRead an uploaded file of FREE-TEXT service requests (emails, voicemail transcripts, texts) and use AI to extract each into a structured job — customer, service type, urgency→priority, title, timeframe — matching known customers and flagging unclear ones. Use when the user uploads unstructured requests (not a clean columned CSV) and asks to turn them into jobs. (writes — confirm-gated). Nothing is saved until confirm_write applies the pending_id it returns when it stages the change.
instruct_agent_task
ChatGPTGive the personal agent a decision or instruction on one of its tasks (approve/decline its proposal, a new fact, a preference, "I've done it"). It is logged in the task's owner notes, the proposal is cleared, and the agent re-checks within minutes. (writes — confirm-gated). Nothing is saved until confirm_write applies the pending_id it returns when it stages the change.
integration_status
ChatGPTThe workspace's accounting/business integrations: status (active, error, expired…), connected account, last error.
invoice_completed_job
ChatGPTInvoice a completed job: create the invoice, COPY the job line items onto it, and link it back to the job — in one confirm. Use for "invoice the Smith job", "bill this completed job". (writes — confirm-gated). Nothing is saved until confirm_write applies the pending_id it returns when it stages the change.
issue_proposal
ChatGPTPropose issuing a proposal to a customer (after preview_proposal). confirm_action creates it and returns the customer link (valid until the proposal expires, can't be revoked). It sends nothing — offer to email or text the link afterwards.
jobs_chart
ChatGPTBar chart of OPEN jobs by a dimension, rendered directly. by = 'status' | 'technician' | 'service_type' | 'priority' (default status). Use for quick visual breakdowns.
list_activity_alert_rules
ChatGPTThe workspace's activity alert rules and how often each has fired — administrators.
list_activity_alerts
ChatGPTAlerts raised by the workspace's activity alert rules (bulk deletes, off-hours activity, sensitive field changes…), newest first — administrators.
list_agent_conversations
ChatGPTRecent conversations (text agents) or calls (voice agents), newest first, with summaries and outcomes.
list_agents
ChatGPTList the workspace's voice (phone) and text (SMS/email) AI agents: id, name, on/off, and the number or mailbox each answers.
list_ai_connections
ChatGPTEvery AI connection to this workspace (administrators): MCP keys — whose they are, who made them (the owner, or an admin who issued it to them), scopes, limits, last used, and whether each is awaiting its owner's claim, active, expired or revoked — and connected apps that signed in with OAuth (Claude, ChatGPT…).
list_ai_memory
ChatGPTCommand Center's standing instructions: yours, and the workspace-wide ones every user's assistant follows.
list_alerts
ChatGPTYour data alerts (things checked every few minutes that notify you when a condition is met): id, name, active/paused, how often, last check.
list_app_versions
ChatGPTList every saved version of an app, newest first, and which one is live.
list_apps
ChatGPTList the workspace's apps: id, name, web or mobile, the live version, the newest version, and whether it's public.
list_automation_runs
ChatGPTRecent runs, newest first, optionally for one automation or one status (running, succeeded, failed, skipped, blocked).
list_automation_versions
ChatGPTAn automation's change history, newest first, with what changed in each version.
list_automations
ChatGPTList the workspace's automations: id, name, on/off, what triggers each, and whether it has been failing.
list_calls
ChatGPTVoice-agent calls, newest first: agent, direction, numbers, when, how long, outcome, summary, and whether follow-up is needed.
list_dashboards
ChatGPTCommand Center dashboards you can see: name, slug, whether published, and how many tiles.
list_deleted_records
ChatGPTRecently deleted records that can still be restored (admins): table, id, when and by whom, and a preview of the row.
list_distinct_values
ChatGPTList the distinct values in a column (for enum/value discovery — e.g. what statuses or service types exist). Returns each value with its row count, most common first.
list_document_templates
ChatGPTThe workspace's PDF / Word document templates (quotes, job reports, invoices…) and the arguments each takes.
list_email_followups
ChatGPTYour pending follow-up reminders on email threads, soonest first (due_only for the ones that have come round).
list_email_templates
ChatGPTYour saved email templates and the team's shared ones: id, name, subject, and the {{placeholders}} each needs. Use one with draft_email (template + template_vars).
list_estimate_templates
ChatGPTThe workspace's estimate templates (published ones can price a job from measurements): id, name, trade, published version.
list_failed_runs
ChatGPTThe automation failure worklist: failed runs nobody has resolved yet (newest first) and failed record-change events.
list_insights
ChatGPTThe workspace's AI insights (e.g. at-risk jobs, next actions): name, kind, schedule and when each last ran.
list_pending_approvals
ChatGPTAutomation steps waiting for someone's approval, with the question asked and who may approve.
list_proposal_blocks
ChatGPTThe proposal content library: reusable pages (id, folder, name, page type). Pass id for one block's full page JSON.
list_proposal_templates
ChatGPTThe workspace's proposal templates: id, title, description, the arguments each takes (with defaults) and its option tiers.
list_proposals
ChatGPTProposals already sent to customers: title, customer, amount, status (sent/viewed/accepted/declined/expired/superseded), expiry.
list_record_files
ChatGPTList the files (photos, PDFs, documents, signatures) stored on one record — e.g. a job's before/after photos. Returns each file's URL, column and kind; look at photos with view_images, read a document's text with read_file.
list_sandboxes
ChatGPTList this workspace's sandboxes made through MCP, with when each expires.
list_saved_views
ChatGPTThe saved filter presets on one app view: your own, then the ones shared with everyone. params are the view's filter parameters in URL form; ai_filters are its AI filter boxes' saved prompts and results.
list_scheduled_reports
ChatGPTYour scheduled reports: id, name, active/paused, cadence in local time, next run, last run and last error.
list_service_zones
ChatGPTThe workspace's service zones (areas drawn on the map): id, name, colour, active, area in km², vertex count and how many records are inside. include_geometry adds each zone's outline as GeoJSON, simplified to ~10 m and 5 decimals.
list_workspace_tools
ChatGPTThe workspace's own AI tools (saved SQL queries and actions every AI in the workspace can call): name, kind, description, on/off, version.
log_invoice_reminder
ChatGPTRecord that a payment reminder was sent for an invoice (bumps reminder_count + last_reminder_sent). (writes — confirm-gated). Nothing is saved until confirm_write applies the pending_id it returns when it stages the change.
log_job_expense
ChatGPTLog a field expense/material cost against a job (e.g. a technician credit-card receipt). Use for "add a $60 parts receipt to the Smith job", "log materials on job 5457". (writes — confirm-gated). Nothing is saved until confirm_write applies the pending_id it returns when it stages the change.
lookup_customers
ChatGPTSearch customers by name, company, or email. Use this instead of raw SQL for customer lookups.
mark_quotes_lost
ChatGPTMark one or more quotes as lost (status = declined) with a reason. Pass a comma-separated list of quote IDs and a reason text. (writes — confirm-gated). Nothing is saved until confirm_write applies the pending_id it returns when it stages the change.
mark_task_done
ChatGPTClose a to-do task (sets status='completed'). (writes — confirm-gated). Nothing is saved until confirm_write applies the pending_id it returns when it stages the change.
my_agent_tasks
ChatGPTThe user's personal-agent tasks with status, what each is waiting on, the latest update, the next move the agent proposes, and when it will check again.
nearest_technicians
ChatGPTThe technicians closest to a place by road, from each one's latest position (up to 5): drive minutes, km, and how old the position is. Only people your location access covers (admins: everyone). A position is where the phone last reported — check their schedule before assigning work.
notify_users
ChatGPTPropose an in-app notification to up to 25 workspace users (their Fieldproxy bell on the web and the phone app), optionally opening a screen when tapped. Nothing is sent until confirm_action. Not an email or text — use draft_email / draft_sms for those.
open_record
ChatGPTGet a link that opens one record (a customer, job, invoice…) on its own screen in the Fieldproxy web app, for the user to click — you can't open their browser yourself. Give the table and the record's id (or another unique column in id_column).
ops_report
ChatGPTDaily FSM operations brief in ONE call: open jobs by status, scheduled-today/unassigned/unscheduled counts, per-technician load, oldest open jobs, and overdue-AR total. Returns a preformatted markdown report (render verbatim). Use for 'morning brief', 'ops report'.
overdue_tasks
ChatGPTTasks past their due date and not completed. Use for 'overdue tasks', 'what's slipping'.
plan_day_routes
ChatGPTPlan one day's routes: which technician visits which job and in what order, minimising drive time (road routing), with a suggested start time per visit and each technician's km and drive minutes. Needs job coordinates; if none have them it says so — use plan_job_distribution instead. Only READS; apply the result with apply_schedule.
plan_field_tour
ChatGPT★ MULTI-DAY TOUR PLANNER — works out the FEWEST engineers that can cover a pool of jobs inside a date window, and lays each one out as Mon-Fri tours that leave a base, stay away overnight when driving home is too far, and are back at base by the Friday cut-off. Use for "schedule this list with the minimum engineers", "plan next month's visits", "how many engineers do I need to clear September", "route these jobs and tell me the overnights". Reads an ATTACHED job list (source:"file" — any CSV/XLSX with a reference, a site or postcode, days required and a due date) or the jobs already in the system (source:"db"; add replan:true to re-plan work that is already in the diary). Handles half-day and multi-day phases, phases needing 2+ engineers on site together, per-phase earliest/due dates, and repositioning travel days for remote work. Call with NO commit first — that returns the plan to look at. Only source:"db" can be booked: call again with the SAME arguments plus commit:true to stage the dates, times, stop order and technician onto the jobs. Params: source, base (postcode / town / "lat,lng"), from_date, to_date, max_engineers (default 20), week_start (06:30), week_end (16:00), day_start, day_end, day_hours, max_home_min (drive-home minutes past which the engineer stays out, default 90), max_leg_hours, tour_days, include_saturday, include_sunday, assign_to, region, replan, commit. FOLLOW-UPS: pass scenarios:[{label,...overrides}] (up to 6) to compare what-ifs side by side in one call — e.g. [{"label":"Only 8 engineers","max_engineers":8},{"label":"Nobody stays out","max_home_min":9999}]; overridable per scenario are max_engineers, tour_days, day_hours, max_home_min, speed_kmh, road_factor, cluster_km, stop_overhead_min, week_start, week_end, day_start, day_end, include_saturday, include_sunday. Pass focus_engineer and/or focus_week to re-show one engineer or one week of the same plan — a big plan folds its later weeks to summary lines to fit the display ceiling, and focus_* is how you open them. TWO OBJECTIVES: default packs each engineer full before opening the next, which gives the FEWEST engineers but a very uneven load (28 visits for the first, 2 for the last). balance:true spreads the weeks evenly across max_engineers instead — use it whenever the user asks for equal/fair distribution, and set max_engineers to the headcount they actually have. MAP: pass render:"map" to get the SAME plan drawn as a route map — a coloured line per engineer-week starting and ending at the base, numbered stops, overnights marked. It is built from the plan computed in that call, so it works for a SCENARIO and works BEFORE anything is booked. Never hand-roll a map by querying jobs and calling display_map — that can only show work already written to the diary and draws no route line. Combine with focus_engineer / focus_week for a readable map. NOT for a single day across a town — the built-in day planner does that. (writes — confirm-gated). Nothing is saved until confirm_write applies the pending_id it returns when it stages the change.
plan_job_distribution
ChatGPTPlan who does which open, unassigned job over a date range, balancing each technician's booked minutes under a daily cap. Only READS — returns a proposed assignment per job (and what couldn't be placed). To make it real, pass the assignments to apply_schedule.
plan_promotion
ChatGPTWork out what copying things from one of this workspace's sandboxes to the LIVE workspace would do — without changing anything. Items: {type:'app', appid, version?}, {type:'automation', id, replace?}, {type:'agent', kind, id, replace?}. Returns the tables/columns live would gain, what each item becomes on live, and anything that blocks it (e.g. something that points at a user only the sandbox has). Show it to the user; if nothing blocks it, confirm_promotion applies it. Run this from the LIVE workspace's connection.
preview_document_template
ChatGPTRender a document template WITHOUT saving it: pass definition (a new or edited one) and/or template (the saved one), with sample_arguments for a real record. Returns pages, size, rows per query, warnings and a preview PDF link (public: anyone with it can open it). Nothing is saved; its queries run read-only. Word / PowerPoint (docx / pptx) templates are Office files uploaded in the PDF editor; they can't be authored here (generate_document still runs them).
preview_proposal
ChatGPTShow what a proposal would contain for a record — title, customer, price, pricing lines and tiers — without creating it.
priority_audit_from_text
ChatGPTAnalyzes service request descriptions against their current priority, flagging requests where the urgency in the text doesn't match the assigned priority. Also flags requests whose description is too vague or empty to dispatch a technician on. Returns each flagged request with the issue found.
propose_write
ChatGPTUse ONLY for a change none of this workspace's own actions covers (it has 20: create_sold_hour_quote, log_job_expense, bulk_reschedule_jobs, import_jobs_from_upload, invoice_completed_job, convert_quote_to_invoice, create_job_with_tasks, create_customer_with_contacts, create_service_contract_with_lines, create_purchase_order, create_stock_transfer, create_recurring_visits, import_service_requests, import_job_phase_list, plan_field_tour, mark_task_done, complete_job_task, apply_late_fee, log_invoice_reminder, mark_quotes_lost). Those carry the workspace's checks, notes, emails and validations; a change written here as SQL skips every one of them. Prepare a change to the workspace's data WITHOUT applying it. Pass ONE INSERT/UPDATE/DELETE as sql, or several as statements to run together in one transaction. The change is dry-run and you get back how many rows it would affect, sample rows and before→after values, plus a pending_id. Nothing is saved until confirm_write. Only tables and columns marked writable in describe_schema can be changed. Changes over 5 rows need allow_bulk on confirm; over 1000 rows are refused. A new proposal cancels any earlier unconfirmed one.
publish_app
ChatGPTMake a draft version LIVE for every user of the app. Omit version to publish the newest draft. Re-checks the version first. Drafts saved here stack, so the newest contains the ones before it; a draft saved elsewhere (the App editor, Command Center) is a separate copy — the result lists any draft that is left out. Ask the user before publishing.
quotes_to_follow_up
ChatGPTSent/viewed/pending quotes due for follow-up (past next_follow_up_date or sent >5 days ago). Use for 'quotes to chase', 'open quotes'.
read_email_thread
ChatGPTRead one of your email threads: subject, participants, linked contact, and the newest messages (condensed, quotes trimmed).
read_file
ChatGPTRead the text of a file stored in this workspace (a URL from list_record_files, a record, or an email attachment): PDF, Word, Excel, PowerPoint, CSV, text or email. An image comes back as the picture itself (view_images does up to 10 at once); video and audio aren't read.
record_history
ChatGPTA record's change history, newest first: each change's time, who made it (user, automation, AI…), and before → after values.
reissue_proposal
ChatGPTPropose replacing an open proposal (from list_proposals) with a fresh one from its template's current version — e.g. after the job or prices changed. The old link then shows it was superseded. All tiers are offered again. Refused for an accepted proposal.
remove_ai_memory
ChatGPTRemove a standing instruction (id from list_ai_memory): your own; a workspace-wide one only if you're an administrator who added it.
render_view
ChatGPTDraw one screen of an app in a real browser, as this user sees it, and look at it: desktop and phone screenshots plus any console errors and failed requests, and a design audit per viewport — a score and findings (overflow, squeezed, cut-off or unresolved text, low contrast, overlapping or ragged cards, missing gutters, type and palette sprawl), each naming the element_id to fix. Use it after save_draft / create_app, fix what it finds, and draw again before publishing. version defaults to the newest (draft or live). The preview is read-only: the screen's onload actions and anything a tap would do don't run, so a screen that sets itself up in onload may look emptier than live. arguments fill {{arguments.*}}, e.g. {"job_id": "42"}.
restore_automation_version
ChatGPTPut an automation back to an earlier version from list_automation_versions. Ask the user first.
restore_deleted_records
ChatGPTPropose restoring deleted records (by recycle-bin id from list_deleted_records, at most 50). Restored on confirm_action.
retry_automation_run
ChatGPTPropose retrying a failed run. Normally it RESUMES: steps that already completed are skipped. When that's impossible (the rule changed, or the step record expired) it says why; only if the user accepts that every step — messages included — runs again, call again with force: true. Nothing runs until confirm_action.
revenue_by_month
ChatGPTCollected revenue (completed payments) by month, last 12 months. Chart with render_chart xField='month' yField='revenue'.
reverse_geocode
ChatGPTThe street address nearest to a coordinate (e.g. where a technician's last position is).
revert_record
ChatGPTPropose putting a record's fields back to how they were right after one audited change (event_id from record_history or workspace_activity) — administrators. Shows each field's current and restored value; applied by confirm_action as an audited revert (which can itself be reverted). Never recreates a deleted record (use the recycle bin) and never writes credential columns.
revoke_ai_access
ChatGPTPropose cutting off one AI connection (administrators): an MCP key (key_id from list_ai_connections) or a connected app (connection_id). It stops working at once; the owner can make a new key. confirm_action does it.
rework_check
ChatGPTReturn visits to the same customer within N days, same trade, that aren't scheduled maintenance — reports labour + material cost of each revisit. Parameter days sets the window (default 14).
rollback_app
ChatGPTMake an earlier version live again (for example after a bad publish). Checked like a publish: it's refused if that version would add lint errors, SQL that fails against today's tables, or broken navigation. Ask the user first.
rollback_document_template
ChatGPTPropose making an earlier version of a document template current again (versions from get_document_template). confirm_action switches it — live at once for everything that renders the template. No version is deleted.
run_automation
ChatGPTPropose running an automation now. It runs every step FOR REAL (emails, texts, calls, webhooks, record changes), even if the automation is switched off — dry-run it first with simulate_automation. Returns a pending_id; nothing runs until confirm_action.
run_insight
ChatGPTRun an insight now on current data (spends AI credits, like its Run button) and return the fresh result.
run_sql
ChatGPTRun ONE read-only PostgreSQL SELECT against the workspace's data and get the rows back (max 500 rows, 5-second limit). Only tables and columns listed by describe_schema are readable. To change data, use propose_write.
save_agent
ChatGPTCreate an agent (omit agent.id) or replace one (pass its id and the agent_hash from get_agent). Pass the COMPLETE agent — fields you leave out are cleared. A new agent is saved switched OFF; test it with simulate_agent, then turn it on with set_agent_enabled. Numbers and mailboxes can only be ones the workspace already has.
save_automation
ChatGPTCreate a rule (omit id) or replace one (pass id and the expected_updated_at get_automation returned). A new rule is always saved switched OFF: dry-run it with simulate_automation, show the user what it would do, then turn it on with set_automation_enabled. Never write rule syntax from memory — read get_automation_docs first.
save_document_template
ChatGPTPropose saving a document template (administrators): a new template, or — with template — a new version of an existing one (same kind; pass the FULL definition). Every data query must be ONE SELECT; in pdfmake/proposal templates an {{arguments.x}} outside quotes must have a number default in arguments. Preview it first (preview_document_template). confirm_action saves it and it is LIVE at once — every screen, automation and document link using the template renders the new version; the previous version is kept for rollback_document_template. Word / PowerPoint (docx / pptx) templates are Office files uploaded in the PDF editor; they can't be authored here (generate_document still runs them).
save_draft
ChatGPTSave a change to an app as a new DRAFT version — nobody sees it until publish_app. Either pass the complete compiled_data, or view_id + view to replace (or add) one screen. base_hash is required: the value get_app / get_view returned, or the one your previous save returned. Drafts stack: the new draft contains the unpublished drafts before it. If a draft was saved after the version you read, your change is combined with it when they touch different screens, and refused (nothing saved) when both changed the same screen. The JSON is checked first; errors refuse the save and are returned so you can fix them.
save_email_template
ChatGPTCreate an email template (yours; is_shared makes it the team's) or, with id, change one — only the fields you pass. Saved at once: reps see the new wording next time they pick it, and every change of wording keeps the previous version. Placeholders: {{contact.first_name}}, {{key|fallback}}, {{cursor}}. body_html alone derives the plain body.
save_proposal_block
ChatGPTSave a reusable proposal page to the content library, or — with id — rename / re-folder it or replace its page. Saved at once. A block is copied into a proposal template when someone inserts it, so no existing template or issued proposal changes.
save_saved_view
ChatGPTSave a filter preset on an app view, or change one (pass id; only the fields you pass change). scope 'user' (default) is private; 'tenant' shares it with everyone and is for administrators. params: parameter name → URL-form string (e.g. {"status": "open", "range": "last_30_days"}); ai_filters: element_id → {prompt, …} — copy the shape from list_saved_views.
save_service_zone
ChatGPTPropose creating a service zone, or changing one (pass id; only the fields you pass change) — administrators. polygon is a GeoJSON Polygon or a ring of [lng, lat] points (closed for you) — longitude FIRST. Shows the area and how many records would enter or leave the zone; confirm_action saves it, recomputes membership and fires the workspace's zone automations for everything that entered or left.
save_workspace_tool
ChatGPTCreate or update a workspace tool (administrators): kind 'read' = one SELECT, kind 'action' = one INSERT/UPDATE/DELETE (always confirmed by the user when an AI uses it). Parameters are written $name in the SQL and declared in params as string | number (trailing ? = optional). A NEW tool is saved switched off: test it (test_workspace_tool), then set_workspace_tool_enabled. Updating an enabled tool changes it for every AI at once; every save is versioned.
schedule_report
ChatGPTPropose a recurring report: one SELECT re-run daily, weekly or monthly and delivered as a notification (and email if asked). Give the time exactly as the user said it, in their local time — the workspace's time zone is used unless timezone is given. The SQL may use {{today}}, {{week_start}}, {{month_start}}, {{user_id}}. Test-run now; created only by confirm_action.
search_freeform
ChatGPTRun an arbitrary READ-ONLY SQL query (SELECT / WITH) against the tenant database when no curated find_* tool fits — custom aggregations, multi-table joins, GROUP BY, distinct counts. Read-only role is enforced; writes are rejected. Always include an explicit LIMIT.
search_inbox
ChatGPTSearch YOUR connected mailboxes' threads (newest first): words in the subject, sender or body, or a participant's address. Returns thread ids for read_email_thread. Replies are drafted with draft_email + reply_to_thread_id.
segment_customers
ChatGPTSegment customers. method='ltv' (top customers by lifetime collected payments), 'dormant' (no job in 180 days). Returns customer + the segment metric.
set_agent_enabled
ChatGPTTurn an agent on or off. When on, it answers real customers on its number or mailbox — ask the user first.
set_automation_enabled
ChatGPTTurn an automation on or off. When on, it acts on real records and can message real customers — ask the user first.
set_email_followup
ChatGPTRemind yourself about one of your email threads later (in the app): in_hours, in_days or an ISO remind_at, up to a year ahead, with a note. By default it cancels itself if they reply first. Setting one again on the same thread moves it.
set_reminder
ChatGPTPropose one email to be sent at a later time: a reminder to yourself (recipient "me") or a note to someone at a set time. Use fire_in_seconds for "in 2 hours" and fire_at (ISO 8601 with a zone) for a clock time. If it should carry live data (today's jobs), read it first and put the real rows in the body. It is sent from Fieldproxy's notification address, not your mailbox, like alert emails. Nothing is scheduled until confirm_action; once scheduled it can't be changed from here.
set_workspace_tool_enabled
ChatGPTSwitch a workspace tool on (every AI in the workspace can then use it) or off.
simulate_agent
ChatGPTTry an agent (even a switched-off one) with a test conversation. It reads real data; anything it would change is staged, never saved; nothing is sent. Pass the customer's side as messages [{role:'user', content:'…'}]. Each run spends the workspace's AI credits (the result says how many).
simulate_automation
ChatGPTDry-run a SAVED automation: what each step would do, with templates filled in from a real record. Reads are real; nothing is written, sent or scheduled. Pass record_id to use a specific record as the trigger.
start_agent_task
ChatGPTHand a goal to the user's personal agent. The agent then works on it in the background for hours or days — watching the linked job, invoice, quote and customer, keeping notes, and sending the user updates and proposed next moves — until it is done or its give-up date passes. (writes — confirm-gated). Nothing is saved until confirm_write applies the pending_id it returns when it stages the change.
sync_integration
ChatGPTPropose pulling the latest payment status from an integration now (e.g. quickbooks, xero). Runs on confirm_action.
tech_workload
ChatGPTPer-technician active job count and jobs in the next 7 days. Use for 'who is busy', 'workload', 'capacity'.
technician_jobs
ChatGPTAll OPEN jobs for a named technician in ONE call — resolves the name or userid and returns their open jobs with customer, status, priority, scheduled date. Use for "X's jobs", "what is X working on". Do NOT use find_technicians + freeform.
technician_locations
ChatGPTWhere your technicians are: each person's latest position, time, battery and accuracy. Only people your location access covers (admins: everyone).
technician_route
ChatGPTOne technician's movement on a day (in the workspace's time zone): time-ordered points, first/last fix and distance covered. Subject to your location access and its history limit.
test_workspace_tool
ChatGPTRun a READ workspace tool (saved or not yet enabled) with sample parameter values and see its rows. Nothing is changed.
todays_schedule
ChatGPTToday's jobs: time, customer, technician, status, priority. Use for 'today's schedule', 'what's on today', morning brief.
triage_new_requests
ChatGPTRead every open service request and judge its real urgency from the customer's own words, not the priority field. Use for 'what needs attention', 'anything urgent in the queue', 'triage the requests', 'what came in that we should act on today'.
unbilled_completed_jobs
ChatGPTCompleted/closed billable jobs that have NO invoice yet (ready-to-invoice candidates). Use for 'what can we invoice', 'unbilled jobs'.
unbilled_jobs_for_tech
ChatGPTCompleted/closed jobs that have no invoice yet for ONE technician in a date range. Returns job number, title, service type, completion date, customer name, and technician name.
undo_write
ChatGPTReverse a change applied by confirm_write, using the undo_id it returned.
validate_app
ChatGPTCheck app JSON exactly as a save would, without saving anything: the linter, every SQL statement EXPLAINed against this workspace's database (never run), every navigation target, and the tenant review's detectors (warnings). Pass a whole compiled_data, or appid + view_id + view to check one screen inside the current app. would_save says whether the change adds anything that blocks a save; problems already in the app don't.
validate_automation
ChatGPTCheck a rule definition without saving it. Returns the first problem found, or the normalised rule. Read get_automation_docs first.
view_dashboard
ChatGPTOpen a dashboard: each tile's name and its current data (first 50 rows per tile).
view_images
ChatGPTLook at photos stored in this workspace (URLs from list_record_files, a record, or an email attachment), e.g. to compare a job's before and after photos. Returns each picture itself, shrunk to at most 1568 px, up to 10 per call.
workspace_activity
ChatGPTWho changed what across the workspace, newest first (administrators): data changes (created / updated / deleted, with before → after values) and account actions (sign-ins, team changes). Filter by table, record, person (actor_id), operation, source (app, automation, api, ai, revert…), a text search over table / record / field names, or a time range. Pass next_cursor back to page.
workspace_usage
ChatGPTThe workspace's usage against its plan: record and seat limits (used / max, over the limit or not) and this month's AI credits (included, used, remaining, hard stop) by feature.
zones_for_location
ChatGPTWhich active service zones contain a place: pass an address (looked up and cached) or lat + lng.