MCP App Store
by KeenEthics

Overview

FieldCamp is field service management software for service businesses —plumbers, electricians, HVAC, cleaning, landscaping and more. This connector lets Claude work directly with your FieldCamp account so you can run the business in plain language instead of clicking through screens. With it connected, you can: • Clients — find, create and update clients; look up a client's jobs, invoices, payment history and documents. • Jobs & visits — list and filter jobs by status or date, create jobs, schedule visits, and check a technician's visit history. • Scheduling — see the day's schedule, check for booking conflicts, and find available team members for a time slot. • Estimates & invoices — list and filter documents by status or amount, create estimates and invoices, and record payments.

Tools

change_stage

ChatGPT
Move a custom-object record to a new pipeline stage. stage must be one of this object's valid_statuses from get_data_model(slug); the transition is validated server-side against the account's pipeline rules first (allowed transitions, required fields) and a clear error is returned if it is not allowed. Use update_record for field changes — this tool ONLY changes the stage.

check_team_schedule_conflicts

ChatGPT
Check scheduling conflicts for team members against proposed visit times. Considers weeklySchedule, specificHours (availability), and existing visit overlaps. REQUIRED parameters: - teamMemberIds: array of team member MongoDB IDs - visits: array of visit objects [{visitStartDateTime, visitEndDateTime}], each local time in the ACCOUNT's timezone — send the wall-clock time the user said and do NOT convert to UTC yourself; a trailing "Z"/offset is IGNORED, not honoured - timezone: string — user's timezone for proper comparison (e.g. 'America/New_York') OPTIONAL: - excludeJobId: string — exclude a specific job when checking overlaps

convert_record

ChatGPT
Execute a conversion rule on a record — creates a NEW record in the rule's target object (e.g. template → live record, unit → renewal job). Confirm with the user before calling. Valid rule_id values: the conversion_actions listed by get_data_model(slug). Each rule has trigger stages — the record must currently be in one of them. additional_data (optional) is merged into the created record.

convert_request_to_estimate

ChatGPT
Convert a service request into an estimate document. REQUIRED: - request_id: MongoDB ObjectId of the request to convert OPTIONAL: - conversion_data: Dictionary with estimate options - dueDate: ISO date for the estimate due date - paymentTerms: integer — number of days (e.g., 30 for Net 30, 0 for Due on receipt) - comments: string - internalNotes: string This copies all line items and taxes from the request into a new estimate, and marks the request stage as "converted". Returns the converted estimate ID and number.

create_calendar_event

ChatGPT
⚠️ CALL SHAPE — pass arguments exactly as: {"event_data": { ...event fields... }} All record fields go INSIDE the *_data object, NOT at the top level (top-level keys are rejected as "unexpected keyword argument"). Create a new event in Google Calendar. REQUIRED fields in event_data: - title: string — event title - start: ISO 8601 datetime — event start, local time in the ACCOUNT's timezone — send the wall-clock time the user said and do NOT convert to UTC yourself; a trailing "Z"/offset is IGNORED, not honoured - end: ISO 8601 datetime — event end, same local-time rule OPTIONAL fields: - timeZone: IANA name (e.g. 'America/New_York') — the calendar provider's display zone only; start/end above are still read in the ACCOUNT's timezone - isAllDay: boolean — whether event spans full day - attendees: array of {email, optional, id} — invitees - recurrence: object — {frequency, interval, weekdays, count, until} - location: string or object — event location - description: string — event notes - colorId: string — color ID or hex color - metadata: object — custom metadata in extended properties

create_client

ChatGPT
⚠️ CALL SHAPE — pass arguments exactly as: {"client_data": { ...client fields... }} All record fields go INSIDE the *_data object, NOT at the top level (top-level keys are rejected as "unexpected keyword argument"). Create a new client in FieldCamp. REQUIRED fields: - client_data: Dictionary containing client information CLIENT_DATA REQUIRED fields: - firstName OR email — at least one of these is required. - firstName: string (MUST split full names - "John Smith" → firstName: "John", lastName: "Smith") - email: string CLIENT_DATA OPTIONAL fields: - lastName: string (can be empty "") - propertyAddress: object with {street, city, state, country, zipCode, formattedAddress} (all optional; an address object, NOT a plain string) - phoneNumber: object {countryCode: "+1", number: "5551234567", countryIdentifier: "us"} - companyName, website, taxNumber: string - billingAddress, companyAddress: object - notes: string - stage: ACCOUNT-SPECIFIC — call get_data_model("client") for this account's real stage values (accounts rename/replace the defaults; sending a stale default fails or mislabels the client) - clientType: "business" or "individual" - properties: array - preferredTechnicianIds, jobFormIds: arrays of ids (Clients have no tags field — it is not accepted, so do not send it.) Example: { "firstName": "John", "lastName": "Smith", "email": "john@example.com", "phoneNumber": {"countryCode": "+1", "number": "5551234567", "countryIdentifier": "us"}, "propertyAddress": { "formattedAddress": "123 Main St, Toronto, Ontario, Canada", "city": "Toronto", "state": "Ontario", "country": "Canada" } }

create_document

ChatGPT
⚠️ CALL SHAPE — pass arguments exactly as: {"document_data": { ...document fields... }} All record fields go INSIDE the *_data object, NOT at the top level (top-level keys are rejected as "unexpected keyword argument"). Create a new invoice or estimate in FieldCamp. REQUIRED fields in document_data: - documentNumber: integer — this field is required. Obtain the next number via the get_document_number tool (pass the same documentType) and use its value here. - documentType: 1 (Invoice) or 2 (Estimate) (default: 1) OPTIONAL fields: - clientId: MongoDB ObjectId - title: string - date: ISO date (default: today) - dueDate: ISO date - items: array of line items [{name, quantity, rate, description, taxIds}] - discount: number - discountType: 1 (percentage) or 2 (flat) - subTotal: number - total: number - paymentStatus: "unpaid", "paid", "partial", "overdue". HONORED ONLY for ESTIMATES (documentType=2). For INVOICES (documentType=1, the default) the backend hard-forces paymentStatus="unpaid" no matter what you pass (silently overwritten). To mark an invoice paid/partial, use the record_payment tool. - paymentTerms: integer — number of days (e.g., 30 for Net 30, 0 for Due on receipt) - privateNotes: string (internal) — or comments for client-facing text. Documents have no notes field — it is not accepted, so do not send it. - terms: string - tags: array MULTI-OPTION ESTIMATE (give the customer choices): set documentType=2, isMultiOption=true, and provide estimateOptions instead of a single items[]. Each option = {name, description?, isDefault?, lineItems:[{name, quantity, rate, description?}]}. Omit top-level items[] when using estimateOptions. Example (create invoice): { "documentNumber": 1, "documentType": 1, "clientId": "68efbd5a689d240560536cd6", "items": [ {"name": "HVAC Repair", "quantity": 1, "rate": 150, "description": "Emergency repair"} ], "dueDate": "2026-02-28" } Example (multi-option estimate): { "documentNumber": 1, "documentType": 2, "isMultiOption": true, "clientId": "68efbd5a689d240560536cd6", "estimateOptions": [ {"name": "Good", "lineItems": [{"name": "Basic clean", "quantity": 1, "rate": 100}]}, {"name": "Best", "isDefault": true, "lineItems": [{"name": "Deep clean", "quantity": 1, "rate": 250}]} ] }

create_job

