# MCP field reference (/docs/developer/mcp-reference)



Use this reference to build an MCP request. Required fields are marked **Required**. Optional fields can be omitted unless a source adds a condition.

## At a glance [#at-a-glance]

| Contract                           | Where to read it                                                                |
| ---------------------------------- | ------------------------------------------------------------------------------- |
| Tool inputs                        | Tables below and the connected tool list                                        |
| Exact operation inputs and outputs | `execute` → `sift.spec(id)`                                                     |
| Organization-specific fields       | Field discovery operations and task playbooks                                   |
| Search results                     | `items`, `nextCursor`; `total` on an agent's first page, or with `includeTotal` |
| Analytics results                  | `rows`, `meta`, optional `comparison`                                           |
| Embedded app results               | `structuredContent`, text, and Sift link                                        |
| Personal connection fields         | MCP connections guide                                                           |

## What you're looking at [#what-youre-looking-at]

The `execute` tool runs a program. `sift.call(id, input)` takes the input of the operation directly.
For example, `sift.call("query.analytics.<source>", query)` takes the query.
Do not add REST pagination fields to an MCP operation.

## Core tool fields [#core-tool-fields]

| Tool              | Field       | Type, requirement, and behavior                                                                                     |
| ----------------- | ----------- | ------------------------------------------------------------------------------------------------------------------- |
| `execute`         | `code`      | **Required** nonempty string. JavaScript async function body. Use `return` for the result.                          |
| `execute`         | `timeoutMs` | Optional positive integer. Set explicitly for predictable runs; runtime default 90000, maximum 120000 milliseconds. |
| `execute`         | `userId`    | Optional compatibility string. Authentication determines identity; this field cannot override it.                   |
| `list_skills`     | No fields   | Send an empty object.                                                                                               |
| `read_skill`      | `name`      | **Required** nonempty string. Skill ID from `list_skills`.                                                          |
| `read_skill_file` | `name`      | **Required** nonempty string. Skill ID.                                                                             |
| `read_skill_file` | `file`      | **Required** nonempty string. Relative reference path listed by `read_skill`.                                       |

## Search operations [#search-operations]

| Source              | Operation                      | Use it for                                       |
| ------------------- | ------------------------------ | ------------------------------------------------ |
| `actions`           | `query.search.actions`         | One row per case                                 |
| `action_records`    | `query.search.action_records`  | One row per record, with engagement and authors  |
| `messages`          | `query.search.messages`        | Message records                                  |
| `reviews`           | `query.search.reviews`         | Requested or completed reviews                   |
| `users`             | `query.search.users`           | People                                           |
| `user_identities`   | `query.search.user_identities` | Per-platform identities                          |
| `user_ids`          | `query.search.user_ids`        | An ordered page of person IDs                    |
| `comments`          | `actions.case.comment.list`    | Comment records                                  |
| `lifecycle_events`  | `search.case.event.list`       | Assignments, status changes, sends, and activity |
| `listening_results` | `query.search.listening`       | Stored Listening posts in an explicit scope      |

Queues, agents, themes, tags, and other configuration entities are catalog operations.
Discover them with `sift.spec()` in `execute`. They are not extra `search.source` values.

## Common search input [#common-search-input]

These fields describe the common record selection. Source-specific exceptions follow.

| Field       | Type and behavior                                                                                                 |
| ----------- | ----------------------------------------------------------------------------------------------------------------- |
| `filter`    | Optional structured filter tree. Each source accepts its own fields and operators. Do not send a DSL string here. |
| `dateRange` | Optional absolute or relative date object. See date fields below.                                                 |
| `time`      | Optional timezone and time-of-day object. Some sources reject time-of-day filtering.                              |
| `sort`      | Optional object with `field` and optional `direction` (`asc` or `desc`). Valid fields depend on the source.       |
| `limit`     | Optional positive integer. Most record schemas accept 1–10000, default 50; runtime page caps can be lower.        |
| `cursor`    | Optional string. Pass the prior `nextCursor` unchanged with the same selection.                                   |

### Filter tree fields [#filter-tree-fields]

