AgentDBDocs

Query your data

With AgentDB you find exactly the records you need. You can:

  • filter records by field values and by linked records,
  • sort and page through large results,
  • count, sum and average without paging,
  • search text across records by words,
  • save a query as a view and run it again later.

Every query is exact and typed. AgentDB never guesses what you meant.

#Example data

The examples on this page use deals that belong to companies. Your agent would set this up with a few tool calls:

MCPChecked
{"tool": "schema_define_object", "arguments": {"name": "company"}}
MCPChecked
{"tool": "schema_define_field", "arguments": {"object": "company", "name": "name", "type": "text", "unique": true}}
MCPChecked
{"tool": "schema_define_field", "arguments": {"object": "company", "name": "country", "type": "text"}}
MCPChecked
{"tool": "schema_define_object", "arguments": {"name": "deal"}}
MCPChecked
{"tool": "schema_define_field", "arguments": {"object": "deal", "name": "title", "type": "text", "unique": true}}
MCPChecked
{"tool": "schema_define_field", "arguments": {"object": "deal", "name": "stage", "type": "enum", "enum_values": ["open", "won", "lost"]}}
MCPChecked
{"tool": "schema_define_field", "arguments": {"object": "deal", "name": "amount", "type": "integer"}}
MCPChecked
{"tool": "schema_define_field", "arguments": {"object": "deal", "name": "closed_on", "type": "date"}}
MCPChecked
{"tool": "schema_define_relationship", "arguments": {"name": "for_company", "source_object": "deal", "target_object": "company", "cardinality": "one"}}
MCPChecked
{"tool": "records_upsert_batch", "arguments": {"object": "company", "match_on": "name", "records": [{"data": {"name": "Example Ltd", "country": "NL"}}, {"data": {"name": "Sample GmbH", "country": "DE"}}]}}
MCPChecked
{"tool": "records_upsert_batch", "arguments": {"object": "deal", "match_on": "title", "records": [{"data": {"title": "Website redesign", "stage": "open", "amount": 12000}}, {"data": {"title": "Support contract", "stage": "won", "amount": 4800, "closed_on": "2026-09-14"}}, {"data": {"title": "Data migration", "stage": "won", "amount": 9500, "closed_on": "2026-10-02"}}, {"data": {"title": "Training day", "stage": "lost", "amount": 1500, "closed_on": "2026-10-20"}}]}}
MCPChecked
{"tool": "relationships_link_batch", "arguments": {"source_object": "deal", "relationship": "for_company", "links": [{"source_key": {"title": "Website redesign"}, "target_key": {"name": "Example Ltd"}}, {"source_key": {"title": "Data migration"}, "target_key": {"name": "Example Ltd"}}, {"source_key": {"title": "Support contract"}, "target_key": {"name": "Sample GmbH"}}]}}

#Filter records

records_query takes the object, a where filter, a sort and a limit. All conditions in where.all must match.

MCPChecked
{"tool": "records_query", "arguments": {"object": "deal", "where": {"all": [{"field": "stage", "op": "eq", "value": "open"}, {"field": "amount", "op": "gte", "value": 10000}]}, "sort": [{"field": "amount", "order": "desc"}], "limit": 20}}

The same query over REST and from the CLI:

RESTChecked
curl -X POST https://app.agentdb.link/v1/workspaces/$AGENTDB_WORKSPACE/query \
  -H "Authorization: Bearer $AGENTDB_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"object":"deal","where":{"all":[{"field":"stage","op":"eq","value":"open"}]}}'
CLIChecked
agentdb query --json '{"object":"deal","where":{"all":[{"field":"stage","op":"eq","value":"open"}]}}'

#Operators

Which operators work depends on the field type.

OperatorMeaningWorks on
eq, neqequal, not equalmost types
inequal to one of up to 100 valuesmost types
lt, lte, gt, gteless than, greater thannumbers, dates, times, text
is_null, is_not_nullhas no value, has a valueevery type
contains, starts_withtext contains, text starts with, ignoring casetext, email, url, phone, rich text
contains, has_any, has_allthe list holds an item, any item, all itemsmulti_select, list
within_bbox, nearinside a box, near a pointgeo