ChatGPT
⚠️ CALL SHAPE — pass arguments exactly as: {"job_data": { ...job fields... }, "notes": "optional"} All record fields go INSIDE the _data object, NOT at the top level (top-level keys are rejected as "unexpected keyword argument"). Create a new job in FieldCamp. REQUIRED parameters: - job_data: Dictionary containing job information OPTIONAL parameters: - notes: the job's free text, stored as internalNotes.note — what the app lists as the job's "description". A job has NO title/description field; put that text here (job_data.internalNotes {"note": "..."} is accepted too). JOB_DATA REQUIRED fields: - clientId: MongoDB ObjectId (from search_database or get_client_by_id) - jobType: "one-off", "recurring", or "multi-day" - jobNumber: string or number - startDateTime: ISO 8601, local time in the ACCOUNT's timezone — send the wall-clock time the user said and do NOT convert to UTC yourself; a trailing "Z"/offset is IGNORED, not honoured (e.g., "2026-01-25T09:00:00") - jobAddress: object with {city, state, country, formattedAddress} JOB_DATA OPTIONAL fields: - jobTypeId: id from get_job_types — the account's job-type catalog ("Annual PM" vs "6-Month Checkup"). Distinct from jobType above. - targetRecordId + targetObjectSlug: link this job to a custom-object record (e.g. targetObjectSlug="unit", targetRecordId=<record id from list_records>). This is how PM jobs attach to the asset they service. - billToClientId: bill a different client than clientId (property manager / homeowner split). - endDateTime: ISO 8601, same local-time rule as startDateTime - jobPhone: object {countryCode: "+1", number: "xxx", countryIdentifier: "us"} - assignedToTeams: array of team IDs - jobItems: array of line-item objects. Each REQUIRES `itemName` (string) + `price` (per-unit number); `quantity` defaults to 1 and `total` is auto-computed (pricequantity). Reference an existing item with itemId (24-hex items id — NOT productServiceId/id); omit itemId for an ad-hoc line. E.g. [{"itemName": "Air filter", "price": 20, "quantity": 2}] - ⚠️ linkedRecords is NOT accepted (rejected with 400 — the backend silently drops it). Use targetRecordId + targetObjectSlug (above) to link a record instead. - subTotal, tax, total, discount: numbers - jobStatus: ACCOUNT-SPECIFIC — call get_data_model("job") for this account's real stage values before setting one. Create does NOT validate (it stores whatever string is sent), so a stale/guessed value silently mislabels the job for filtering/UI. Defaults to "scheduled" if omitted. - priority: "low", "medium", "high" - timezone: string (e.g., "America/Toronto") - anyTime: boolean — the job has no fixed start time, just a duration - serviceDuration: number (seconds). The create endpoint itself keeps this only for anyTime jobs, so for a scheduled job it is written back with a follow-up update — which counts as a job UPDATE (history entry, the "Job Updated" push to involved users, calendar sync, and any "job updated" workflow automations fire); the response says so if that write-back fails. - aiDispatcher: {"enabled": true} hands scheduling to the AI dispatcher. Only then is description read — as the dispatcher's visit label. - scheduleLater: boolean RECURRING JOBS: set jobType="recurring" AND provide recurringOptions — a list like [{"frequency": "weekly", "interval": 1, "duration": {"value": 1, "unit": "month"}}] (frequency = daily/weekly/monthly; interval = every N periods). Complex patterns (specific weekdays, nth-weekday, days-of-month) use customSettings {monthlyType, nthWeekday, daysOfMonth, weekDays}; if the pattern is non-trivial or unclear, confirm the exact recurringOptions with the user instead of guessing. Example: { "clientId": "68efbd5a689d240560536cd6", "jobType": "one-off", "jobNumber": "JOB-001", "jobStatus": "scheduled", "jobAddress": { "formattedAddress": "123 Main St, Toronto, Ontario, Canada", "city": "Toronto", "state": "Ontario", "country": "Canada" }, "startDateTime": "2026-01-25T09:00:00", "endDateTime": "2026-01-25T17:00:00" }

create_product_service