| Field        | Type and behavior                                                                                                 |
| ------------ | ----------------------------------------------------------------------------------------------------------------- |
| `filterType` | **Required** string. A source-supported leaf field, or `and` / `or` for a group.                                  |
| `operator`   | **Required** for a leaf. Use the operator declared for that field.                                                |
| `value`      | Leaf value. Type depends on the field: string list, scalar, boolean, or range object.                             |
| `filters`    | **Required** for an `and` / `or` group. Array of nested filter trees.                                             |
| `field`      | Required for filters such as `actionCustomField`, `agentCustomField`, or `formField`. Names the registered field. |
| `formId`     | Optional on `formField`. Limits the comparison to a form.                                                         |
| `tagTypes`   | Optional on supported `tag` / `tagId` clauses: `USER`, `SYSTEM`, `GEN_AI`.                                        |

Use `sift.spec` for the complete leaf union. A field supported by actions can fail on another source.
Unknown fields, operators, or values must not silently widen your query.

### Action-specific fields [#action-specific-fields]

| Field                      | Type and behavior                                                                                                            |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `dateField`                | Optional clock. Read its enum in `query.search.actions`. A case list reads the action date; a record list reads `createdAt`. |
| `idsOnly`                  | Optional boolean. Skips enrichment and returns identifiers and creation time.                                                |
| `includeModerationSummary` | Optional boolean, off by default. Adds the selected evaluation summary where moderation is available.                        |

Actions default to 50 rows per call and return at most 500.
A case list sorts by `easyId`, `createdAt desc`, or `updatedAt desc`.

`query.search.action_records` lists one row per record. It takes the same `filter`, `dateRange`, `time`, `dateField`, `idsOnly`, `includeModerationSummary`, `cursor` and `limit`. It also takes these fields, and any sort that the schema lists:

| Field                  | Type and behavior                                                                                                                   |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `includeBrandAuthored` | Optional boolean. Includes brand-authored records, excluded by default.                                                             |
| `project`              | Optional array of allowed extra column names, for example `["author", "score", "numComments"]`. Discover valid names in the schema. |

`query.search.actions` refuses `grain`, `project` and `includeBrandAuthored`, and the refusal names `query.search.action_records`.

### Context and message fields [#context-and-message-fields]

| Source                     | Field           | Type and behavior                                                                                                          |
| -------------------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `actions`                  | `context`       | Optional `lean` or `full`. Set it to read each case with its context; `full` adds more prior cases and cross-case history. |
| `actions`                  | `contextFormat` | Optional `text` or `json`. Default `text`; JSON separates profile, messages, notes, and history.                           |
| `actions` (with `context`) | `limit`         | Default 5; runtime maximum 20. Use small pages for full context.                                                           |
| `messages`                 | `externalScope` | Optional `exclude`, `include`, or `only`. Default `exclude`; controls ambassador external-context records.                 |

Messages sort by `createdAt` or `id`. Reviews sort by `createdAt`.
Comments sort by `createdAt`. Lifecycle events support `createdAt desc` only.
Users, comments, and lifecycle events do not support time-of-day windows.

### People fields [#people-fields]

| Field                            | Type and behavior                                                                               |
| -------------------------------- | ----------------------------------------------------------------------------------------------- |
| `windowKind`                     | Optional `community`, `activity`, `first_activity`, or `snapshot`.                              |
| `userProfiles`                   | Optional object.                                                                                |
| `userProfiles.fetchCustomFields` | Optional boolean, default false. Adds organization-defined user fields.                         |
| `userProfiles.filter`            | Optional object with the toggles below. Everything else about who a person is goes in `filter`. |

`scope` was retired. Per-platform identities are `query.search.user_identities` (a `keyword` filter and paging only). An ordered page of profile ids is `query.search.user_ids` (a people filter and paging only).
Find a person by name, handle, or email with a `keyword` leaf in `filter`. Send volume bounds as a `volume30d` leaf.
The community window is the top-level `windowKind` and `dateRange`.
A date range alone does not change a People snapshot into an active-user population.