Some rules to know:

  • eq on text is exact and case-sensitive. Use contains or starts_with to ignore case.
  • A field without a value never matches eq, neq or a range. Only is_null finds it.
  • boolean fields take only eq, neq and the null operators.
  • You can filter on the built-in fields id, created_at and updated_at.
  • A query holds at most 20 conditions.

agentdb_capabilities {"operation": "records_query"} lists the exact operators per field type.

A relationship condition matches records whose linked records match. This finds deals for companies in NL:

MCPChecked
{"tool": "records_query", "arguments": {"object": "deal", "where": {"all": [{"relationship": "for_company", "where": {"all": [{"field": "country", "op": "eq", "value": "NL"}]}}]}}}

Add "direction": "incoming" to follow links that point at the queried object. A query holds at most 3 relationship conditions.

#Sort and page

  • sort takes one field with "order": "asc" or "desc". Ties are sorted by id, so the order is stable.
  • Without sort, records come oldest first.
  • Fields without a value come first when ascending and last when descending.
  • limit is 1 to 200. The default is 50.

When more records match, the result holds a next_cursor. Send it as cursor with the identical query to get the next page. A next_cursor of null means you have them all.

MCPChecked
{"tool": "records_query", "arguments": {"object": "deal", "sort": [{"field": "amount", "order": "desc"}], "limit": 2}}
MCPChecked
{"tool": "records_query", "arguments": {"object": "deal", "sort": [{"field": "amount", "order": "desc"}], "limit": 2, "cursor": "$NEXT"}}

Add "fields": ["title", "amount"] to return only those fields. Archived records stay hidden unless you add "include_archived": true.

#Count and total

Use records_aggregate for counts, sums, averages, minimums and maximums. AgentDB computes them, so you never page through records to add them up.

MCPChecked
{"tool": "records_aggregate", "arguments": {"object": "deal", "group_by": ["stage"], "metrics": [{"op": "count"}, {"op": "sum", "field": "amount"}]}}

Group date fields by hour, day, week, month or year:

MCPChecked
{"tool": "records_aggregate", "arguments": {"object": "deal", "where": {"all": [{"field": "stage", "op": "eq", "value": "won"}]}, "group_by": [{"field": "closed_on", "bucket": "month"}], "metrics": [{"op": "sum", "field": "amount"}]}}
  • Group by up to 3 fields, with up to 10 metrics.
  • where uses the same filter as records_query.
  • count needs no field. Every other metric needs one.

From the CLI, agentdb records count deal --by stage gives a quick count per stage.

Full-text search finds records by words, ranked by relevance. Turn it on once per object. By default AgentDB indexes every text-like field.

MCPChecked
{"tool": "search_configure", "arguments": {"object": "deal", "enabled": true}}

From then on, AgentDB keeps the index current on every write. Search with records_search:

MCPChecked
{"tool": "records_search", "arguments": {"object": "deal", "query": "website redesign"}}
CLIChecked
agentdb search query deal migration
  • Every word must occur. Add "match": "any" to match at least one word.
  • The last word also matches as a prefix, so migr finds "migration".
  • Punctuation is ignored. A search holds at most 8 words.
  • Each hit has a score, the matched fields and highlighted snippets.
  • Add a where filter to search only matching records.

#Saved views

A saved view is a named query that you or your agent can run again. Views are versioned. A view is private by default. With "visibility": "workspace", everyone in the workspace can use it, each with their own permissions.

MCPChecked
{"tool": "views_create", "arguments": {"name": "open_deals", "object": "deal", "definition": {"where": {"all": [{"field": "stage", "op": "eq", "value": "open"}]}, "sort": [{"field": "amount", "order": "desc"}]}, "visibility": "workspace"}}
MCPChecked
{"tool": "views_run", "arguments": {"view": "open_deals"}}
CLIChecked
agentdb views run open_deals

A view can also describe how to show its records: as a table, list, kanban board, calendar, timeline or report. You can share a view read-only through a link. See Dashboards and sharing.

#Next steps