ChatGPT
⚠️ CALL SHAPE — pass arguments exactly as: {"product_service_data": { ...fields... }} All record fields go INSIDE the *_data object, NOT at the top level (top-level keys are rejected as "unexpected keyword argument"). Create a new product or service in FieldCamp. REQUIRED parameters: - product_service_data: Dictionary containing product/service information PRODUCT_SERVICE_DATA REQUIRED fields: - name: string - type: "Product" or "Service" - price: number PRODUCT_SERVICE_DATA OPTIONAL fields: - description: string - properties: array - isTaxExempt/exemptFromTax: boolean (default: false) - duration: number (minutes, for services) - isActive: boolean (default: true) - isInventoried/trackInventory: boolean (default: false). If true, inventory (below) is REQUIRED — the backend creates a stock row and 400s/500s without it. - categoryIds: array of category IDs - inventory: object — required when tracking is on. Shape: { "locationId": "<24-hex warehouse ObjectId>", // REQUIRED. This is the // warehouse key — NOT "warehouseId"/"warehouse"/"location" // (those are not accepted). Get one from get_warehouses. "sku": "SKU-001", // REQUIRED, must be GLOBALLY unique (duplicate 500s) "quantity": 10, // integer on-hand count (default 0) "lowStockAlert": 5, // integer reorder threshold (default 5) "binLocation": "A-1" // optional } - taxIds: array of tax IDs - formIds: array - settings: object with {onlineBooking, allowFillForm, serviceDuration, bookingType} - cost: number — internal unit cost (never client-facing); drives the estimate phase-margin breakdown (product cost → Material, service cost → Labor) - unitOfMeasurementId: string — unit of measurement id (sq ft, hour, each, …); valid ids from GET /api/unit-measures; reads return populated unitOfMeasurement Example: { "name": "GPU", "type": "Product", "price": 100, "description": "High-performance graphics card", "isActive": true, "exemptFromTax": false, "trackInventory": false }

create_purchase_order

ChatGPT
Create a purchase order (order stock from a vendor) in FieldCamp. REQUIRED in po_data: - vendorId: the supplier to order from (use get_vendors to find it). - items: non-empty array of line items. Each item: {itemId, quantity, price}; set displayType:'kit' to order an inventory kit (the backend expands it into its component items). OPTIONAL in po_data: - poNumber, expectedDeliveryDate (ISO date), notes. Call get_vendors for the vendorId and get_products_services / get_inventory for item ids before creating.

create_record

ChatGPT
Create a record of a CUSTOM object (e.g. slug="unit"). Call get_data_model(slug) FIRST — data must be keyed by the canonical field NAMES it returns (not labels), and status (optional initial pipeline stage) must be one of its valid_statuses. Relation fields take the target record's id (or array of ids for multi-relations). Example: create_record("unit", data={"serial_no": "GEN-002", "client_ref": "<client id>"}, status="active")

create_request

ChatGPT
⚠️ CALL SHAPE — pass arguments exactly as: {"request_data": { ...request fields... }} All record fields go INSIDE the *_data object, NOT at the top level (top-level keys are rejected as "unexpected keyword argument"). Create a new service request in FieldCamp. REQUIRED fields in request_data: - clientId: MongoDB ObjectId of the client OPTIONAL fields: - source: string (default: "manual") - description: string - urgency: string enum — "low", "medium", "high", "critical" (default: "medium") - requestAddress: object {formattedAddress, city, state, country} - startDate: ISO 8601 format - endDate: ISO 8601 format - stage: ACCOUNT-SPECIFIC (request pipeline is org-configurable) — call get_data_model("request") for this account's real stage slugs. Default: "new_request". Built-in default slugs: new_request, unscheduled, overdue, inspection_scheduled, inspection_complete, quote_created, quote_sent, converted, lost_no_response, lost_reject_quote, cancelled, duplicate - assignedTo: array of user MongoDB ObjectIds - notes: string - tags: array of strings - estimatedValue: number - items: array of line items [{itemId, itemName, quantity, rate}]. ⚠️ itemId is REQUIRED on each item and MUST be a real product/service id from get_products_services — items without a valid itemId cause a server error. If you have no product id, OMIT items entirely (use description/estimatedValue). - taxes: array of tax objects [{taxId, name, rate, taxType}] Example: { "clientId": "68efbd5a689d240560536cd6", "description": "HVAC repair needed", "urgency": "high", "stage": "new_request" }

create_task

ChatGPT
Create a new task in FieldCamp. REQUIRED parameters: - name: Task name/title - scheduleDateTime: ISO 8601, local time in the ACCOUNT's timezone — send the wall-clock time the user said and do NOT convert to UTC yourself; a trailing "Z"/offset is IGNORED, not honoured (e.g., "2026-01-25T14:00:00") OPTIONAL parameters: - instructions: Detailed task instructions - priority: "low", "normal", "high", "urgent" (default: "normal") - category: "admin", "maintenance", "follow_up", "inspection" (default: "follow_up") - assignedToId: MongoDB ObjectId of user to assign (search users collection) - clientId: MongoDB ObjectId of linked client - linkType: "client", "job", "estimate", "invoice" - jobId, estimateId, invoiceId: MongoDB ObjectIds for linked entities - propertyAddress: string - scheduleType: "once", "daily", "weekly", "monthly" (default: "once"). For a recurring task pass a non-"once" value AND a recurrenceRule — recurrence is driven by recurrenceRule; scheduleType is the stored label. - scheduleEndDate: ISO 8601 (for recurring tasks), same local-time rule as scheduleDateTime - allDay: boolean (default: false) - duration: minutes (default: 30) - recurrenceRule: e.g., "FREQ=DAILY;INTERVAL=1" (for recurring) - recurrenceCount: number of occurrences - reminderType: "email", "sms", "push" - reminderTime: minutes before task (default: 15) - tags: array of strings - emailTeam: boolean - notify assignee (default: false)

create_tax

ChatGPT
Create a tax rate in FieldCamp. REQUIRED in tax_data: - name: tax name (e.g. 'GST'). - rate: percentage as a number (e.g. 5 for 5%). OPTIONAL in tax_data: - taxType: 1 = exclusive (default), other values per settings. - description, applyOnAllItems (bool), countryId, stateId, effectiveDate (ISO date), applicationRules (array). The new tax id feeds the taxIds arrays on create_document and create_product_service. Admin / settings permission required.

create_vendor

ChatGPT
Create a vendor / supplier in FieldCamp. REQUIRED: - name: vendor name. OPTIONAL: - email: must be unique for the org (backend rejects a duplicate). - phone: composite OBJECT (dict), NOT a plain string — a bare string is rejected by the backend. Shape: {"countryCode": "+1", "number": "4155550100", "countryIdentifier": "us"} - address: composite OBJECT (dict), NOT a plain string — a bare string is rejected by the backend. Shape (sub-fields optional; at minimum pass {"formattedAddress": "..."}): {"formattedAddress": "...", "city": "...", "state": "..."} Returns the created vendor. Use its id as preferredVendorId on create_product_service / update_product_service. Call get_vendors first to check whether the vendor already exists.

create_visit

ChatGPT
Create a new visit/appointment for a job. REQUIRED parameters: - jobId: MongoDB ObjectId of the job (get from search_database or get_job_by_id) - visitStartDateTime: ISO 8601, local time in the ACCOUNT's timezone — send the wall-clock time the user said and do NOT convert to UTC yourself; a trailing "Z"/offset is IGNORED, not honoured (e.g., "2026-01-25T14:00:00") - visitEndDateTime: ISO 8601, same local-time rule (e.g., "2026-01-25T16:00:00") - teamId: team-member id(s) from get_teams — one 24-hex id as a plain string, or several as a JSON-array string, e.g. '["6a17e04da8237fae54dcef8e","6a17e04da8237fae54dcef8f"]'. Not a name. OPTIONAL parameters: - visitStatus: account-specific — call get_data_model("visit") for valid values (default: "scheduled") - priority: "low", "medium", "high" (default: "medium") - scheduleLater: "true" or "false" as string (default: "false") - anyTime: "true" or "false" as string - flexible time (default: "false") - isExtraVisit: "true" or "false" as string - extra visit beyond original (default: "false") - skillsId: required skills for the visit

create_warehouse

ChatGPT
Create a warehouse / inventory location in FieldCamp. REQUIRED: - name: warehouse name. OPTIONAL: - warehouseType: stored as the warehouse type (e.g. 'Main Warehouse', 'Technician Truck/Van'). - address: composite OBJECT (dict), NOT a plain string — a bare string is rejected by the backend. Shape (all sub-fields optional; at minimum pass {"formattedAddress": "..."}): { "formattedAddress": "123 Main St, Austin, TX 78701, USA", "street": "123 Main St", "city": "Austin", "state": "TX", "country": "USA", "zipCode": "78701" } Returns the created warehouse. Use its id as fromWarehouseId / toWarehouseId on transfer_inventory and as the warehouse filter on get_inventory. Call get_warehouses first to check whether a matching location already exists.

delete_calendar_event

ChatGPT
Delete an event from Google Calendar. REQUIRED: - eventId: string — ID of the calendar event to delete

delete_client

ChatGPT
Delete a client from FieldCamp. ⚠️ WARNING: This is a destructive operation! REQUIRED: - client_id: MongoDB ObjectId of the client OPTIONAL: - forceDelete: "true" to permanently delete, "false" to soft delete (default: "false") Set forceDelete="true" to permanently delete the client and all associated data. Set forceDelete="false" to soft delete (can be recovered).

delete_inventory

ChatGPT
Delete inventory item(s) from FieldCamp. ⚠️ WARNING: This is a destructive operation! REQUIRED: - delete_ids: Array of inventory item MongoDB ObjectIds OPTIONAL: - current_warehouse_id: MongoDB ObjectId of warehouse (when an item exists in multiple warehouses, this picks which one to delete)

delete_invoice

ChatGPT
Delete invoice(s) or estimate(s) from FieldCamp. ⚠️ WARNING: This is a destructive operation! REQUIRED: - document_ids: Array of document MongoDB ObjectIds to delete

delete_job

ChatGPT
Delete a single job from FieldCamp. ⚠️ WARNING: This is a destructive operation! REQUIRED: - job_id: MongoDB ObjectId of the job NOTE: This tool deletes ONE job at a time. If the user wants to delete multiple jobs, call this tool separately for each job_id.

delete_payment

ChatGPT
Delete/reverse a payment transaction. Recalculates invoice balance. ⚠️ WARNING: Cannot reverse online payments (Stripe). REQUIRED: - transactionId: MongoDB ID of the payment record to delete - documentId: MongoDB ID of the invoice/estimate

delete_product_service

ChatGPT
Delete product(s) or service(s) from FieldCamp. ⚠️ WARNING: This is a destructive operation! REQUIRED: - delete_ids: Array of product/service MongoDB ObjectIds to delete

delete_purchase_order

ChatGPT
Delete one or more purchase orders in FieldCamp. REQUIRED: - delete_ids: array of purchase order ids to delete (from get_purchase_orders). DESTRUCTIVE: removes the purchase orders and their line items. Confirm with the user before calling.

delete_request

ChatGPT
Delete a service request from FieldCamp (soft delete). ⚠️ WARNING: This is a destructive operation! REQUIRED: - request_id: MongoDB ObjectId of the request Sets the request status to 'Deleted' and removes related items and taxes. Only the request creator or parent user can delete.

delete_task

ChatGPT
Delete a task from FieldCamp. ⚠️ WARNING: This is a destructive operation! REQUIRED: - task_id: MongoDB ObjectId of the task

delete_tax

ChatGPT
Delete one or more tax rates in FieldCamp. REQUIRED: - delete_ids: array of tax ids to delete (from get_taxes). DESTRUCTIVE: soft-deletes the taxes (status='Deleted') and marks any QuickBooks tax mappings deleted. Existing documents keep their stored tax values. Admin / settings permission required. Confirm with the user before calling.

delete_vendor

ChatGPT
Delete one or more vendors / suppliers in FieldCamp. REQUIRED: - delete_ids: array of vendor ids to delete (from get_vendors). DESTRUCTIVE: the backend archives each vendor and its related data, then removes the vendors and their purchase orders. Confirm with the user before calling.

delete_visit

ChatGPT
Delete a visit/appointment from FieldCamp. ⚠️ WARNING: This is a destructive operation! REQUIRED: - visitId: MongoDB ObjectId of the visit

delete_warehouse

ChatGPT
Delete one or more warehouses / inventory locations in FieldCamp. REQUIRED: - delete_ids: array of warehouse ids to delete (from get_warehouses). DESTRUCTIVE: the backend archives each warehouse and its related data, then removes inventory transfers/items in those warehouses and flags affected products as non-inventory. Confirm with the user before calling.

fetch

ChatGPT
Fetch the FULL record for a single type-prefixed id returned by search. This is step two of the search→fetch retrieval pair: after search finds a record, call fetch with its id to pull the complete details (all fields) for clients, jobs, visits, products/services, invoices, estimates, requests, and tasks. It routes to the correct underlying record lookup automatically based on the id prefix — you do NOT need to know or call the entity-specific get_*_by_id tool yourself. PARAMETERS: - id: the TYPE-PREFIXED id from a search result, e.g. "client:<id>", "job:<id>", "invoice:<id>", "estimate:<id>", "request:<id>", "product:<id>", "visit:<id>", "task:<id>" (or "custom:<slug>:<id>"). RETURNS a JSON object: {"id", "title", "text", "url", "metadata"} where text is the full record serialized as readable JSON, url is the app deep link, and metadata carries key fields (status, totals, type, ...).

get_all_team_members

ChatGPT
Get all team members (no pagination - returns full roster). OPTIONAL: - view: "assignedTeam", "assignedSelf", or omit for all members Returns all active team members with name, email, role, skills, service areas, and schedule information. Use for: "Who's on the team?", "List all technicians", "Which team members have HVAC skills?"

get_analytics

ChatGPT
Get business analytics and metrics data. This is the PREFERRED tool for totals, sums, rankings, and trends (e.g. total outstanding A/R, top clients, revenue over time) — it computes them server-side. Do not try to total these yourself by listing records. REQUIRED: - metric: The metric to retrieve (see list below) ⚠️ ALWAYS pass start_date AND end_date. Most metrics return an EMPTY result ("data": []) when no date range is given. For an "all-time" total, pass a wide range (e.g. start_date="2020-01-01" through a date in the future). Example: outstandingRevenue over a wide range returns the current total A/R; topRevenueClients returns the ranked client list. OPTIONAL: - start_date: ISO date (e.g., "2026-01-01") - end_date: ISO date (e.g., "2026-01-31") - group_by: "auto", "day", "week", "month", "quarter", "none" (default: "auto") - breakdown_by: dimension to break down by (see list below). NOTE: breakdown_by is applied PER-METRIC — not every dimension works with every metric, and a dimension the chosen metric doesn't support is silently ignored (no error; the result simply comes back without that breakdown). - filters: array of filter objects AVAILABLE METRICS: Jobs: totalJobsForChart, jobCompletionRate, jobVolumeTrends, avgJobValue, avgJobDuration, jobStatusDistribution, jobTypeDistribution, jobsByClient, jobsByAssignee Visits: totalVisits, visitSuccessRate, avgVisitDuration, visitsPerJob Financial: revenueTrends, paidRevenue, outstandingRevenue, overdueInvoiceAmount, invoiceCount, avgInvoiceValue, collectionRate, topRevenueClients, avgDaysToPayment Estimates: totalEstimates, estimateValue, estimateApprovalRate, estimateConversionRate CRM: newClientsOverTime, totalClients, totalRequests, clientConversionRate, requestConversionRate, clientsStages, requestsByStage Tasks: totalTasks, taskCompletionRate, overdueTasksCount, tasksByStatus, tasksByPriority Workforce: scheduledHoursByTechnician, jobsPerTechnician, technicianRevenue Geographic: jobsByCity, revenueByCity, clientsByCity BREAKDOWN DIMENSIONS: createdBy, assignedTo, teamId, clientId, clientType, clientStage, jobStatus, paymentStatus, visitStatus, jobType, city, state

get_available_team_members_schedule

ChatGPT
Get available team members for a specific time slot. Checks both visit overlaps and team member schedules (weeklySchedule/specificHours). REQUIRED parameters: - visitStartDateTime: ISO 8601 start of the window, local time in the ACCOUNT's timezone — send the wall-clock time the user said and do NOT convert to UTC yourself; a trailing "Z"/offset is IGNORED, not honoured - visitEndDateTime: ISO 8601 end of the window, same local-time rule - timezone: string — user's timezone (e.g. 'Asia/Kolkata') OPTIONAL: - requiredSkillIds: array of skill IDs to filter by required skills - excludeJobId: string — exclude this job from conflict check

get_calendar_activity

ChatGPT
Get recent calendar activity feed (status changes, assignments, completions, alerts). OPTIONAL parameters: - limit: integer (1-50, default: 20) — max activities to return - since: ISO 8601 datetime — get activities since this date (default: 24 hours ago) - types: comma-separated string — filter: 'status_change', 'assignment', 'completion', 'alert'

get_calendar_events

ChatGPT
Fetch calendar events including visits, invoices, tasks, requests, and Google Calendar events. OPTIONAL parameters: - month: integer (1-12) — month to fetch events for - year: integer (e.g. 2026) — year to fetch events for - source: string — filter by source: 'google_calendar', 'job_visits', 'invoices', 'estimates', 'tasks', 'requests' - eventTypes: JSON array string — event types: ['all', 'visits', 'invoices', 'estimates', 'tasks', 'requests', 'events'] - view: string — 'ownEvents' for personal events only - clientId: string — MongoDB ID to filter events by client - upcoming: string — 'true' to get upcoming events only - email: string — filter events tied to a specific user email - isFromClientEvents: boolean — scope the fetch to the client-events feed - fetchOnlyEvents: boolean — return only Google Calendar events (skip visits/invoices/tasks/requests)

get_client_by_id

ChatGPT
Get complete client details by MongoDB ObjectId. PARAMETERS: - client_id: MongoDB ObjectId of the client Returns all client information including name, contact details, property address, billing address, tags, custom fields, and metadata.

get_client_documents

ChatGPT
Get documents (invoices and estimates) for a specific client. REQUIRED: - client_id: MongoDB ObjectId of the client OPTIONAL: - view: Set to "assigned" to only see documents assigned to current user Returns list of documents with document type (1=Invoice, 2=Estimate), document number, status, payment status, title, total, and date.

get_client_payment_history

ChatGPT
Get payment history for a specific client. REQUIRED: - client_id: MongoDB ObjectId of the client OPTIONAL: - view: Set to "assigned" to only see payments from documents assigned to current user Returns list of payments with document number, payment amount, payment date, payment method, document total, and payment status. Sorted by payment date descending.

get_client_products

ChatGPT
Get products associated with a specific client from their jobs. REQUIRED: - client_id: MongoDB ObjectId of the client OPTIONAL: - view: Set to "assigned" to only see products from jobs assigned to current user Returns list of products with item name, description, quantity, price, total, and linked job number.

get_company_info

ChatGPT
Get company information and settings. OPTIONAL: - withCurrencyData: when True, backend enriches the response with extra currency metadata. Default False (flag omitted from wire). Returns company details including business name, address, phone, email, website, timezone, currency, industry, mileage tracking settings, labor rate settings, and other configuration. Use for: Understanding business context (timezone, currency, industry) before performing operations.

get_company_schedule

ChatGPT
Get the company's weekly business hours and specific hour exceptions (holidays, special hours). Returns weeklySchedule (7 days) and specificHours (date-specific overrides).

get_data_model

ChatGPT
Return THIS account's LIVE, customized schema — the real pipeline status values, allowed transitions, and custom fields for an object. Pipelines, statuses and fields are CUSTOMIZABLE per account, so the default status names mentioned in other tools may not match this account. Call this BEFORE filtering/setting a status or creating/updating a record whenever you are unsure of the valid values for THIS account — then use the exact values it returns. Scoped to the caller's own organization. object_type: "client", "job", "visit", "invoice", "estimate", "request", "task", or "all" (default). Also accepts any CUSTOM object slug (tenant-defined — e.g. "unit"). "all" lists custom objects by name only; pass the specific slug to get its fields (keyed by canonical field NAME — use these exact names in create_record/update_record data), stages, transitions, and conversion actions (valid rule_id values for convert_record).

get_dispatch_suggestions

ChatGPT
Get AI-powered dispatch suggestions for unassigned visits. Recommends technicians based on workload, availability, and client relationships. OPTIONAL parameters: - visitId: string — get suggestions for a specific unassigned visit - date: string (YYYY-MM-DD) — target date for finding unassigned visits (default: today)

get_document_number

ChatGPT
Get the next available document number for invoices or estimates. REQUIRED: - documentType: integer — 1=Invoice, 2=Estimate

get_filtered_clients

ChatGPT
Get clients with advanced filtering, pagination, and sorting. REQUIRED: - filters: Array of filter objects (can be empty [] to get all clients) OPTIONAL: - view, page, limit, sorting, stage - limit: max records per page (server-clamped to 30) VALID FILTER FIELDS (use ONLY these — any other field name returns HTTP 400): - firstName, lastName, email, companyName, website, taxNumber - stage: ACCOUNT-SPECIFIC — call get_data_model("client") for this account's real stage values (accounts rename/replace the defaults; sending a stale default fails or mislabels the client) - clientType: "business" or "individual" - propertyAddress (address filter — see CRITICAL note below) - createdAt, updatedAt (use ISO date: "2026-01-15") - notes ⚠️ CRITICAL: For address filtering, use the single field "propertyAddress" (it matches across street/city/state/country/zipCode/formattedAddress): - ✅ CORRECT: field="propertyAddress", value="Toronto" - ❌ WRONG: "city"/"state"/"country" or "propertyAddress.city" → HTTP 400 ("'<field>' is not a valid field") NOTE: "tags" is NOT a filterable field on clients (returns HTTP 400). STAGE PARAMETER (optional convenience filter - EXACT string match, no shortcuts): The backend matches stage as an EXACT string, and stage values are ACCOUNT-SPECIFIC (accounts rename/replace the defaults) — call get_data_model("client") for this account's real values before filtering. There is NO "pipeline"/"all"/"active"/"leads"/"clients" stage value; those will match nothing. To list ALL clients (every stage), OMIT the stage parameter AND pass filters=[] (empty array). Filter structure (stage value below is a PLACEHOLDER — use this account's real values from get_data_model("client")): [ {"filterCondition": "", "field": "stage", "condition": "is", "value": "<stage value>"}, {"filterCondition": "and", "field": "propertyAddress", "condition": "contains", "value": "Toronto"} ] Condition operators: - Text: contains, doesNotContain, is, isNot, startsWith, endsWith, isEmpty, isNotEmpty - Dates (createdAt/updatedAt): equalTo, lessThan, greaterThan, dateRange, isEmpty, isNotEmpty (use EXACTLY these tokens — "equals"/"before"/"after" are NOT accepted: before/after → HTTP 400; "equals" silently returns UNFILTERED results) - Select: is, isNot Example by stage: stage="<value from get_data_model>" parameter OR filters with field="stage" Example for Toronto clients: [{"filterCondition": "", "field": "propertyAddress", "condition": "contains", "value": "Toronto"}]

get_filtered_jobs

ChatGPT
Get jobs with advanced filtering, pagination, and sorting. REQUIRED: - filters: Array of filter objects OPTIONAL: - view, page, limit, sorting - limit: max records per page (server-clamped to 30) VALID FILTER FIELDS (use ONLY these - flat field names, NO nested paths): - jobStatus: FIXED backend allow-list (exact values, backend 400s on anything else): "draft", "scheduled", "in-progress", "completed", "invoiced", "paid", "cancelled", "on-hold", "closed" - jobType: "one-off", "recurring", "multi-day" - jobNumber, clientName, description (internalNotes) - jobAddress: SINGLE address field that searches street/city/state/country/zip together (use condition "contains"). There are NO flat city/state/country filter fields for jobs. - startDateTime, endDateTime, createdAt, updatedAt (use ISO date: "2026-01-15") - total, subTotal, discount, tax (numeric) - priority: "low", "medium", "high" - assignedToTeams ⚠️ CRITICAL: For address filtering on jobs, use the single jobAddress field: - ✅ CORRECT: {"field": "jobAddress", "condition": "contains", "value": "Toronto"} - ❌ WRONG: "city", "state", "country" (these are NOT valid job filter fields) - ❌ WRONG: "jobAddress.city" (no nested paths) Filter structure: [ {"filterCondition": "", "field": "jobStatus", "condition": "is", "value": "in-progress"}, {"filterCondition": "and", "field": "jobAddress", "condition": "contains", "value": "Toronto"} ] Condition operators: - Text: contains, doesNotContain, is, isNot, startsWith, endsWith, isEmpty, isNotEmpty - Dates: equals, before, after, isEmpty, isNotEmpty (dates apply to fields startDateTime, endDateTime, createdAt, updatedAt) - Numeric: equals, notEquals, greaterThan, lessThan, greaterThanOrEqual, lessThanOrEqual - Select: is, isNot NOT SUPPORTED — filtering jobs by a single assignee: The backend has NO assignee filter handler for jobs (assignments live in assignedToTeams and there is no server-side filter for them). Do NOT rely on the assigned_to_id parameter to narrow jobs to one person — it is not applied server-side and will not return a useful/filtered result. Example for jobs by client: [{"filterCondition": "", "field": "clientName", "condition": "contains", "value": "John"}] Example for jobs in Toronto: [{"filterCondition": "", "field": "jobAddress", "condition": "contains", "value": "Toronto"}]

get_history

ChatGPT
Get activity history for any entity (audit trail). REQUIRED: - module_id: MongoDB ObjectId of the record - module_type: "job", "visit", or a CUSTOM-OBJECT SLUG. Custom-object records DO have history: create/update/delete each write a History row keyed by the object slug. Pass the slug field from list_object_definitions VERBATIM — it is not the plural form and not the display name (real slugs look like "warnty", "contract_renewal", "all_mode", whose namePlural is a separate display-only field). A record with no history yet returns an empty list, which means "nothing recorded for this record", not "unsupported". NOT available here: "client" and "request". Client activity lives in a separate clientHistory table this endpoint does not read, and request activity is not recorded at all — both return an EMPTY result rather than an error, so do not read an empty response as "nothing ever changed". OPTIONAL: - page: page number (default: 1) - limit: max records per page (server-clamped to 30) Returns chronological activity log including who made changes, what was changed, descriptions, and timestamps. Use for: "What changes were made to this job?", "History of this visit?"

get_inventory

ChatGPT
Get inventory data with filtering and pagination. REQUIRED: OPTIONAL PARAMETERS: - page: Page number (default: 1) - limit: max records per page (server-clamped to 30) - type: Warehouse type filter. This is FREE-TEXT and CASE-SENSITIVE, and the valid values are account-specific — NOT a fixed enum. Do NOT guess values like "Main Warehouse" or "Technician Truck/Van"; call get_warehouses first and pass a warehouse's actual name/type string exactly as returned. - warehouse: MongoDB ObjectId of specific warehouse - lowStock: "true" or "false" - filter for low stock items only - category: MongoDB ObjectId of category - id: MongoDB ObjectId to get specific inventory item RETURNS: Inventory items with quantity, SKU, warehouse location, item info (name, price, type), categories, and stock alerts. Use for: checking stock levels, finding low stock items, filtering by warehouse.

get_inventory_by_id

ChatGPT
Get inventory item details by MongoDB ObjectId. REQUIRED: - inventory_id: MongoDB ObjectId of the inventory item Returns complete inventory information including item details, warehouse, quantity, SKU, and metadata.

get_invoice_by_id

ChatGPT
Get invoice or estimate details by MongoDB ObjectId. PARAMETERS: - document_id: MongoDB ObjectId of the invoice/estimate Returns complete document information including line items, payments, client details, and status.

get_invoices

ChatGPT
Get invoices or estimates with advanced filtering. REQUIRED: - documentType: 1 for Invoices, 2 for Estimates - filters: Array of filter objects OPTIONAL: - view, page, limit, sorting - limit: max records per page (server-clamped to 30; use -1 for summary mode) VALID FILTER FIELDS (use ONLY these): - documentNumber, title, privateNotes, comments - client, clientName, clientEmail, clientCity, clientState - total, subTotal, paidAmount (numeric) - documentStatus: ONLY these values are accepted (backend 400s on anything else): "draft", "sent", "approved", "viewed", "pending", "approved_pending_signature". (Do NOT pass "declined", "expired" or "awaiting response" as a documentStatus — they are rejected. For an estimate's accept/decline outcome use actionStatus below instead.) - actionStatus (ESTIMATES ONLY): the customer's decision on an estimate. 0 = pending / awaiting customer response, 1 = approved, 2 = declined. ⚠️ To answer "how many estimates are awaiting / approved / declined", filter documentType=2 by actionStatus — NOT documentStatus. (An approved or declined estimate usually still has documentStatus "draft"/"sent", so filtering documentStatus="declined" wrongly returns nothing.) e.g. {"filterCondition":"","field":"actionStatus","condition":"is","value":2} - paymentStatus: ONLY these values are accepted (backend 400s on anything else): "unpaid", "partial", "paid", "overdue". (Do NOT pass "draft", "sent", "pending" or "canceled" as a paymentStatus — they are rejected.) - date, dueDate, createdAt, updatedAt (use ISO date: "2026-01-15") - createdBy, paymentTerms Filter structure: [ {"filterCondition": "", "field": "paymentStatus", "condition": "is", "value": "unpaid"}, {"filterCondition": "and", "field": "total", "condition": "greaterThan", "value": 1000} ] ⚠️ TOTALS / "HOW MUCH IS OWED" — DO NOT paginate and add up amounts yourself (that is error-prone). Call this tool with limit=-1: it returns server-computed summary_statistics { total_documents, total_amount, total_paid, total_outstanding, payment_status_breakdown } plus a few sample_documents. Note "unpaid" alone excludes "partial" and "overdue" — to get the TOTAL amount owed, either filter by all three or (better) use get_analytics metric="outstandingRevenue" / "topRevenueClients" with a date range.

get_job_by_id

ChatGPT
Get complete job details by MongoDB ObjectId. PARAMETERS: - job_id: MongoDB ObjectId of the job - view: View options: 'all', 'own', 'viewAssigned' (default: 'all') Returns job information including client, visits, line items, invoices, and metadata.

get_job_types

ChatGPT
List this account's job-type catalog — the named service types jobs are classified by (e.g. "Annual PM", "6-Month Checkup"), each with an id, description, and estimated duration. Use the returned id as jobTypeId in create_job/update_job job_data. Job types are account-defined; never guess a jobTypeId. PARAMETERS: - page / limit: pagination - search: filter by title (contains, case-insensitive)

get_next_job_number

ChatGPT
Get the next available job number. Returns the next sequential job number for job creation. Useful for previewing the job number before creating a job.

get_payment_history

ChatGPT
Get payment history for an invoice or estimate. REQUIRED: - documentId: MongoDB ID of the document Returns: total, paidAmount, paymentStatus, and array of payment records with amount, date, method, note, and transaction details.

get_product_categories

ChatGPT
List product/service categories configured in FieldCamp (reference data). OPTIONAL: - search: case-insensitive substring to match a category name. Returns categories with id and name. The ids are the valid values for the categoryIds field on create_product_service / update_product_service and for the category filter on get_inventory. NOTE: the backend returns at most 10 categories. With no search term you get the first 10 alphabetically — pass search to locate a specific category that may fall outside that first 10.

get_product_service_by_id

ChatGPT
Get product or service details by MongoDB ObjectId. PARAMETERS: - product_service_id: MongoDB ObjectId of the product/service Returns complete product/service information including name, type, price, inventory status, tax settings, and custom properties.

get_products_services

ChatGPT
Get products and services with advanced filtering. REQUIRED: - filters: Array of filter objects OPTIONAL: - page, limit - limit: max records per page (server-clamped to 30; use -1 for summary mode) VALID FILTER FIELDS (use ONLY these): - name, description - type: "Product" or "Service" - price (numeric) - status: "available" or "unavailable" — use this to filter active vs inactive products/services (field="status", value="available" for active). - createdAt, updatedAt (use ISO date) NOT filterable here (the backend cannot filter on these — passing them returns 0 results, so do NOT use them as filter fields): isActive, trackInventory, exemptFromTax. For active/inactive use field="status" above. Filter structure: [ {"filterCondition": "", "field": "type", "condition": "is", "value": "Product"}, {"filterCondition": "and", "field": "price", "condition": "greaterThan", "value": 100} ] Returns summary statistics for large result sets to prevent token overflow.

get_purchase_orders

ChatGPT
List purchase orders in FieldCamp. OPTIONAL: - page: page number (default 1). - limit: max records per page (server-clamped to 30). - status: filter by PO status. Valid values: "Draft", "Ordered", "Received", "Canceled". If omitted, NO status filter is applied and purchase orders of ALL statuses are returned (it does NOT default to "Ordered"). Each purchase order includes its vendor and line items.

get_record

ChatGPT
Get one custom-object record by MongoDB ObjectId. Returns the record's status (pipeline stage), its data object (keyed by canonical field names — see get_data_model(slug)), and system timestamps.

get_record_summary

ChatGPT
Financial/progress rollups for one custom-object record, resolved server-side in a single call: jobs targeting this record plus invoices linked to them (all-time / windowed / paid totals and counts), and a newest-first per-job invoiced history. Use this for "how much have we spent on this unit?" / "repair or replace?" questions instead of listing jobs and invoices yourself.

get_request_by_id

ChatGPT
Get complete service request details by MongoDB ObjectId. REQUIRED: - request_id: MongoDB ObjectId of the request Returns full request including client details, line items (requestItems), taxes (requestTaxes), stage, and all metadata.

get_requests

ChatGPT
Get service requests with filtering, pagination, and sorting. OPTIONAL: - page: page number (default: 1) - limit: max records per page (server-clamped to 30) - tab: "requests" (active), "pipeline", "archived" (default: "requests") - view: "all" or "assigned" (default: "all") - filters: array of filter objects - sorting: array of sorting objects - client_id: filter by client MongoDB ObjectId FILTERABLE FIELDS: requestNumber, clientName, clientEmail, description, source, urgency, stage, estimatedValue, createdAt, assignedTo, notes, startDate, endDate STAGE filter: exact string match, and stage slugs are ACCOUNT-SPECIFIC (request pipeline is org-configurable) — call get_data_model("request") for this account's real slugs before filtering. Built-in default slugs: new_request, unscheduled, overdue, inspection_scheduled, inspection_complete, quote_created, quote_sent, converted, lost_no_response, lost_reject_quote, cancelled, duplicate Returns requests with client info, stage counts, and pagination.

get_task_by_id

ChatGPT
Get complete task details by MongoDB ObjectId. REQUIRED: - task_id: MongoDB ObjectId of the task Returns task information including name, schedule, assignee, linked records, status, and instructions.

get_tasks

ChatGPT
Get all tasks with sorting options. REQUIRED: OPTIONAL PARAMETERS: - sort: string enum — the ONLY values the backend supports are "due_date", "creation_date", "assignee" (default: "due_date"). Any other value (e.g. "priority", "created_at", "status") is not supported. - order: "ascending" or "descending" (default: "descending") RETURNS: Tasks grouped by status: - overdue: Past due tasks - today: Due today - thisWeek: Due this week - upcoming: Future tasks - completed: Finished tasks Each task includes: name, priority, due date, assigned team member, client/job linkage, category, and completion status.

get_tasks_by_client

ChatGPT
Get tasks linked to a specific client, paginated. REQUIRED: - client_id: MongoDB ObjectId of the client OPTIONAL: - page: Page number (default: 1) - limit: max records per page (server-clamped to 30) - view: Set to "Assigned" to only see tasks assigned to current user Returns paginated task list sorted by schedule date, with total count.

get_tasks_by_job

ChatGPT
Get tasks linked to a specific job, paginated. REQUIRED: - job_id: MongoDB ObjectId of the job OPTIONAL: - page: Page number (default: 1) - limit: max records per page (server-clamped to 30) Returns only tasks where linkType is 'job' matching the given job ID. Sorted by schedule date with total count.

get_taxes

ChatGPT
Get tax rates configured in FieldCamp. OPTIONAL: - page: page number (default: 1) - limit: max records per page (server-clamped to 30) - name: search by tax name (case-insensitive) Returns tax rates with name, rate percentage, tax type (exclusive/inclusive), state/country info, and application rules. Use for: Looking up available tax rates before creating invoices or estimates.

get_team_member

ChatGPT
Get complete team member details by MongoDB ObjectId. REQUIRED: - team_member_id: MongoDB ObjectId of the team member Returns full team member profile including name, email, phone, role, skills, service areas, schedule, labor rates, and availability.

get_teams

ChatGPT
Get team members with advanced filtering and pagination. OPTIONAL: - filters: array of filter objects (same format as client filters) - page: page number (default: 1) - limit: max records per page (server-clamped to 30) - view: "all" or "own" (default: "all") - sorting: array of sorting objects [{field, order}] - assignable_only: "true" to only show members assignable to jobs FILTERABLE FIELDS: name, email, status, phoneNumber, address, createdAt, roleId, skillsId Filter structure: [ {"filterCondition": "", "field": "name", "condition": "contains", "value": "John"}, {"filterCondition": "and", "field": "status", "condition": "is", "value": "Active"} ]

get_units_of_measurement

ChatGPT
List the units of measurement configured in FieldCamp (reference data). No params. Returns the full org-wide list; each entry has an id, name, and abbreviation. Use this to find a valid unitOfMeasurementId BEFORE calling create_product_service or update_product_service. Pricing a product without a unit leaves it unitless, which lets a flat per-job price be multiplied by an area/quantity in estimates (e.g. 2000 sqft × $9500 = $19M). This is the only tool that enumerates valid unit ids.

get_vendors

ChatGPT
List vendors / suppliers configured in FieldCamp (reference data). OPTIONAL: - page: page number (default 1) - limit: max records (default -1 = all; any other value server-clamped to 30) - search: match vendor name or email (case-insensitive) Returns each vendor with id, name, email, phone, address, and status. The id is the valid value for the preferredVendorId field on create_product_service / update_product_service. Use this to find a valid preferredVendorId BEFORE creating or updating a product with a preferred vendor — this is the only tool that enumerates vendor ids.

get_visit_by_id

ChatGPT
Get complete visit/appointment details by MongoDB ObjectId. PARAMETERS: - visit_id: MongoDB ObjectId of the visit Returns visit information including job details, assigned team, schedule, status, and notes.

get_visit_stats

ChatGPT
Get visit statistics and list for a date range (dispatcher dashboard). OPTIONAL: - start_date: YYYY-MM-DD format (omit both dates for all visits) - end_date: YYYY-MM-DD format - view: "all", "ownEvents", "viewAssigned" (default: "all") RETURNS: - stats: {total, completed, pending, scheduled, in_transit, arrived, in_progress, paused, cancelled, active, unassigned} - visits: array of visits with job and client details Use for: "How many visits today?", "What's unassigned this week?", "Status breakdown for this month?"

get_visits_for_job

ChatGPT
Get all visits/appointments for a specific job. REQUIRED: - job_id: MongoDB ObjectId of the job Returns all active visits for the job with team member details, schedule, status, notes, and GPS tracking data. Sorted by start time.

get_warehouses

ChatGPT
List warehouses / inventory locations configured in FieldCamp (reference data). OPTIONAL: - page: page number (default 1) - limit: max records (default -1 = all; any other value server-clamped to 30) Returns each warehouse with id, name, address, and type. These ids are the valid values for transfer_inventory (fromWarehouseId / toWarehouseId) and the warehouse filter on get_inventory. Use this to discover warehouse ids BEFORE transferring stock or filtering inventory by location — otherwise the ids can only be scraped from get_inventory results.

list_object_definitions

ChatGPT
Discover this account's CUSTOM objects (tenant-defined record types such as "unit" or "warranty" — objects beyond the built-in clients/jobs/etc.). Returns for each object: slug (use it in every other *_record tool), names, record/field counts, whether it is schedulable, and its recordActions (valid action_key values for run_record_action). Call this FIRST when the user mentions a record type you don't recognize. Then call get_data_model("<slug>") for the object's fields and stages.

list_records

ChatGPT
List records of a CUSTOM object (e.g. slug="unit"). Call get_data_model(slug) first for this object's field names and valid status values — statuses are account-specific. PARAMETERS: - slug: the custom object's slug (from list_object_definitions) - page / limit: pagination (limit is clamped server-side) - search: free-text search over the object's searchable fields - status: filter by pipeline stage value (exact value from get_data_model) - filters: array of {field, condition, value}. field is a canonical field NAME from get_data_model(slug); condition is one of: is, isNot, contains, isEmpty, isNotEmpty, greaterThan, lessThan, equals, in (value must be an array for in). Example: [{"field": "next_pm_date", "condition": "lessThan", "value": "2026-09-01"}] - linked_record_id: only records related to this parent record id (e.g. all units of one client) - sort_field / sort_order: createdAt|updatedAt|status|id sort at the DB; any custom field name sorts in the application layer. asc|desc.

record_payment

ChatGPT
Record a manual payment on an invoice or estimate. REQUIRED: - documentId: MongoDB ID of the invoice/estimate - amount: payment amount (number) - date: ISO 8601 payment date (e.g. '2026-03-10') OPTIONAL: - method: payment method (e.g. 'cash', 'check', 'card', 'bank_transfer') - note: payment note/memo - paymentTypeCode: payment type classification - isDepositPayment: mark as deposit payment (default: false) Updates the document's paidAmount and paymentStatus (unpaid → partial → paid).

resolve_record_hierarchy

ChatGPT
Resolve a custom-object record's ancestor chain, ROOT-FIRST (e.g. Location → Unit → Equipment), with each level's visible fields. Use when a record belongs to a nested structure and you need its parents (e.g. which Location a Unit sits at). slug/record_id identify the LEAF.

run_record_action

ChatGPT
Execute a configured action button on a custom-object record (e.g. "Renew Now") — this RUNS the operation, which may create jobs or other records. Confirm with the user before calling. Valid action_key values: the object's recordActions from list_object_definitions(). Some actions accept an optional job_id.

send_document_email

ChatGPT
Send an invoice or estimate to a client via email. REQUIRED: - to: array of recipient email addresses - subject: email subject line - message: email message body OPTIONAL: - documentId: MongoDB ID of the document (for tracking) - documentType: 1=Invoice, 2=Estimate - documentNumber: document number (for PDF filename) - documentViewUrl: URL for 'View Document' button in email - cc: array of CC email addresses - bcc: array of BCC email addresses - attachPdf: boolean — attach rendered PDF (default: false)

transfer_inventory

ChatGPT
Transfer inventory between warehouses. REQUIRED: - fromWarehouseId: source warehouse MongoDB ID - toWarehouseId: destination warehouse MongoDB ID (must differ from source) - inventoryId: inventory record MongoDB ID to transfer from - quantity: number of units to transfer (must be > 0 and <= available stock) OPTIONAL: - note: transfer note/reason

update_calendar_event

ChatGPT
⚠️ CALL SHAPE — pass arguments exactly as: {"event_data": { "eventId": "<id>", ...fields... }} All record fields go INSIDE the *_data object, NOT at the top level (top-level keys are rejected as "unexpected keyword argument"). Update an existing Google Calendar event. REQUIRED fields in event_data: - eventId: string — ID of the event to update OPTIONAL fields: - title: string — new title - start: ISO 8601 datetime — new start, local time in the ACCOUNT's timezone — send the wall-clock time the user said and do NOT convert to UTC yourself; a trailing "Z"/offset is IGNORED, not honoured - end: ISO 8601 datetime — new end, same local-time rule - timeZone: IANA name — the calendar provider's display zone only; start/end are still read in the ACCOUNT's timezone - isAllDay: boolean - location: string or object - description: string - recurrence: object — new recurrence rules - attendees: array — updated attendees (set status='removed' to remove) - sendNotifications: boolean — notify attendees of changes - colorId: string — new color

update_client

ChatGPT
⚠️ CALL SHAPE — pass arguments exactly as: {"client_id": "<id>", "client_data": { ...fields to change... }} All record fields go INSIDE the *_data object, NOT at the top level (top-level keys are rejected as "unexpected keyword argument"). Update an existing client's information. REQUIRED: - client_id: MongoDB ObjectId (from search_database or get_filtered_clients) UPDATABLE fields (provide only what you want to change): - firstName, lastName, email, companyName, website, taxNumber - phoneNumber: {countryCode: "+1", number: "5559999999", countryIdentifier: "us"} - propertyAddress, billingAddress, companyAddress: {city, state, country, formattedAddress} - stage: ACCOUNT-SPECIFIC — call get_data_model("client") for this account's real stage values (accounts rename/replace the defaults; sending a stale default fails or mislabels the client) - clientType: "business" or "individual" - notes, properties (there is no tags field on clients) Example: { "phoneNumber": {"countryCode": "+1", "number": "5559999999", "countryIdentifier": "us"} }

update_document

ChatGPT
⚠️ CALL SHAPE — pass arguments exactly as: {"document_id": "<id>", "document_data": { ...fields to change... }} All record fields go INSIDE the *_data object, NOT at the top level (top-level keys are rejected as "unexpected keyword argument"). Update an existing invoice or estimate. REQUIRED: - document_id: MongoDB ObjectId of the document - document_data: Dictionary of fields to update ⚠️ There is NO top-level status field. Passing {"status": "..."} is a silent no-op (it changes nothing). Use documentStatus / actionStatus below. UPDATABLE fields (provide only what you want to change): - documentStatus: ACCOUNT-SPECIFIC (document pipeline is org-configurable) — call get_data_model("invoice") / get_data_model("estimate") for this account's real values. PATCH does not reject other strings (it stores whatever is sent), so a guessed value silently mislabels the document. Built-in defaults: "draft", "approved", "sent", "viewed", "pending", "approved_pending_signature". - actionStatus (ESTIMATES ONLY): record the customer's decision — 1 = accept, 2 = decline. - documentType: 1 (Invoice) or 2 (Estimate) - clientId: MongoDB ObjectId - jobId: MongoDB ObjectId - items: array of line items; per-line tax is set with taxIds (an array of tax ObjectIds), e.g. {"name": "...", "quantity": 1, "rate": 100, "taxIds": ["<taxId>"]}. (There is NO per-line taxes array of {name,rate}.) - comments: string (customer-facing notes) - privateNotes: string (internal notes) - date: ISO date (YYYY-MM-DD) — the issue/document date - dueDate: ISO date (YYYY-MM-DD) - discount: number ⚠️ PAYMENT STATUS CANNOT BE SET HERE. There is no way to mark a document paid/partial via this tool — recording a payment (which drives paid/partial) must go through the record_payment tool. Example (send an invoice/estimate to the customer): { "documentStatus": "sent" } NOTE: This tool sends PATCH on the wire (partial update). The backend bridge at /documents/[id]/route.js also accepts PUT as an alias, but PATCH is the canonical method.

update_job

ChatGPT
⚠️ CALL SHAPE — pass arguments exactly as: {"job_data": { "jobId": "<jobId>", ...fields... }, "notes": "optional"} All record fields go INSIDE the _data object, NOT at the top level (top-level keys are rejected as "unexpected keyword argument"). Update an existing job's information. REQUIRED parameters: - job_data: Dictionary containing job information OPTIONAL parameters: - notes: Additional notes (default: "") REQUIRED in job_data: - jobId: MongoDB ObjectId (from search_database, NOT the job number!) UPDATABLE fields: - jobAddress, jobPhone: objects - startDateTime, endDateTime: ISO 8601, local time in the ACCOUNT's timezone — send the wall-clock time the user said and do NOT convert to UTC yourself; a trailing "Z"/offset is IGNORED, not honoured - jobStatus: a status CHANGE is validated against the org's configurable job pipeline. If the org has no pipeline config, any value is accepted; if it does, an invalid transition returns HTTP 400 (invalidStatusTransition) and the valid stages are org-defined (may include custom values) — call get_data_model("job") for this account's real stages and allowed transitions before changing status. - jobType: "one-off", "recurring", "multi-day" - priority: "low", "medium", "high" - subTotal, tax, total, discount: numbers - discountType: string - jobItems: array of line-item objects, each ADDING to, editing or removing a line the job already has — this array does NOT replace the job's line items: • add — `itemName` (string) + `price` (per-unit number); `quantity` defaults to 1 and `total` is auto-computed (pricequantity). Reference an existing catalog item with itemId (24-hex items id — NOT productServiceId/id); omit it for an ad-hoc line. • edit — id (the LINE's 24-hex id, from get_job_by_id) + action: 2, plus only the fields that change. • remove — id + action: 3, nothing else. To replace a job's lines, remove the old ones in the same call as the new ones. subTotal/total are recomputed from the lines the job ends up with (the backend derives no money of its own) unless you send them yourself. - assignedToTeams: array of team IDs - jobTypeId: id from get_job_types (the account's job-type catalog) - targetRecordId + targetObjectSlug: link/relink the job to a custom-object record (e.g. targetObjectSlug="unit") - ⚠️ linkedRecords is NOT accepted (rejected with 400 — the backend silently drops it). Use targetRecordId + targetObjectSlug above instead. - billToClientId: bill a different client than the job's clientId - anyTime, serviceDuration, timezone, properties Example job_data: { "jobId": "689abc123def456", "jobStatus": "in-progress", "priority": "high" }

update_product_service

ChatGPT
⚠️ CALL SHAPE — pass arguments exactly as: {"product_service_id": "<id>", "product_service_data": { ...fields to change... }} All record fields go INSIDE the *_data object, NOT at the top level (top-level keys are rejected as "unexpected keyword argument"). Update an existing product or service in FieldCamp. REQUIRED: - product_service_id: MongoDB ObjectId of the product/service - product_service_data: Dictionary of fields to update OPTIONAL fields in product_service_data: - name: string (1-100 chars) - description: string - type: "Product" or "Service" - price: number (>= 0) - cost: number (>= 0) - currency: string - duration: integer (minutes, for services) - isActive: boolean - status: string ("available" or "unavailable") - isTaxExempt: boolean - isInventoried: boolean (toggles inventory tracking; if true, inventory required) - inventory: object {locationId (REQUIRED 24-hex warehouse id — the warehouse key is locationId, NOT warehouseId/warehouse/location), sku (REQUIRED, globally unique), quantity, lowStockAlert, binLocation} - taxIds: array of tax IDs - categoryIds: array of category IDs - properties: array (custom properties) - settings: object (online booking settings) - pricingType: "fixed" or "hourly" - hourlyRate: number (required if pricingType="hourly") - billingBasis: "scheduled" or "actual" - minimumCharge: number

update_record

ChatGPT
Update fields of a custom-object record. Send ONLY the fields you are changing, keyed by canonical field NAME (call get_data_model(slug) first). Does NOT change the record's pipeline stage — use change_stage for that.

update_request

ChatGPT
⚠️ CALL SHAPE — pass arguments exactly as: {"request_id": "<id>", "request_data": { ...fields to change... }} All record fields go INSIDE the *_data object, NOT at the top level (top-level keys are rejected as "unexpected keyword argument"). Update an existing service request. REQUIRED: - request_id: MongoDB ObjectId of the request - request_data: Dictionary of fields to update UPDATABLE fields: - stage: ACCOUNT-SPECIFIC (request pipeline is org-configurable) — call get_data_model("request") for this account's real stage slugs. Built-in default slugs: new_request, unscheduled, overdue, inspection_scheduled, inspection_complete, quote_created, quote_sent, converted, lost_no_response, lost_reject_quote, cancelled, duplicate - assignedTo: array of user MongoDB ObjectIds - followUpDate: ISO 8601 format or null - notes: string - description: string - urgency: string enum — "low", "medium", "high", "critical" - items: array of line items (full replace) Example: { "stage": "inspection_scheduled", "assignedTo": ["user_id_1"] }

update_task

ChatGPT
⚠️ CALL SHAPE — pass arguments exactly as: {"task_id": "<id>", "task_data": { ...fields to change... }} All record fields go INSIDE the *_data object, NOT at the top level (top-level keys are rejected as "unexpected keyword argument"). Update an existing task's information. Use field 'taskStatus' (NOT 'status') to update task status. REQUIRED: - task_id: MongoDB ObjectId of the task - task_data: Dictionary of fields to update UPDATABLE fields (provide only what you want to change): - name: string - taskStatus: ACCOUNT-SPECIFIC (task pipeline is org-configurable) — call get_data_model("task") for this account's real values. Built-in defaults: "scheduled", "pending", "in_progress", "completed", "cancelled" - priority: "low", "normal", "high", "urgent" - assignedToId: MongoDB ObjectId of user to assign - scheduleDateTime: ISO 8601, local time in the ACCOUNT's timezone — send the wall-clock time the user said and do NOT convert to UTC yourself; a trailing "Z"/offset is IGNORED, not honoured - scheduleEndDate: ISO 8601, same local-time rule as scheduleDateTime - dueDateTime: ISO 8601 — sent AS GIVEN (not converted), so include an explicit offset - instructions: string - category: "admin", "maintenance", "follow_up", "inspection" - completed: boolean - clientId: MongoDB ObjectId - jobId: MongoDB ObjectId - linkType: "client", "job", "estimate", "invoice" - duration: minutes (number) - allDay: boolean Example: { "taskStatus": "completed", "completed": true }

update_tax

ChatGPT
Update a tax rate in FieldCamp (partial update). REQUIRED: - tax_id: id of the tax to update (from get_taxes). - tax_data: dict of fields to change (name, rate, taxType, description, applyOnAllItems, countryId, stateId, effectiveDate, applicationRules). Only the keys present in tax_data are changed. Admin / settings permission required.

update_vendor

ChatGPT
Update a vendor / supplier in FieldCamp. REQUIRED: - vendor_id: id of the vendor to update (from get_vendors). OPTIONAL (only the fields you pass are changed): - name - email: must stay unique for the org (backend rejects a duplicate). - phone: composite OBJECT (dict), NOT a plain string — a bare string is rejected by the backend. Shape: {"countryCode": "+1", "number": "4155550100", "countryIdentifier": "us"} - address: composite OBJECT (dict), NOT a plain string — a bare string is rejected by the backend. Shape (sub-fields optional; at minimum pass {"formattedAddress": "..."}): {"formattedAddress": "...", "city": "...", "state": "..."} Call get_vendors first to obtain the vendor_id.

update_visit

ChatGPT
Update an existing visit's information. REQUIRED: - visitId: MongoDB ObjectId of the visit - jobId: MongoDB ObjectId of the job OPTIONAL (provide only fields to update): - visitStartDateTime, visitEndDateTime: ISO 8601, local time in the ACCOUNT's timezone — send the wall-clock time the user said and do NOT convert to UTC yourself; a trailing "Z"/offset is IGNORED, not honoured - visitStatus: see VALID TRANSITIONS below - priority: "low", "medium", "high" - teamId: team-member id(s) — a plain 24-hex id or a JSON-array string of ids (same as create_visit); "[]" unassigns everyone - anyTime: "true" or "false" (as string) - isConfirmed: "true" or "false" (as string) - isExtraVisit: "true" or "false" (as string) - notes: string - jobIncome: string (revenue for the visit) ⚠️ STEP-BY-STEP TRANSITIONS (cannot skip): typical default flow is scheduled → in_transit → arrived → in_progress → completed (paused↔in_progress; completed/cancelled are final). The exact stages + allowed transitions are PER ACCOUNT — call get_data_model("visit") for this account's real ones. ⚠️ TRANSITION REQUIREMENTS (the smart part): a transition can require a capability before it's allowed — e.g. on many accounts in_progress→completed REQUIRES a customer signature (others may require a photo, job form, or notes). get_data_model("visit") lists each transition's requirements. If a completion/transition is rejected for a missing requirement, tell the user what's needed (e.g. "collect the customer's signature first") and help them capture it — do NOT just retry the status change.

update_warehouse

ChatGPT
Update a warehouse / inventory location in FieldCamp. REQUIRED: - warehouse_id: id of the warehouse to update (from get_warehouses). OPTIONAL (only the fields you pass are changed): - name - warehouseType: e.g. 'Main Warehouse', 'Technician Truck/Van'. - address: composite OBJECT (dict), NOT a plain string — a bare string is rejected by the backend. Shape (all sub-fields optional; at minimum pass {"formattedAddress": "..."}): {"formattedAddress": "...", "street": "...", "city": "...", "state": "...", "country": "...", "zipCode": "..."} Call get_warehouses first to obtain the warehouse_id.

check_team_schedule_conflicts

Claude

convert_request_to_estimate

Claude

create_calendar_event

Claude

create_client

Claude

create_document

Claude

create_job

Claude

create_product_service

Claude

create_purchase_order

Claude

create_request

Claude

create_task

Claude

create_tax

Claude

create_vendor

Claude

create_visit

Claude

create_warehouse

Claude

delete_calendar_event

Claude

delete_client

Claude

delete_inventory

Claude

delete_invoice

Claude

delete_job

Claude

delete_payment

Claude

delete_product_service

Claude

delete_purchase_order

Claude

delete_request

Claude

delete_task

Claude

delete_tax

Claude

delete_vendor

Claude

delete_visit

Claude

delete_warehouse

Claude

fetch

Claude

get_all_team_members

Claude

get_analytics

Claude

get_available_team_members_schedule

Claude

get_calendar_activity

Claude

get_calendar_events

Claude

get_client_by_id

Claude

get_client_documents

Claude

get_client_payment_history

Claude

get_client_products

Claude

get_company_info

Claude

get_company_schedule

Claude

get_data_model

Claude

get_dispatch_suggestions

Claude

get_document_number

Claude

get_filtered_clients

Claude

get_filtered_jobs

Claude

get_history

Claude

get_inventory

Claude

get_inventory_by_id

Claude

get_invoice_by_id

Claude

get_invoices

Claude

get_job_by_id

Claude

get_next_job_number

Claude

get_payment_history

Claude

get_product_categories

Claude

get_product_service_by_id

Claude

get_products_services

Claude

get_purchase_orders

Claude

get_request_by_id

Claude

get_requests

Claude

get_task_by_id

Claude

get_tasks

Claude

get_tasks_by_client

Claude

get_tasks_by_job

Claude

get_taxes

Claude

get_team_member

Claude

get_teams

Claude

get_units_of_measurement

Claude

get_vendors

Claude

get_visit_by_id

Claude

get_visit_stats

Claude

get_visits_for_job

Claude

get_warehouses

Claude

record_payment

Claude

send_document_email

Claude

transfer_inventory

Claude

update_calendar_event

Claude

update_client

Claude

update_document

Claude

update_job

Claude

update_product_service

Claude

update_request

Claude

update_task

Claude

update_tax

Claude

update_vendor

Claude

update_visit

Claude

update_warehouse

Claude

Capabilities

Writes

Example Prompts

Click any prompt to copy it.

App Stats

185

Tools

3

Prompts

ChatGPT, Claude

Platforms

Category

CRM Records

Works with

ChatGPT
Claude

Data refreshed daily