| `userProfiles.filter` field         | Type and behavior                                                                 |
| ----------------------------------- | --------------------------------------------------------------------------------- |
| `filterEmptyRecords`                | Optional boolean, default true. Keep profiles with linked, non-deleted records.   |
| `championsOnly`, `excludeChampions` | Optional booleans. Include only champions or exclude them.                        |
| `championTerms`                     | Optional string array. Champion matching terms.                                   |
| `staffOnly`, `excludeStaff`         | Optional booleans. Include only community staff or exclude them.                  |
| `staffTerms`                        | Optional string array. Community staff matching terms.                            |
| `requirePeriodActivity`             | Optional boolean. Community mode with a window; require in-window contribution.   |
| `sortModel`                         | Optional array with required `colId` string and `sort` (`asc` / `desc`) per item. |

### Listening fields [#listening-fields]

| Field                      | Type and behavior                                                                                                                        |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `scope`                    | Optional object with required `from` and `to`, and optional `filters`. Do not combine with `dateRange`.                                  |
| `scope.filters.filterTree` | Optional saved-view filter tree. Top-level `filter` narrows it.                                                                          |
| `filter`                   | Optional structured Listening filter tree.                                                                                               |
| `dateRange`, `time`        | Optional common window fields. Use the intended Listening window.                                                                        |
| `sort`                     | Optional stored engagement field, `authorFollowers`, or `observedAt`. Default `observedAt desc`; ascending observation order is refused. |
| `limit`                    | Optional integer, 1–100; default 50.                                                                                                     |
| `cursor`                   | Optional previous continuation token.                                                                                                    |

Listening requires personal authentication and the organization's Listening feature.
Its scope `from` is inclusive and `to` is exclusive. Ranked analysis can stop at a bounded cap.
Read the returned window and scope metadata. Do not report a capped set as every matching post.

## Dates, timezone, and sort [#dates-timezone-and-sort]

| Field                                      | Type and behavior                                                                                    |
| ------------------------------------------ | ---------------------------------------------------------------------------------------------------- |
| `dateRange.from`, `dateRange.to`           | **Required** strings for an absolute window. ISO date or date-time. End must not precede start.      |
| `dateRange.relative.unit`                  | **Required** `day`, `week`, `month`, or `year`.                                                      |
| `dateRange.relative.count`                 | **Required** integer, 1–3660.                                                                        |
| `dateRange.relative.calendar`              | **Required** boolean. `true` starts on a calendar unit boundary.                                     |
| `dateRange.relative.includeCurrent`        | **Required** boolean. Include the current day or end before it.                                      |
| `time.timezone`                            | Optional IANA timezone. Defaults to organization timezone, then UTC.                                 |
| `time.timeOfDay.from`, `time.timeOfDay.to` | **Required** `HH:mm` strings when a clock window is present. A start after the end crosses midnight. |
| `sort.field`                               | Source-specific sort field. Required by record sort objects; optional in analytics.                  |
| `sort.direction`                           | Optional `asc` or `desc`. Analytics defaults to `desc`.                                              |

Use either an absolute or relative window. Resolved query windows use an exclusive UTC `to` bound.
Date-only bounds represent calendar days in the selected timezone. Read resolved bounds in result metadata.
The REST action-list endpoint has different date rules; see its reference.

## Analytics input fields [#analytics-input-fields]

Pass this query directly to `sift.call("query.analytics.<source>", query)`.

| Field               | Type and behavior                                                                             |
| ------------------- | --------------------------------------------------------------------------------------------- |
| `v`                 | **Required** literal `1`.                                                                     |
| `source`            | **Required** supported data source. Discover source IDs in the schema and analytics playbook. |
| `filter`            | Optional structured tree for the whole query.                                                 |
| `dateRange`, `time` | Optional window and timezone fields described above.                                          |
| `lines`             | **Required** array with at least one measured line.                                           |
| `groupBy`           | **Required** array of dimensions. Use an empty array for an ungrouped result.                 |
| `sort`              | Optional result ordering.                                                                     |
| `limit`             | Optional positive integer; maximum result rows.                                               |
| `options`           | Optional source-specific options below.                                                       |

### Measured line fields [#measured-line-fields]

