Data Tools

Pure JSON/structure manipulation tools for operating on any value โ€” maps, arrays, or scalars. Zero credits, no external calls, no LLM. Plus data.map for fan-out orchestration over MCP tools. All tools accept either inline payload or a cache_ref from _meta.datagrout.cache_ref of any previous tool response. All Data tools are available at data-grout@1/data.*@1.


data.get@1

Access a value at a path within a nested structure.

Parameters

Parameter Type Required Default Description
payload any conditionally โ€“ JSON value to access. Provide either payload or cache_ref
cache_ref string conditionally โ€“ Cache reference from a prior tool call
path array yes โ€“ Ordered list of keys (strings) and indices (integers)

Example

{
  "name": "data-grout@1/data.get@1",
  "arguments": {
    "cache_ref": "rc_abc123...",
    "path": ["QueryResponse", "Invoice", 0, "TotalAmt"]
  }
}

Response: {"value": 150.00, "found": true}


data.pick@1

Keep only the specified keys from a map. If payload is a list of maps, picks from each one.

Parameters

Parameter Type Required Default Description
payload object | array conditionally โ€“ Map or list of maps
cache_ref string conditionally โ€“ Cache reference
keys array yes โ€“ List of key names to keep

Example

{
  "name": "data-grout@1/data.pick@1",
  "arguments": {
    "payload": {"name": "Alice", "age": 30, "email": "a@b.com", "internal_id": "xyz"},
    "keys": ["name", "age"]
  }
}

Response: {"data": {"name": "Alice", "age": 30}}


data.omit@1

Remove the specified keys from a map. If payload is a list of maps, omits from each one.

Parameters

Parameter Type Required Default Description
payload object | array conditionally โ€“ Map or list of maps
cache_ref string conditionally โ€“ Cache reference
keys array yes โ€“ List of key names to remove

data.take@1

Return the first N items from an array. When operating on a cache_ref, creates a structural-sharing view instead of duplicating data.

Parameters

Parameter Type Required Default Description
payload array conditionally โ€“ Array to take from
cache_ref string conditionally โ€“ Cache reference
n integer yes โ€“ Number of items to take

Response: {"data": [...], "count": N}


data.drop@1

Skip the first N items from an array and return the rest. Creates a view ref when using cache_ref.

Parameters

Parameter Type Required Default Description
payload array conditionally โ€“ Array to drop from
cache_ref string conditionally โ€“ Cache reference
n integer yes โ€“ Number of items to skip

data.keys@1

Return the keys of a map or the indices (0..n-1) of an array.

Parameters

Parameter Type Required Default Description
payload any conditionally โ€“ Map or array
cache_ref string conditionally โ€“ Cache reference

Response: {"keys": ["name", "age", "email"], "count": 3}


data.count@1

Count items in an array, keys in a map, or characters in a string.

Parameters

Parameter Type Required Default Description
payload any conditionally โ€“ Value to count
cache_ref string conditionally โ€“ Cache reference

Response: {"count": 42}


data.flatten@1

Flatten a nested map into a single-level map with dot-path keys.

Parameters

Parameter Type Required Default Description
payload object | array conditionally โ€“ Nested map or array
cache_ref string conditionally โ€“ Cache reference
separator string no "." Path separator

Example

{
  "name": "data-grout@1/data.flatten@1",
  "arguments": {
    "payload": {"user": {"name": "Alice", "address": {"city": "SF"}}}
  }
}

Response: {"data": {"user.name": "Alice", "user.address.city": "SF"}}


data.merge@1

Merge two maps together. Target values override base for conflicting keys.

Parameters

Parameter Type Required Default Description
base object conditionally โ€“ Base map (inline)
base_cache_ref string conditionally โ€“ Cache reference for base
target object conditionally โ€“ Map to merge on top
target_cache_ref string conditionally โ€“ Cache reference for target
deep boolean no false Recursively merge nested maps

data.filter@1

Filter items in an array using declarative predicate conditions with path-based field access. Works on any array โ€” record maps, nested objects, or flat values. When operating on a cache_ref, creates a structural-sharing view.

Parameters

Parameter Type Required Default Description
payload array conditionally โ€“ Array to filter
cache_ref string conditionally โ€“ Cache reference
where array yes โ€“ List of condition objects

Each condition in where:

Field Type Description
path array Path to the value to compare (list of keys/indices). [] compares the element itself
field string Shorthand for path: [field] โ€” use for simple record maps
op string Operator: eq, neq, gt, gte, lt, lte, in, not_in, contains, starts_with, ends_with, is_null, not_null
value any Comparison value (not needed for is_null/not_null)

Example: filter nested objects

{
  "name": "data-grout@1/data.filter@1",
  "arguments": {
    "cache_ref": "rc_abc123...",
    "where": [
      {"path": ["address", "state"], "op": "eq", "value": "CA"},
      {"field": "active", "op": "eq", "value": true}
    ]
  }
}

Response: {"data": [...], "count": 15, "removed": 85}

Example: filter flat array

{
  "name": "data-grout@1/data.filter@1",
  "arguments": {
    "payload": [1, 5, 10, 15, 20, 25],
    "where": [{"path": [], "op": "gte", "value": 10}]
  }
}

Response: {"data": [10, 15, 20, 25], "count": 4, "removed": 2}


data.sort@1

Sort any array. For flat arrays, sorts by value directly. For arrays of maps, use by to specify sort keys.

Parameters

Parameter Type Required Default Description
payload array conditionally โ€“ Array to sort
cache_ref string conditionally โ€“ Cache reference
by string | array no โ€“ Field name or list of sort specs with field/path and dir
dir string no "asc" Default direction when by is omitted or a simple string

Example: multi-field sort

