> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blockworks.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Tabular Datasets

> tabular_catalog and tabular_data browse the row-and-column models, then read rows with filters, sorting, and pagination.

Two tools cover tabular data, and they are meant to be used in order: the assistant discovers what exists, then
reads it.

| Tool              | Purpose                                                                                              |
| ----------------- | ---------------------------------------------------------------------------------------------------- |
| `tabular_catalog` | List the tabular models, or describe one in full: every column, its type, and the filters it accepts |
| `tabular_data`    | Read rows from one model, filtered, sorted, and paginated                                            |

Tabular models are row-and-column datasets (assets, exchanges, funding rounds, funds, ETF holdings) that answer
*what is true right now*. For metrics observed over time, use the [timeseries tools](/mcp/tools/timeseries); for
questions whose answer is written down rather than computed, start with
[`search_documents`](/mcp/tools/search).

These tools are a thin layer over the REST [Data API](/getting-started/concepts/catalog): the same models, the same
field names, the same filter operators. Anything documented for
[filtering and pagination](/getting-started/filtering-pagination) applies here too.

## The workflow

<Steps>
  <Step title="The assistant discovers what is queryable">
    `tabular_catalog` with no arguments returns one compact entry per model: `slug`, `name`, `description`,
    `access`, and `columnCount`. Passing `search` narrows that list by a case-insensitive substring match on the
    name, slug, and description.

    Passing a `model` slug instead returns that one model in full, including every column:

    | Field                     | What it is                                                              |
    | ------------------------- | ----------------------------------------------------------------------- |
    | `name`, `field`           | The display name and the exact field name to use in `tabular_data`      |
    | `description`             | What the column holds                                                   |
    | `type`, `unit`            | The column's data type and unit, where it has one                       |
    | `primaryKey`              | Whether the column identifies the row                                   |
    | `sortable`, `defaultSort` | Whether it can be sorted on, and whether it is the model's default sort |
    | `filters`                 | The exact operators this column accepts                                 |

    You can trigger this step explicitly:

    ```text theme={null}
    What Blockworks tabular datasets are available for funding rounds?
    ```

    ```text theme={null}
    Which columns can I filter on in the assets ranking dataset?
    ```
  </Step>

  <Step title="The assistant reads the rows">
    With a model identified, `tabular_data` reads it. Its arguments map onto the catalog exactly:

    | Argument                  | What it does                                                          |
    | ------------------------- | --------------------------------------------------------------------- |
    | `model`                   | The model slug, exactly as the catalog returns it. Required           |
    | `selections`              | Which column fields to return. Omit for every column                  |
    | `filters`                 | Conditions of the form `{field, operator, values}`, combined with AND |
    | `sortBy`, `sortDirection` | A sortable column field, and `asc` (default) or `desc`                |
    | `page`, `pageSize`        | 1-based page number, and rows per page: 25 by default, 200 at most    |

    ```text theme={null}
    Show me the top 10 assets by market cap.
    ```

    ```text theme={null}
    List DeFi protocols with more than $1B in TVL, sorted by 30-day TVL change.
    ```

    ```text theme={null}
    Which funding rounds closed above $50M this year, and who led them?
    ```
  </Step>
</Steps>

## Filters

A filter is an object of the form `{field, operator, values}`, and multiple filters combine with AND. A column only
accepts the operators its catalog entry lists:

| Operator                            | Meaning                                                         |
| ----------------------------------- | --------------------------------------------------------------- |
| `Eq`, `NotEq`                       | Equals, does not equal                                          |
| `Gt`, `Gte`, `Lt`, `Lte`            | Numeric and time comparisons                                    |
| `IsOneOf`, `IsNotOneOf`             | Value is, or is not, in the list                                |
| `Contains`                          | Case-insensitive substring match                                |
| `Includes`, `NotIncludes`           | An array column contains, or does not contain, this element     |
| `IncludesAnyOf`, `NotIncludesAnyOf` | An array column contains at least one of these, or none of them |

Values are written as strings and coerced to the column's type. Filters on a time column accept `YYYY-MM-DD`,
RFC3339, or unix seconds. The full operator reference, including which operators each column type supports, is on
[Filtering & Pagination](/getting-started/filtering-pagination).

## What comes back

`tabular_data` returns one page of rows plus the totals for the whole filtered set:

| Field                     | What it is                                             |
| ------------------------- | ------------------------------------------------------ |
| `model`                   | The model that was read                                |
| `rows`                    | The page of rows, as objects keyed by field name       |
| `totalRows`, `totalPages` | The size of the whole filtered set, not of this page   |
| `page`, `pageSize`        | The page that was returned, and how many rows it holds |

Because `totalRows` describes the whole filtered set, it is how you tell a complete answer from a first page. If a
result looks short, check it before concluding the data is thin.

<Note>
  The MCP tools cap a read more tightly than the REST API does, because every row returned is spent from the
  assistant's context window: 25 rows by default and 200 at most, against the REST API's 100 and 1000. A larger
  `pageSize` is clamped to 200 rather than rejected. To answer a question about a large model, filter and sort
  rather than paging through it.
</Note>

## Best practices

* **Name the entity precisely.** "Uniswap v4" and "Uniswap" resolve to different rows.
* **Say what to rank on.** "Sorted by 30-day TVL change" removes a guess that a bare "top protocols" leaves open.
* **State the filter you mean.** "Above \$1B in TVL" becomes a server-side filter; "the big ones" does not.
* **Ask what is available first** when you are scoping work: "what tabular datasets cover DeFi protocols?" tells
  you what is queryable before you commit to a specific prompt.

<Tip>
  Tabular models are also where series keys come from. If you want a metric over time for a named asset, the
  assistant reads the identifier out of the matching tabular model first, then hands it to
  [`timeseries_data`](/mcp/tools/timeseries) as a series key.
</Tip>

## When to use something else

* The answer is written down rather than computed. Use [`search_documents`](/mcp/tools/search).
* You want a metric over time at a stated granularity. Use the [timeseries tools](/mcp/tools/timeseries).

<Note>
  `tabular_catalog` lists only the models Blockworks publishes to the public API. Within that list, reading a model
  still depends on your key's entitlements, so "that data is not available" may be an entitlements boundary rather
  than a gap in coverage.
</Note>