| Field                            | Type and behavior                                                                                        |
| -------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `measure`                        | **Required** nonempty metric ID. Validity depends on the source.                                         |
| `aggregation`                    | **Required** `sum`, `avg`, `median`, `p75`, `p90`, `p95`, `p99`, `count`, `min`, `max`, or `percentage`. |
| `label`                          | Optional display string; echoed in metadata.                                                             |
| `filter`                         | Optional tree. Narrows this line within the query filter.                                                |
| `customFieldKey`                 | Optional registered numeric action field.                                                                |
| `sampleCount`                    | Optional literal `rows`. Adds the line's sample size.                                                    |
| `formula`                        | Optional calculated line; replaces plain aggregation.                                                    |
| `formula.op`                     | **Required** `divide`, `percent_of`, `subtract`, or `add`.                                               |
| `formula.left`, `formula.right`  | **Required** operand objects.                                                                            |
| Operand `measure`, `aggregation` | **Required** metric ID and aggregation.                                                                  |
| Operand `filter`                 | Optional tree. Narrows the operand within the line filter.                                               |
| `formula.round`                  | Optional integer. Decimal places; omit to avoid rounding.                                                |

Each grouping object has required `field` and optional `customFieldKey`.
Metric and dimension compatibility depends on the source. Read the analytics playbook and exact operation contract before guessing IDs.

### Analytics options [#analytics-options]

| Field                     | Type and behavior                                                                        |
| ------------------------- | ---------------------------------------------------------------------------------------- |
| `windowKind`              | Optional `community`, `activity`, `first_activity`, or `snapshot` for Users populations. |
| `dateField`               | Optional action clock from the schema.                                                   |
| `threshold`               | Optional numeric cutoff for a threshold metric.                                          |
| `asOf`                    | Optional `range_end`. Read historical action state at the window end.                    |
| `comparison`              | Optional `previous_period` or `previous_year`.                                           |
| `comparisonOutput`        | Optional `paired`, `delta`, `percent_change`, or `new_members`.                          |
| `excludeSystemAgents`     | Optional boolean. Excludes system agents.                                                |
| `includeAgentAttribution` | Optional boolean. Adds the agent that did the work.                                      |
| `fillEmpty`               | Optional boolean. Fills empty time buckets with zero.                                    |
| `resultKind`              | Optional literal `transitions`. Returns state transitions.                               |

## Find fields and values [#find-fields-and-values]

Read the fields and metrics of a data source with `sift.spec("query.analytics.<source>")`. It returns the TypeScript declaration of the query, with one comment line per filter field: its name, its operators, and the list source that holds its values.

List a field's values with that list source: `sift.call("query.search.<list>", input)`. The lists are `tags`, `tag_groups`, `channels`, `queues`, `teammates`, `servers`, `goals`, `saved_searches`, `themes`, `statuses`, `platforms`, `competitors`, `discord_roles`, `qa_forms`, `user_groups`, `gainsight_values`, `custom_fields` and `custom_field_options`. People come from `query.search.users`: find a person with a `keyword` leaf, `{ filter: { filterType: "keyword", operator: "contains", value: ["<words>"] } }`.

| Field    | Type and behavior                                                 |
| -------- | ----------------------------------------------------------------- |
| `name`   | Optional string. Keeps the rows whose name contains it.           |
| `ids`    | Optional array. Returns exactly these rows.                       |
| `budget` | Optional integer. Tokens per page, default 4,000, at most 15,000. |
| `cursor` | Optional string. Pass the prior `nextCursor` unchanged.           |

Each row has `id` and `name`. Put `id` in a filter leaf; a name is refused. A custom field's label is its field name: list the fields with `query.search.custom_fields { source }` and a field's options with `query.search.custom_field_options { field }`.

## Creator lookup fields [#creator-lookup-fields]

Use external creator lookup only when the user asks for it. Call `social.profile.get` with `sift.call`. It is not a stored Sift search.

| Input field           | Type and behavior                                                                |
| --------------------- | -------------------------------------------------------------------------------- |
| `url`                 | **Required** nonempty public profile or supported link-aggregator URL.           |
| `includeDemographics` | Optional boolean, default true. Request age and gender inference from the photo. |