{
  "name": "data-grout@1/data.sort@1",
  "arguments": {
    "cache_ref": "rc_abc123...",
    "by": [
      {"field": "department", "dir": "asc"},
      {"field": "salary", "dir": "desc"}
    ]
  }
}

Example: sort flat array descending

{
  "name": "data-grout@1/data.sort@1",
  "arguments": {
    "payload": [3, 1, 4, 1, 5, 9],
    "dir": "desc"
  }
}

Response: {"data": [9, 5, 4, 3, 1, 1], "count": 6}


data.unique@1

Deduplicate an array, keeping the first occurrence of each value.

Parameters

Parameter Type Required Default Description
payload array conditionally โ€“ Array to deduplicate
cache_ref string conditionally โ€“ Cache reference
by string no โ€“ Field name to deduplicate on (for arrays of maps)
path array no โ€“ Path to the value to deduplicate on (takes precedence over by)

Example

{
  "name": "data-grout@1/data.unique@1",
  "arguments": {
    "cache_ref": "rc_abc123...",
    "by": "email"
  }
}

Response: {"data": [...], "count": 42, "duplicates_removed": 8}


data.aggregate@1

Reduce a list to a single value using a named operation. Works on flat lists of numbers/values or on a specific field across a list of records.

Parameters

Parameter Type Required Default Description
payload array conditionally โ€“ List of values to aggregate
cache_ref string conditionally โ€“ Cache reference
op string yes โ€“ Operation: sum, mean, min, max, count, count_distinct, product, median, mode, range, join, first, last, flatten
field string no โ€“ When payload is a list of maps, the field to extract before aggregating
separator string no ", " Separator for the join operation

Example: sum a flat list

{
  "name": "data-grout@1/data.aggregate@1",
  "arguments": {
    "payload": [12, 435, 67543, 2567],
    "op": "sum"
  }
}

Response: {"result": 70557, "op": "sum", "count": 4, "skipped": 0}

Example: average a field across records

{
  "name": "data-grout@1/data.aggregate@1",
  "arguments": {
    "cache_ref": "rc_abc123...",
    "op": "mean",
    "field": "TotalAmt"
  }
}

Response: {"result": 2450.75, "op": "mean", "count": 24, "skipped": 0}

Example: join strings

{
  "name": "data-grout@1/data.aggregate@1",
  "arguments": {
    "payload": ["Alice", "Bob", "Charlie"],
    "op": "join",
    "separator": " | "
  }
}

Response: {"result": "Alice | Bob | Charlie", "op": "join", "count": 3, "skipped": 0}


data.map@1

Fan-out: call any MCP tool once per item in a list, collecting results. Like list.map { |item| tool.call(item) } where the function is any tool available on the current server. Each iteration is a separate tool call with its own credit charge. Executions run in parallel by default.

Parameters

Parameter Type Required Default Description
payload array conditionally โ€“ List of items to iterate over
cache_ref string conditionally โ€“ Cache reference
tool string yes โ€“ Fully-qualified tool name to call for each item
as string no โ€“ Inject each item as this named argument
template object no โ€“ Argument template with $item / $item.field placeholders
extra_args object no {} Additional arguments merged into every tool call
max_items integer no 50 Safety cap on items processed. Set to 0 for no limit
concurrency integer no 5 Max parallel tool calls. Set to 1 for sequential
on_error string no "collect" Error handling: collect (errors inline), skip (omit failures), abort (stop on first error)
timeout_ms integer no 30000 Per-item timeout in milliseconds

Example: look up multiple items

{
  "name": "data-grout@1/data.map@1",
  "arguments": {
    "payload": ["INV-001", "INV-002", "INV-003"],
    "tool": "quickbooks@1/get-invoice@1",
    "as": "id"
  }
}

Each item is passed as {"id": "INV-001"}, {"id": "INV-002"}, etc. Results are collected into a list.

Example: with template

{
  "name": "data-grout@1/data.map@1",
  "arguments": {
    "cache_ref": "rc_abc123...",
    "tool": "salesforce@1/get-account@1",
    "template": {"account_id": "$item.Id"},
    "concurrency": 3,
    "on_error": "skip"
  }
}

Example: enrich records with extra args

{
  "name": "data-grout@1/data.map@1",
  "arguments": {
    "payload": ["AAPL", "GOOG", "MSFT"],
    "tool": "market-data@1/get-quote@1",
    "as": "symbol",
    "extra_args": {"include_history": true, "period": "1d"}
  }
}

Response:

{
  "results": [
    {"symbol": "AAPL", "price": 185.23, ...},
    {"symbol": "GOOG", "price": 142.50, ...},
    {"symbol": "MSFT", "price": 415.80, ...}
  ],
  "total": 3,
  "succeeded": 3,
  "failed": 0,
  "skipped": 0,
  "_cache_ref": "rc_xyz789..."
}

The combined results are cached with their own cache_ref for downstream chaining โ€” pipe into data.filter, frame.group, prism.chart, etc.


Using cache_ref with data tools

Every tool call response includes _meta.datagrout.cache_ref. Use this ref in subsequent data tool calls to avoid re-transmitting payloads:

[
  {"tool": "salesforce@1/get-all-accounts@1", "args": {}, "output": "accounts"},
  {"tool": "data-grout@1/data.take@1", "args": {"cache_ref": "$accounts._meta.datagrout.cache_ref", "n": 5}},
  {"tool": "data-grout@1/data.pick@1", "args": {"cache_ref": "$accounts._meta.datagrout.cache_ref", "keys": ["Name", "Industry"]}}
]

Cache entries have a 10-minute touch-on-access TTL. All cached data is AES-256-GCM encrypted at rest. Entries are isolated per user.