---
title: Filters and pagination
description: MCP tools filter with their own JSON syntax and page with limit and a cursor, and global_search takes a text. The REST API uses filter and filter-op parameters and first and after.
canonical: https://developers.coevera.com/ai/filters-and-pagination/
section: ai
publisher: Coevera
---

# Filters and pagination

**Answer:** MCP tools do not use the REST query syntax. search_records, run_report and export_records take a JSON filter tree with AND, OR and NOT and operators such as eq, contains and gte, on fields marked filterable only. search_records pages with limit (default and maximum 100) and a cursor, where REST pages with first (default 30, maximum 100).

Agent builders often use both the MCP server and the REST API, and the two look alike without
being alike. This page sets them side by side.

## Filters

`search_records`, `run_report` and `export_records` take the same filter. A filter is a tree.
Inner nodes combine conditions; leaves test one field:

```text
{"AND": [node, node, ...]}
{"OR": [node, node, ...]}
{"NOT": node}
{"field_name": {"operator": value}}
```

| Operators                                                                  | Value                                                          |
| -------------------------------------------------------------------------- | -------------------------------------------------------------- |
| `eq`, `ieq`, `contains`, `icontains`, `starts`, `istarts`, `ends`, `iends` | A list of strings, matched with OR. The `i` forms ignore case. |
| `lt`, `lte`, `gt`, `gte`                                                   | A single value, as a string                                    |
| `null`, `empty`                                                            | `true` or `false`                                              |

- Only fields marked `filterable: true` by `meta_describe_entity` can be filtered. Filterable
  types are string, int, date, datetime, uuid and enum.
- Relation fields cannot be filtered. A condition on one is refused with an error.
- Call `meta_describe_entity` first: it gives the field names, their types and which can be
  filtered or expanded.

## Pagination

`search_records` returns at most `limit` records, 100 by default and at most. When more exist,
the response carries `has_next_page` and a `next_cursor`; pass the cursor as `after` or `cursor`
in the next call to get the following page.

Every tool rejects an argument name it does not know, with an error that lists the valid names,
so a misspelt cursor fails instead of returning the first page again.

## Text search

`global_search` takes a text instead of a filter and searches several entities at once, as the
search bar in Coevera does.

- The text is 2 to 200 characters. A record matches when every word of 3 or more characters
  appears in one of its searched fields, or when the whole text is a close match for one field.
  Words of 1 or 2 characters match the start of a word, and a phrase in double quotes must
  appear exactly.
- Only the fields the space admin has set for global search are searched; `meta_describe_entity`
  lists them, and `meta_list_entity_types` says which entities global search covers.
- Results are ranked by relevance, with counts per entity. Deleted records are left out;
  archived records are included and flagged. Each result links to its record; `get_records`
  gives the details.
- It pages with `limit` (1 to 50, 20 by default) and `cursor`, the previous response's
  `next_cursor`. A cursor works only with the same text and entities.
- Tasks and appointments are searched together. When you ask for only one of them, a page can
  hold fewer than `limit` results, so keep paging while there is a `next_cursor`.

## MCP and REST side by side

|                                    | MCP tools                                            | REST API                                                |
| ---------------------------------- | ---------------------------------------------------- | ------------------------------------------------------- |
| Filter syntax                      | JSON tree in the tool arguments                      | `filter[field]` and `filter-op[field]` query parameters |
| Negation                           | `NOT` node                                           | `not-eq`, `not-ieq`, `not-null`, `not-empty` operators  |
| Range                              | `gt`, `gte`, `lt`, `lte`                             | The same, plus `between`                                |
| Filter on a related record's field | Not supported                                        | Dotted paths, for example `filter[owner.email]`         |
| Page size                          | `limit`, default 100, maximum 100                    | `first`, default 30, maximum 100                        |
| Next page                          | `after` or `cursor`, with the previous `next_cursor` | `after` with the previous `page_info.end_cursor`        |
| More pages?                        | `has_next_page`                                      | `page_info.has_next_page`                               |
| Related records                    | `expand`                                             | `expand`, dot notation                                  |

The REST side is described in [querying](/concepts/querying/) and
[pagination](/concepts/pagination/). The MCP side is specified in the tool reference's
[filter syntax](https://mcp-server.coevera.com/doc#filter) and [expand](https://mcp-server.coevera.com/doc#expand) sections.

## Expand

`get_records` returns related records with `expand`. Name the relation and the related fields, either in flat form (`"relation": ["field", "nested.field"]`) or in dotted
form (`"relation.nested": ["field"]`). An empty relation comes back as `[]`.