| Output field             | Meaning                                                                                                            |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------ |
| `url`                    | Requested URL.                                                                                                     |
| `demographics`           | Nullable object: optional `ageLow`, `ageHigh`, `gender`, and `confidence` (0–100). Inferences, not verified facts. |
| `expandedIdentity`       | Nullable aggregator identity with `provider`, `sourceUrl`, optional profile facts, and platform links.             |
| `untrustedContentNotice` | Reminder to treat public text as evidence.                                                                         |

`expandedIdentity.provider` is `linktree`, `linkme`, `komi`, `pillar`, `linkbio`, or `beacons`.
Its required fields are `provider`, `sourceUrl`, `verticals` (string array), and `destinations` (array).
Optional strings are `username`, `displayName`, `bio`, `avatarUrl`, and `email`.
Each destination has required string `platform` and `url`, and optional string `title`.
Missing facts stay missing.

## App and reply tool fields [#app-and-reply-tool-fields]

Use these tools only when the connected server advertises them. App views require personal OAuth.
The embedded app remains a development prototype; text and native links can work without an embedded view.

| Tool                              | Fields                                                                                                                                                                                                              |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `open_inbox`                      | Optional `scope`: `queues` (default) or `mine`; optional trimmed `search` up to 200 characters; optional `cursor`; optional integer `limit` 1–50, default 30.                                                       |
| `open_action`                     | **Required** nonempty `actionId`.                                                                                                                                                                                   |
| `open_dashboard`                  | **Required** nonempty `slug`, `from`, and `to`.                                                                                                                                                                     |
| `open_dashboard_evidence`         | **Required** `slug`, `widgetId`, `from`, `to`, `expectedUpdatedAt`; optional `cursor`; optional integer `limit` 1–50, default 20.                                                                                   |
| `prepare_reply`                   | **Required** UUID `requestId`, nonempty `actionId`, trimmed `text` 1–24000 characters; optional nonempty `serverId`; optional boolean `isPublicReply`.                                                              |
| `review_reply`, `send_reply`      | **Required** UUID `requestId` only. Human confirmation supplies the decision.                                                                                                                                       |
| `open_reply`, `get_reply_request` | **Required** UUID `requestId` only. Read preparation and delivery state.                                                                                                                                            |
| `review_handle_reply`             | **Required** UUID `requestId` for the account owner's review request. Personal OAuth; no decision field.                                                                                                            |
| `save_reply_draft`                | App-only. **Required** `actionId`, `expectedRevision` (64 characters), `clientMutationId` (8–128 characters), trimmed `text` (1–10000 characters), and `replyAccountId`. Saves a pending email review; never sends. |

`expectedUpdatedAt` binds evidence to the saved dashboard revision.
`expectedRevision` binds a draft to the current reply context. Use values returned by the prior read.
`clientMutationId` is a retry key. Reuse it only for the same draft.
`serverId` selects the sending account. `isPublicReply` selects public or private mode.
`requestId` binds one immutable reply; a changed draft requires a new UUID.

## Events fields [#events-fields]

Events require a modern client, an advertised Events capability, and personal OAuth.
Use `events/list` to discover the supported `action.message_received` event and its payload schema.
It covers future incoming Instagram and Messenger messages on one action. It excludes backfill and brand replies.

| Method               | Fields                                                                                                                                                                                                                                 |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `events/list`        | Optional `cursor`; omit it for the current single-page event catalog.                                                                                                                                                                  |
| `events/subscribe`   | **Required** `name`: `action.message_received`; required `arguments.actionId`; required `delivery.mode`: `webhook`; required `delivery.url` and `delivery.secret`; optional `cursor`: null; optional positive integer or null `ttlMs`. |
| `events/unsubscribe` | **Required** UUID `id` of the subscription.                                                                                                                                                                                            |

The callback must use HTTPS and pass verification. The secret uses `whsec_` with 24–64 base64-encoded key bytes.
Keep it in a secret store. The subscription has a finite lifetime; retain its returned expiry.

