Skip to main content
Glama

Read Sheet Rows

sheet.read
Read-onlyIdempotent

Read rows from a sheet the user has access to. Returns the sheet's title and up to limit row objects. ID-typed cells are pre-resolved to display names: single-value (Member, Team, Job, Status, Select, Pipeline, Actor, CreatedBy, ModifiedBy) become the resolved name; list-valued (Employee List, Team List, Job List, Multi-Select, Relation) become a comma-joined string. Original FK ids are preserved on each row under _ids[code] (string for single-valued, string[] for list-valued) when you need them for follow-up tools. Mirror and File List cells pass through as raw values. filters values on those columns may be the names you see (e.g. Status EQ 'Done', Assignee EQ 'Sara'); an unknown or ambiguous name is an error that lists the choices. Document and Description cells are returned IN FULL as markdown by default — headings, lists, links and code preserved — so you never need a second call to read a description. All other cells are clipped to 80 characters with a trailing '…'. Rows come in a stable order. Each call returns as many whole rows as fit (up to limit), with total (rows matching the filters), hasMore and nextOffset: to read every row, call again with offset = nextOffset until hasMore is false. To count rows that match a condition, pass filters and read total instead of paging. Use a tighter limit when you only need a sample. Archived rows are left out unless archived is shown or only; then each row carries Archived and ArchivedAt. Contact cells (email, phone, address, location; on the employee sheet also handle and bio) come back as null unless includeContactFields is true — set it only when the user explicitly asks for contact details. Password cells are always null. sort orders the rows by up to three fields (name or code, asc or desc); for latest, recent or newest questions sort by ModifiedAt desc (recently changed) or CreatedAt desc (recently added), for the oldest use asc. Without sort rows keep the sheet's board order. Empty cells come first in a descending sort, and a sort field edited between calls can shift rows across pages. fields returns only the named attributes plus id; documents = preview clips Document and Description cells to 80 characters and omit leaves them out — use either to scan many rows in one call, then read one row (e.g. filter Index EQ) for its documents in full.

Input Schema

NameRequiredDescriptionDefault
sortNoRow order, up to three keys applied in turn; `field` is an attribute name or code. Newest first = `[{ field: "ModifiedAt", direction: "desc" }]` (recently changed) or CreatedAt desc (recently added)
limitNo
fieldsNoReturn only these attributes (names or codes) plus `id`; use it to scan many rows per call
offsetNoRow position to start at; pass the previous call's `nextOffset` to read the next page
filtersNo
sheetIdYes
archivedNoArchived rows: hidden (default), shown alongside the rest, or only the archived ones
documentsNoDocument and Description cells: `full` markdown (default), an 80-char plain-text `preview`, or `omit` themfull
includeContactFieldsNoReturn email, phone, address and location cells. Set it only when the user explicitly asks for someone's contact details.

Output Schema

NameRequiredDescriptionDefault
rowsYesRow objects keyed by attribute code; ID-typed cells are display names, raw ids under `_ids`
sheetYesThe sheet that was read
totalYesHow many rows match the filters and archived setting
offsetYesPosition of the first returned row
hasMoreYesTrue when rows remain after this page
returnedYesHow many rows this call returned
truncatedYesSame as `hasMore`
nextOffsetYesPass as `offset` to read the next page; null when `hasMore` is false

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • removedOutput schema / properties / nextOffset / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / nextOffset / type
      Added value: +[
      +  "number",
      +  "null"
      +]
  2. Changed3 schema fields changed
    • addedInput schema / properties / documents
      Added value: +{
      +  "default": "full",
      +  "description": "Document and Description cells: `full` markdown (default), an 80-char plain-text `preview`, or `omit` them",
      +  "enum": [
      +    "full",
      +    "preview",
      +    "omit"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / fields
      Added value: +{
      +  "description": "Return only these attributes (names or codes) plus `id`; use it to scan many rows per call",
      +  "items": {
      +    "minLength": 1,
      +    "type": "string"
      +  },
      +  "minItems": 1,
      +  "type": "array"
      +}
    • addedInput schema / properties / sort
      Added value: +{
      +  "description": "Row order, up to three keys applied in turn; `field` is an attribute name or code. Newest first = `[{ field: \"ModifiedAt\", direction: \"desc\" }]` (recently changed) or CreatedAt desc (recently added)",
      +  "items": {
      +    "properties": {
      +      "direction": {
      +        "enum": [
      +          "asc",
      +          "desc"
      +        ],
      +        "type": "string"
      +      },
      +      "field": {
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "field",
      +      "direction"
      +    ],
      +    "type": "object"
      +  },
      +  "maxItems": 3,
      +  "minItems": 1,
      +  "type": "array"
      +}
  3. First observed

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Far exceeds the annotations (which only cover read-only/idempotent/no-destroy safety). It discloses non-obvious behaviors an agent could not guess: ID cells pre-resolved to display names with originals preserved under `_ids[code]`, contact cells null by default, password cells always null, non-document cells clipped to 80 chars, stable row order, and the caveat that a sort field edited between calls can shift rows across pages.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Almost every sentence carries unique, non-redundant information and the most important facts (purpose, pagination contract) come first. It is a single dense block with no line breaks or bullets across nine parameters, which makes it harder to scan than it needs to be despite the high information density.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a nine-parameter tool with nested sort objects and an output schema, the description covers everything an agent needs: access requirement, pagination loop, filtering semantics, cell-type handling, archival, sorting, and field projection. Return-shape detail is arguably redundant given the output schema, but nothing needed to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 67% and notably `filters` and `limit` have no schema description at all; the description compensates by explaining that filters accept display names (e.g. Status EQ 'Done'), that an unknown/ambiguous name errors with the choices listed, and by documenting the exact pagination contract (limit/offset/nextOffset/hasMore/total) and sort semantics including empty-cells-first on descending.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb and resource ('Read rows from a sheet') and immediately bounds scope with 'the user has access to' plus what is returned (title and up to limit row objects). It implicitly separates itself from sheet.aggregate by explaining how to get counts via filters/total rather than paging, but it never names that or any other sibling, so an agent must infer the boundary rather than being told.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to guidance throughout: use filters+total to count instead of paging, use a tighter limit when sampling, set includeContactFields only when the user explicitly asks for contact details, use documents=preview/omit to scan many rows, and sort ModifiedAt desc for 'latest/recently changed' vs CreatedAt desc for 'recently added'. It also states exclusions (password cells always null, archived rows omitted by default) that tell the agent when not to expect data.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources