Sitemate
Interact with Sitemate data
- Category
- Productivity
- Primary Subcategory
- Field Service Management Software
Integration details
Description
The Sitemate app in ChatGPT lets you search, query, and interact with your construction and project management data in one place. Access information stored across Sitemate, including Dashpivot, using natural language to surface insights, track progress, and answer questions instantly.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Field Service Management Software
- Secondary Subcategories
- None listed
- Brand
- Sitemate
- Access
- Account required
- First tracked
- 2026-07-09
- Tool count
- 6
- Geography
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Get alerts for Sitemate
Get updates when Sitemate’s Discoverability Score or category rank changes.
ChatGPT Plugin Discovery Score
ChatGPT Plugin discovery is coming soon
ChatGPT can surface a Plugin when it matches a user's request.Your Plugin Discovery Score measures how often yours appears.
No spam. Unsubscribe any time.
What discovery looks like

Competing in ChatGPT Field Service Management Software
View Category6 tools agents can invoke
Retrieves app (template) definitions from Dashpivot with field-level metadata. ## Purpose Gateway to form data. Discover apps, review field definitions, select field IDs before calling get-forms. ## Prerequisites - For browse queries: call get-workspace-structure first to discover the hierarchy, then pass _path values. - For direct lookup: use `appIds` with any app identifier (FlakeID, ObjectId, or unique app ID). No _path needed — the server resolves it automatically. - If the user provides a Dashpivot URL, extract the ID from the URL path and pass it to `appIds`. ## Scoping Rules - **Preferred**: Use a project/team _path (e.g., "/ws_xxx/p_xxx") for targeted browse results. - **Broader**: Using a workspace _path ("/ws_xxx") may return many apps — only use for workspace-level apps or when a narrower _path is unavailable. - Combine _path with appName or templateTags to narrow results further. ## Parameters - appIds: Look up apps by any identifier — FlakeID (app_xxx), MongoDB ObjectId (24 hex chars), or unique app ID (e.g. TDW-C-JK6AQ). No _path needed. - _path: Required for browse queries, optional when appIds is provided. Use the narrowest paths available (e.g., ["/ws_xxx/p_xxx"]). - appName / templateTags: Filter apps - pageSize (default 25, max 25), pageCursor for pagination ## Key Behaviour - List/browse queries return app metadata with `fieldCount` only — look up specific apps by `appIds` to get full field definitions - Each app includes a `_path` field — use directly as `_path` in get-forms (e.g., ["/ws_xxx/p_xxx/app_xxx"]) - For workspace-wide queries, use `_path: ["/" + workspaceId]` (e.g., ["/ws_xxx"]) - A `/ws_xxx/app_xxx` path returns both workspace-level apps and their team-level deployed copies together, only team-deployed copies have forms. To get-forms, pass in a team-level path `/ws_xxx/p_xxx/p_xxx/app_xxx` as `_path`. ## Field Selection for get-forms When calling get-forms, pass specific field IDs via the optional `fieldIds` parameter to control which fields are returned. Omitting fieldIds returns ALL fields including media (photo, signature, sketch) which contain large binary data. Select fields based on the task: - For text analysis: use singleLineInput, multiLineInput fields - For date filtering: use date fields - For status checks: use category, yesNoCheckbox fields - Avoid media fields (photo, signature, sketch, attachment) unless specifically needed — they contain large binary data ## Examples - Browse all apps in a project: `{ _path: ["/ws_xxx/p_xxx"] }` - Find safety templates: `{ _path: ["/ws_xxx/p_xxx"], templateTags: ["safety"] }` - Get field definitions for a specific app: `{ appIds: ["app_xxx"] }` <!-- mcp-router:region-aware-pagination --> **Pagination across regions:** The response includes `pageDetails.regions` keyed by region (e.g. `au1`, `uk1`). To get the next page, pass `pageCursor` as a JSON object (not a string) with an entry for each region where `isLastPage: false`. Example: `pageCursor: {"au1": "ws_abc", "uk1": "ws_xyz"}`. Omit `pageCursor` entirely for the first page. `pageSize` applies per-region — the response may include up to `pageSize × N` items where N is the number of regions with data.
get-apps
Retrieves form data (filled-in records) for summarization, analysis, and reporting. ## When to Use - If the user provides a specific _path, call get-forms directly — do NOT call get-workspace-structure or get-apps first. - If the user asks about forms without a path, follow the standard discovery workflow. - If get-forms returns 0 results, check the instructions field for diagnostic guidance before making follow-up calls. ## Required Parameter - **_path**: Array of FlakeID paths (max 100). Use `_path` values from get-apps or get-workspace-structure (e.g., ["/ws_xxx/p_xxx/app_xxx"] or ["/ws_xxx"]). ## Key Parameters - formName / fieldFilters: Filter forms - workflowStep: Filter by workflow column — accepts position numbers (1, 2) and/or column name strings ("Supervisor Approval"). Case-insensitive. - createdDate: Filter by creation date range (`{ after?, before? }` — ISO 8601 strings in **UTC**, e.g. `2026-01-01T00:00:00Z`). Use when the user is asking about when forms were *started* or *opened*. - updatedDate: Filter by last-updated date range (`{ after?, before? }` — ISO 8601 strings in **UTC**, e.g. `2026-01-01T00:00:00Z`). Use when the user is asking about when forms were *submitted*, *completed*, or *finalised* — `updatedAt` advances when a draft is filled in or saved, while `createdAt` is fixed at the moment the form was first opened. - fieldIds: Return only specific fields (use IDs from get-apps) - pageSize (default 10, max 10), pageCursor for pagination ## Choosing createdDate vs updatedDate A form can be drafted on day 1 and submitted on day 8. `createdAt` is fixed at draft time; `updatedAt` reflects the last save. Map customer phrasing to the right filter: - "submitted / completed / filled out / finalised in the last week" → `updatedDate` - "started / drafted / opened / created in the last week" → `createdDate` - Both filters can be combined; they compose with AND. - When the intent is ambiguous, prefer `updatedDate` and state the choice in your reply. - All date bounds are interpreted as **UTC**. Convert any relative or local-time phrasing ("today", "last week") to absolute UTC ISO 8601 strings before calling. ## Response Format (compact) Compressed JSON with ~63% fewer tokens. Field values are lossless. Forms are grouped by app. Structure: - `apps`: array of app groups, each containing: - `appPath`: shared app path for this group - `fields`: array of { name, kind } — field definitions declared once per app - `forms`: array of { id, name, num, workflowCol, created, by, values } — each form's `values` array is positionally mapped to `fields` - Shortened keys: id=itemId, num=automatedFormNumber, workflowCol.pos=workflowColumn.position, workflowCol.name=workflowColumn.name, created=createdAt, by=createdBy.name - Pagination: pass `pageDetails.cursor` back as `pageCursor` to fetch the next page. `pageDetails.pageNumber` is informational only. Example response: ``` {"apps":[{"appPath":"/ws_xxx/p_xxx/app_xxx","fields":[{"name":"Inspector","kind":"singleLineInput"},{"name":"Status","kind":"category"}],"forms":[{"id":"form_xxx","name":"Inspection #1","num":"SI-001","workflowCol":{"pos":2,"name":"Supervisor Approval"},"created":"2026-03-20T10:00:00Z","by":"John","values":["Michael",[{"name":"Pass","value":"pass"}]]}]}],"totalFormCount":42,"instructions":["Sending form 1 of 42.","More results available. Pass the cursor value as pageCursor to fetch the next page."],"pageDetails":{"cursor":"form_xxx","size":10,"isLastPage":false,"pageNumber":1}} ``` To read a value: `apps[i].forms[j].values[k]` corresponds to `apps[i].fields[k]`. Field IDs for fieldFilters/fieldIds are available from get-apps. ## Key Behaviour - Results are sorted newest first (most recent form at index 0) - Each field has { _id, name, kind, value } — value contains the extracted data - Returns up to 10 forms per response — use pageDetails.cursor for pagination when more results exist - More specific _path values return faster results - Field value structures vary by kind — see get-apps field definitions for type metadata ## Examples - Get all forms for an app: `{ _path: ["/ws_xxx/p_xxx/app_xxx"] }` - Forms from Q1 2026: `{ _path: ["/ws_xxx/p_xxx/app_xxx"], createdDate: { after: "2026-01-01T00:00:00Z", before: "2026-04-01T00:00:00Z" } }` - Forms submitted in Q1 2026: `{ _path: ["/ws_xxx/p_xxx/app_xxx"], updatedDate: { after: "2026-01-01T00:00:00Z", before: "2026-04-01T00:00:00Z" } }` - Return only text fields: `{ _path: ["/ws_xxx/p_xxx/app_xxx"], fieldIds: ["fi_xxx", "fi_yyy"] }` - Forms in approval step: `{ _path: ["/ws_xxx/p_xxx/app_xxx"], workflowStep: ["Supervisor Approval"] }` - Forms in columns 1 or 2: `{ _path: ["/ws_xxx/p_xxx/app_xxx"], workflowStep: [1, 2] }`
get-forms
Retrieves Dashpivot lists (spreadsheet-like data containers): columns, items, and property values. Lists power list fields and list property columns in forms — use this to understand what data populates form dropdowns and lookup fields. ## Modes (dispatched by leaf prefix of each _path) - **Browse** (leaf is ws_ or p_): returns list metadata plus `columns` (so the LLM can see what each list is shaped like and read `columns[].id` for follow-up `columnFilters`). `items` and `itemsPagination` are omitted. Use when discovering which lists exist under a workspace/project. - **Details** (leaf is li_): returns full data for the named list — columns, items, and property values. Use when a specific list has been identified to inspect. `columns` is always present on every list entry (empty array when the list has no columns). Browse and details paths can be mixed in one call — each entry resolves on its own leaf prefix. ## When to Use - If the user provides a specific _path, call get-lists directly — do NOT call get-workspace-structure first. - If the user asks about lists without a path, follow the standard discovery workflow: browse first, then narrow to a li_ path for details. - If get-lists returns 0 results, check the instructions field for diagnostic guidance. ## Required Parameter - **_path**: Array of FlakeID paths (max 100). Workspace/project paths (e.g., ["/ws_xxx"], ["/ws_xxx/p_xxx"]) trigger browse mode; list paths (e.g., ["/ws_xxx/li_xxx"]) trigger details mode. ## Key Parameters - listName: Filter by list name (case-insensitive partial match) — narrows which lists are returned in browse mode. - itemValue: Filter items by display value — the Item column shown in the list library (case-insensitive partial match). Only meaningful in details mode. - columnFilters: Filter items by column values. AND across entries, OR within each entry's queries. Each filter has a `columnId` (lp_ FlakeID — read from `columns[].id` in a prior details response), `queries` (array of one or more string/number values for OR matching within the entry), and an optional `match` mode controlling how each query compares to the cell value: `"contains"` (default — case-insensitive substring), `"exact"` (case-insensitive equality — use for IDs, codes, and precise numeric matches: `queries: ["1"]` with `match: "exact"` matches `"1"` only, NOT `"10"` or `"9991"`), or `"prefix"` (case-insensitive starts-with). To find rows where a column is empty / has no value, fetch the list without columnFilters and look for null in each item's positional properties array at the relevant column index. Only items matching ALL filter entries are returned. Only meaningful in details mode. - pageSize (default 25, max 25), pageCursor for list-level pagination. - itemPageSize (default 100, max 1000) — items per details list per page. Silently ignored for browse paths. - itemCursors — per-list item pagination cursors keyed by full list path (e.g. `{ "/ws_xxx/li_yyy": "lr_..." }`). Each value is an item FlakeID from a previous response's `itemsPagination.cursor`. Lists not in the map start at page 1; cursors for lists not in `_path` are silently ignored. ## Response Shape (compact) - Browse entries emit `{ id, path, name, created, updated, columns }` — no `items`, no `itemsPagination`. - Details entries additionally emit `{ items, itemsPagination }`. Keys are shortened: `id`=itemId, `path`=full `_path`, `created`=createdAt, `updated`=updatedAt. - `columns` is always present (empty array when the list has no columns). - `columns` is declared once per list as `[{ id, name, model }]` where `id` is the lp_ FlakeID (use it for `columnFilters[].columnId`) and `model` is one of: `text-simple`, `number-simple`, `date-simple`, `date-expiry`, `attachment-simple`. Use `model` to interpret each column's values. - `items` is an array of `{ id, value, properties }`. `properties` is a positional array — `properties[i]` corresponds to `columns[i]`. Length always equals `columns.length`; missing/unsupported properties are `null`. - `itemsPagination` is `{ cursor?, isLastPage }`. To fetch more items for a list, pass back the cursor via top-level `itemCursors` keyed by the list's `path`. ## Key Behaviour - Browse mode returns metadata only; details mode returns columns, items, and per-list `itemsPagination`. - Only active lists and items are returned. - Details entries are always returned even when filters yield no items on the current page — advance via `itemsPagination.cursor` to look further. Browse entries don't carry `itemsPagination`. - When `columnFilters` is set, pages reliably fill up to `itemPageSize` matched items; `itemsPagination.isLastPage` is true exactly when no further matches exist. - `columnFilters[].columnId` must be a valid lp_ FlakeID read from `columns[].id` on a prior details response — names are not accepted. Filters whose `columnId` is not on the list contribute no matches. - Lists exist at workspace or project level (never teams). Workspace-level lists can be deployed into projects. ## Examples - Discover lists in a workspace (browse): `{ _path: ["/ws_xxx"] }` - Inspect a specific list (details): `{ _path: ["/ws_xxx/li_xxx"] }` - Browse then narrow: first call with the workspace path to see what lists exist, then call again with the chosen list's li_ path to fetch its data. - Find lists by name: `{ _path: ["/ws_xxx"], listName: "Materials" }` - Search items by display value: `{ _path: ["/ws_xxx/li_xxx"], itemValue: "Concrete" }` - Filter items by column value: `{ _path: ["/ws_xxx/li_xxx"], columnFilters: [{ "columnId": "lp_xxx", "queries": ["Active"] }] }` - OR within a column: `{ _path: ["/ws_xxx/li_xxx"], columnFilters: [{ "columnId": "lp_xxx", "queries": ["Active", "Pending"] }] }` - Multiple column filters (AND): `{ _path: ["/ws_xxx/li_xxx"], columnFilters: [{ "columnId": "lp_type", "queries": ["Steel"] }, { "columnId": "lp_grade", "queries": ["A"] }] }` - Advance one list's items: `{ _path: ["/ws_xxx/li_a", "/ws_xxx/li_b"], itemCursors: { "/ws_xxx/li_a": "lr_..." } }` — only `li_a` advances; `li_b` returns item page 1.
get-lists
Retrieves user information within a workspace's folder hierarchy. ## Modes - **users-in-folder**: List the users in a specific folder. - **folders-for-user**: Given a person's name or email, list which folders they can access within the queried workspace(s). ## PII Protection Every user in the response has `lastName` reduced to its initial (e.g. "S") and `email` masked (e.g. "j***@example.com"). `firstName`, `sitemateUserId`, and `_id` are unmasked. Do not reconstruct or guess full names/emails from the masked values — ask the human if you need the original. ## When to Use - "Who has access to this project?" → mode "users-in-folder" - "Which folders can <person> access?" / "What is <person>'s access in this workspace?" → mode "folders-for-user" ## Required Parameters - **_path**: Array of 1-100 FlakeID paths from get-workspace-structure. Each must be workspace-rooted (e.g. "/ws_xxx" or "/ws_xxx/p_xxx"). Paths may span multiple workspaces. - **mode**: "users-in-folder" or "folders-for-user" ## Mode-Specific Parameters - **users-in-folder**: pageSize, pageCursor. Pass multiple paths to union users across folders — a user who appears in any queried folder is returned once. Lists users granted on the queried folder OR a sub-folder beneath it; access inherited from a PARENT is not reflected (query the parent folder to see its controllers). - **folders-for-user**: provide `name` or `email` (exact match, takes precedence over name). `name` uses case-insensitive **exact** equality, not substring/partial — "John" matches users whose firstName OR lastName is exactly "John"; "John Smith" matches firstName "John" AND lastName "Smith". Returns one of: a single **user-match** with their accessible folders (inheritance-aware — a workspace controller is listed for a queried child folder); a **disambiguation** signal carrying NO user data when multiple users share the name (ask the human for the exact email, then re-call with `email`); or **no-match**. ## Notes - users-in-folder membership is a superset of folders-for-user reachability. users-in-folder lists a user straight from the permission service regardless of whether the granting folder is still active, so it can include grants on archived/deleted sub-folders that folders-for-user (which resolves to active folders only) will not return. ## Examples - Users in a project: `{ _path: ["/ws_xxx/p_xxx"], mode: "users-in-folder" }` - Users across multiple projects: `{ _path: ["/ws_xxx/p_a", "/ws_xxx/p_b"], mode: "users-in-folder" }` - Users across workspaces: `{ _path: ["/ws_A", "/ws_B"], mode: "users-in-folder" }` - Folders a user can access: `{ _path: ["/ws_xxx"], mode: "folders-for-user", name: "John Smith" }` - Disambiguate by exact email: `{ _path: ["/ws_xxx"], mode: "folders-for-user", email: "[email protected]" }`
get-users
Browse the Sitemate workspace hierarchy by drilling from workspaces → projects → teams. Returns a level-discriminated page — one of `workspaces[]`, `projects[]`, or `teams[]` per call, never the full tree. Use `_path` values from one response as input to the next. ## When to Call First tool in any workflow. Walk the 3-call pattern below to resolve a workspace name to a project or team `_path`, then pass that `_path` to tools like `get-apps`. ## Parameters - `_path` (string[]): omit to list workspaces; `["/ws_xxx"]` to list projects in a workspace; `["/ws_xxx/p_yyy"]` to list teams in a project. - `nameFilter` (string): case-insensitive partial match on the entity name at the current `_path` level. Use short, distinctive substrings (`"Acme"`, not `"Acme Construction Pty. Ltd."`). - `state`: `"active"` (default), `"archived"`, or `"deleted"`. Workspaces don't support `"deleted"`. - `pageSize`: default 50, max 50. - `pageCursor`: pass `pageDetails.cursor` from the previous response. ## Response Always carries `level` + `instructions[]`. Switch on `level` before accessing arrays: - `level: "workspace"` → `workspaces[]` (`itemId`, `_path`, `name`, `projectCount`, `totalTeamCount`) - `level: "project"` → `projects[]` (`itemId`, `_path`, `name`, `teamCount`) - `level: "team"` → `teams[]` (`itemId`, `_path`, `name`) Empty pages omit the array entirely; check `pageDetails.isLastPage` before paginating. ## Worked example (browse → drill → drill) 1. `get-workspace-structure({})` → `level: "workspace"`, e.g. `_path: "/ws_acme"` 2. `get-workspace-structure({ _path: ["/ws_acme"] })` → `level: "project"`, e.g. `_path: "/ws_acme/p_highway"` 3. `get-workspace-structure({ _path: ["/ws_acme/p_highway"] })` → `level: "team"`, e.g. `_path: "/ws_acme/p_highway/p_safety"` Pass the final `_path` to `get-apps` to fetch apps at that scope. ## Cursor-error recovery Cursors are scope-bound to the level that issued them. Reusing a cursor across scopes returns a `BadRequestError` with a `cursorValidationFailureMode` discriminator (`workspace-cursor-on-drill-down`, `drill-down-cursor-on-workspace`, or `unrecognised-prefix`). Recovery: drop the cursor and retry without it. Don't try to translate cursors across scopes. <!-- mcp-router:region-aware-pagination --> **Pagination across regions:** The response includes `pageDetails.regions` keyed by region (e.g. `au1`, `uk1`). To get the next page, pass `pageCursor` as a JSON object (not a string) with an entry for each region where `isLastPage: false`. Example: `pageCursor: {"au1": "ws_abc", "uk1": "ws_xyz"}`. Omit `pageCursor` entirely for the first page. `pageSize` applies per-region — the response may include up to `pageSize × N` items where N is the number of regions with data.
get-workspace-structure
Logs missing or unclear capabilities in the Sitemate toolset. ## When To Call - You cannot answer the user's Sitemate-related requests with the listed tools at all. - You can answer it, but only by chaining multiple Sitemate discovery tools together. That friction is the signal. - The user uses a Sitemate domain noun that isn't a parameter or tool name in the schema (e.g., "actions", "incidents", "RFIs"). - Do NOT call for non-Sitemate requests (web search, weather, Slack messages). ## How To Call - Call early and often in parallel with your other tool calls. - It is free to call as it logs the gap without blocking and does NOT count as a failure. - Once per stuck moment is enough — don't repeat the same suggestion in a conversation. - Do not treat it as an alternative to answering; it's silent telemetry. ## Parameters - **intent** (recommended): Plain-language description of what the user actually asked for. Be concrete — "show forms past their due date" beats "find late stuff". - **suggestedToolName** (required): Your guess at what the tool would be called, in kebab-case (e.g. "get-forms"). - **attemptedTools** (optional): Array of tool names you already tried / used as a workaround (e.g., ["get-workspace-structure", "get-apps", "get-forms"]). Non-empty = friction report; empty = no workaround attempted. - **conversationId** (recommended): Same UUID across all tool calls answering the user's question, so calls can be correlated. ## Response Format Returns a literal acknowledgement — there is no payload to act on: ``` { "logged": true, "message": "Feedback logged." } ``` This is a telemetry channel, not a router. The response is informational only. ## Examples - Domain noun + chained Sitemate discovery: `{ "intent": "show me the top 10 actions across my workspace", "suggestedToolName": "get-actions", "attemptedTools": ["get-workspace-structure", "get-apps", "get-forms"], "conversationId": "abc-123" }` - Sitemate filter not exposed: `{ "intent": "find all overdue forms in the middle of a safety audit", "suggestedToolName": "get-overdue-forms", "attemptedTools": ["get-forms"], "conversationId": "abc-123" }` - True gap in Sitemate toolset: `{ "intent": "create a new Sitemate template from scratch", "suggestedToolName": "create-template", "conversationId": "abc-123" }`
suggest
How do I improve a ChatGPT Plugin's discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are Sitemate alternatives on ChatGPT?
As of 2026-09-29, Sitemate competes with A4B CMMS, AI Dispatcher by FieldCamp, BlueSuite, Crisphive, D-Tools Cloud, DroneBundle, EquipDash, EZFlow Pro, Field Control, FieldCamp, Fielmo, Fluix, Front Desk, Itcons.app Work Reports, Jobber, Knowify, magicplan, Meistron, Obratec, OpsBack, PracticPro, Presuo, ProjectBase Beta, Qminder, QuoteCraft AI, Relay Tow, ServiceM8, STACK, Sunwise, Taskara, Trussi AI in ChatGPT Field Service Management Software, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.