Payload fields are `eventId` (UUID), `name`, `timestamp` (ISO date-time), `data.actionId`, `data.recordId`, `data.url`, and `cursor` (null).
Verify signed webhook headers before processing. Read the action for current evidence; an event is not permission to send.

## Result fields and schema discovery [#result-fields-and-schema-discovery]

Inside `execute`, `sift.call` returns the operation output. If the operation fails, it throws an Error whose message names the `code`, the `message`, and the failing fields.
An approval-required result does not contain a completed write.

```js
// The TypeScript declaration of the operation: its input and output types.
return await sift.spec("query.analytics.actions")
```

`sift.spec(id)` returns one operation as a TypeScript declaration: `declare function call(id, input: XInput): Promise<XOutput>`, with each field's description as a doc comment. The input and output are named types in the same text. A type that repeats, such as the filter tree, is written once and used by name. The declaration is generated from the same schema the server validates with, so it stays current when the server changes. HTTP clients read the same contract as JSON Schema in OpenAPI.

`sift.spec()` with no id returns the catalog index: `id`, `productFamily`, optional `aliases`, `summary`, `description`, `domain`, `effect`, `access`, `ui`, `url`, `discovery`, optional `examples`, `inputSchema` and `outputSchema`. Filter it in code and return only what you need.

### Search output [#search-output]

Read `items` and `nextCursor`. A null cursor ends the list. Search does not return a total.
Source metadata varies; inspect the output schema. An empty first page carries `emptyReason`.
Action rows can include `id`, `actionId`, `threadId`, `userId`, `username`, `author`, `engagement`, `platform`, `operationStatus`, `channelId`, `channel`, `summary`, `description`, `matchedText`, `easyId`, `easyIdNumber`, `link`, and `url`.

Use `actionId` for a case, `link` for its Sift page, and `url` for public source evidence.
Fields can be null or absent. Projections add source-specific columns; do not assume all rows contain all fields.

### Analytics output [#analytics-output]

| Field                  | Meaning                                                                                        |
| ---------------------- | ---------------------------------------------------------------------------------------------- |
| `rows`                 | Grouping values and measured line values.                                                      |
| Row `_filter`          | Record selection behind the group. Combine with query and line filters for evidence reads.     |
| Row `_window`          | Optional window for an action-clock bucket.                                                    |
| `meta.queryJSON`       | Exact query that ran, including resolved scope and defaults.                                   |
| `meta.source`          | Resolved source.                                                                               |
| `meta.dateField`       | Optional resolved action clock.                                                                |
| `meta.dateRange`       | Optional resolved `from` / `to` window; `to` is exclusive.                                     |
| `meta.appliedDefaults` | Array of `id` and `summary` for applied defaults.                                              |
| `meta.truncated`       | Whether more rows exist than returned.                                                         |
| `meta.lines`           | Per-line `key`, `label`, `measure`, `aggregation`, optional `sampleCountKey` and `windowKind`. |
| `meta.units`           | Optional units. Read before displaying durations or scores.                                    |
| `comparison`           | Optional prior-period `dateRange` and `rows`.                                                  |

Read values by `meta.lines[].key`, not by a guessed column name.
App tools return their view in `structuredContent`. Preserve the native URL and versioned view fields.
Use the connected output schema for a complete app projection; do not treat an app result as a search envelope.

## Tips [#tips]

* Read schemas before new operations. Do not infer fields from tool names.
* Use real returned IDs. Labels and usernames do not replace every ID field.
* Preserve pagination scope and returned evidence links.
* Keep credentials out of `code` and other tool arguments.

Read the [Record field dictionary](/docs/developer/record-fields) for `pmid`, `prid`, other short keys, and nested result fields.

## Related [#related]

<Cards>
  <Card href="/docs/developer/agent-guide" title="Agent guide">
    Working procedure and copyable recipes.
  </Card>

  <Card href="/docs/developer/mcp-connections" title="MCP connections">
    Authentication and connection fields.
  </Card>

  <Card href="/docs/developer/api-reference" title="API field reference">
    The separate REST contracts.
  </Card>
</Cards>
