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.