Parameterized query tools usage examples#
This page provides complete examples of parameterized tool definitions, invocation, and rendered SQL. For more information, read this MCP tool’s documentation.
Customer analysis with static tables#
This example demonstrates static table resources, CONSTANT_LIST with
allowedValues, COLUMN_REF with parent validation, FUNCTION_REF, and
optional parameters with defaults.
name: customer_analysis
description: >
Analyze customers by market segment with flexible filtering.
Returns customer details and aggregated order information.
tables:
- name: customers
tableName: tpch.tiny.customer
- name: orders
tableName: tpch.tiny.orders
parameters:
- name: segments
type: CONSTANT_LIST
description: Market segments to include in analysis
sqlType: VARCHAR
required: true
constraints:
minItems: 1
maxItems: 5
- name: min_balance
type: CONSTANT
description: Minimum account balance filter
sqlType: DOUBLE
required: false
defaultValue: 0
constraints:
min: 0
- name: group_by
type: COLUMN_REF
description: Column to group results by
parent: customers
required: true
- name: agg_func
type: FUNCTION_REF
description: Aggregation function for order totals
required: true
constraints:
allowedValues: ["SUM", "AVG", "COUNT"]
- name: limit_rows
type: CONSTANT
description: Maximum rows to return
sqlType: INTEGER
required: true
constraints:
min: 1
max: 1000
templateLogic: |
SELECT
{{ group_by }},
COUNT(*) as customer_count,
{{ agg_func }}(o.totalprice) as order_total
FROM {{ customers }} c
LEFT JOIN {{ orders }} o ON c.custkey = o.custkey
WHERE c.mktsegment IN ({{ segments }})
AND c.acctbal >= {{ min_balance }}
GROUP BY {{ group_by }}
ORDER BY order_total DESC
LIMIT {{ limit_rows }}
Example invocation by the AI agent:
{
"toolName": "customer_analysis",
"parametersJson": {
"segments": ["BUILDING", "AUTOMOBILE"],
"min_balance": 1000,
"group_by": "mktsegment",
"agg_func": "SUM",
"limit_rows": 10
}
}
Dynamic table analysis with subquery filter#
This example demonstrates TABLE_REF and QUERY with requiredColumns
constraints, COLUMN_REF validated against a dynamic TABLE_REF parent,
pattern constraints, and DATE parameters.
name: dynamic_sales_report
description: >
Generate a sales report from any table containing sales data.
Filters results using a custom subquery for flexible data selection.
The source table must have 'sale_date', 'amount', and 'region' columns.
parameters:
- name: source
type: TABLE_REF
description: >
Fully qualified table name (catalog.schema.table) containing sales data.
Must include columns: sale_date, amount, region.
required: true
constraints:
requiredColumns: ["sale_date", "amount", "region"]
- name: filter_query
type: QUERY
description: >
Subquery that returns region values to include in the report.
Must output a 'region' column.
required: true
constraints:
requiredColumns: ["region"]
- name: group_column
type: COLUMN_REF
description: Column from the source table to group results by
parent: source
required: true
- name: start_date
type: CONSTANT
description: Start date for the report period (YYYY-MM-DD)
sqlType: DATE
required: true
- name: end_date
type: CONSTANT
description: End date for the report period (YYYY-MM-DD)
sqlType: DATE
required: true
- name: region_pattern
type: CONSTANT
description: Regex pattern to filter region names (e.g., "AMERICA|EUROPE")
sqlType: VARCHAR
required: false
defaultValue: ".*"
constraints:
maxLength: 100
templateLogic: |
SELECT
{{ group_column }},
COUNT(*) as transaction_count,
SUM(amount) as total_sales,
AVG(amount) as avg_sale
FROM {{ source }}
WHERE sale_date BETWEEN {{ start_date }} AND {{ end_date }}
AND region IN {{ filter_query }}
AND regexp_like(region, {{ region_pattern }})
GROUP BY {{ group_column }}
ORDER BY total_sales DESC
Example invocation by the AI agent:
{
"toolName": "dynamic_sales_report",
"parametersJson": {
"source": "analytics.public.sales_transactions",
"filter_query": "SELECT DISTINCT region FROM analytics.public.active_regions WHERE is_active = true",
"group_column": "region",
"start_date": "2024-01-01",
"end_date": "2024-12-31",
"region_pattern": "AMERICA|EUROPE"
}
}
Rendered SQL output:
EXECUTE IMMEDIATE '
SELECT
"region",
COUNT(*) as transaction_count,
SUM(amount) as total_sales,
AVG(amount) as avg_sale
FROM "analytics"."public"."sales_transactions"
WHERE sale_date BETWEEN ? AND ?
AND region IN (SELECT DISTINCT region FROM analytics.public.active_regions WHERE is_active = true)
AND regexp_like(region, ?)
GROUP BY "region"
ORDER BY total_sales DESC
' USING DATE '2024-01-01', DATE '2024-12-31', 'AMERICA|EUROPE'
Data profiling with FUNCTION_REF signature constraints#
This uses a QUERY as a primary data source, COLUMN_REF validated against
dynamic query output, FUNCTION_REF with both allowedValues and signature
constraints, Pebble conditionals, and Pebble filters.
name: profile_column
description: >
Profile a numeric column from any query result. Computes statistical metrics
including count, null percentage, distinct values, and configurable aggregations.
Use this to understand data distribution before analysis.
parameters:
- name: data_query
type: QUERY
description: >
SQL query returning the data to profile. Must include a numeric column
to analyze. Example: SELECT amount, region FROM sales WHERE year = 2024
required: true
- name: profile_column
type: COLUMN_REF
description: The numeric column from data_query to compute statistics on
parent: data_query
required: true
- name: central_tendency_func
type: FUNCTION_REF
description: Function to measure central tendency (typical value)
required: true
constraints:
allowedValues: ["AVG", "APPROX_PERCENTILE"]
- name: dispersion_func
type: FUNCTION_REF
description: Function to measure data spread/dispersion
required: true
constraints:
allowedValues: ["STDDEV", "VARIANCE", "STDDEV_POP", "VAR_POP"]
functionType: scalar
- name: percentile_value
type: CONSTANT
description: Percentile to compute (0.0 to 1.0), used when central_tendency_func is APPROX_PERCENTILE
sqlType: DOUBLE
required: false
defaultValue: 0.5
constraints:
min: 0.0
max: 1.0
- name: sample_limit
type: CONSTANT
description: Maximum rows to sample for profiling (0 for no limit)
sqlType: INTEGER
required: false
defaultValue: 0
constraints:
min: 0
max: 10000000
templateLogic: |
WITH source_data AS (
{{ data_query }}
),
sampled_data AS (
SELECT * FROM source_data
{% if sample_limit > 0 %}LIMIT {{ sample_limit }}{% endif %}
),
base_stats AS (
SELECT
COUNT(*) as total_rows,
COUNT({{ profile_column }}) as non_null_count,
COUNT(*) - COUNT({{ profile_column }}) as null_count,
COUNT(DISTINCT {{ profile_column }}) as distinct_count,
MIN({{ profile_column }}) as min_value,
MAX({{ profile_column }}) as max_value,
{{ central_tendency_func }}(
{% if central_tendency_func == 'APPROX_PERCENTILE' %}
{{ profile_column }}, {{ percentile_value }}
{% else %}
{{ profile_column }}
{% endif %}
) as central_value,
{{ dispersion_func }}({{ profile_column }}) as dispersion_value
FROM sampled_data
)
SELECT
total_rows,
non_null_count,
null_count,
ROUND(100.0 * null_count / NULLIF(total_rows, 0), 2) as null_percentage,
distinct_count,
ROUND(100.0 * distinct_count / NULLIF(non_null_count, 0), 2) as uniqueness_percentage,
min_value,
max_value,
max_value - min_value as value_range,
central_value as {{ central_tendency_func | lower }}_value,
dispersion_value as {{ dispersion_func | lower }}_value
FROM base_stats
Example invocation by the AI agent:
{
"toolName": "profile_column",
"parametersJson": {
"data_query": "SELECT totalprice, orderstatus FROM tpch.tiny.orders WHERE orderdate >= DATE '2024-01-01'",
"profile_column": "totalprice",
"central_tendency_func": "AVG",
"dispersion_func": "STDDEV"
}
}
Customer profile analysis with STRUCT_LIST and Pebble macros#
This uses STRUCT_LIST with mixed field types (EXPRESSION, TABLE_REF,
COLUMN_REF, CONSTANT, CONSTANT_LIST), Pebble macros for reusable SQL
fragments, and optional STRUCT_LIST parameters with EXPRESSION and ALIAS
fields.
This example shows the full power of parameterized tools: the AI agent can define multiple population segments, each with its own source table, filter date, and segment values. The tool computes a standard set of demographic and behavioral metrics for each population, and any additional ad-hoc metrics the agent requests.
name: customer_profile_analysis
description: |
Analyzes customer profiles across user-defined population segments. Computes
standard demographic, channel engagement, product ownership, and financial
metrics for each population, plus any additional metrics requested by the user.
The LLM provides:
1. Population definitions via 'populations' - each defines a label expression,
source table, date column, filter date, and segment values. These are
combined with UNION ALL to form the base CTE.
2. Additional metrics via 'additional_metrics' - each defines an aggregate
SQL expression and column alias to append beyond the standard metric set.
parameters:
- name: populations
type: STRUCT_LIST
required: true
description: |
Population segments to analyze. Each population defines a labeled slice
of the customer profile data. Segments are combined with UNION ALL.
Example:
- label: "'Overall Consumer'"
source_table: catalog.schema.profile_table
date_col: xtrct_dt
date: "2025-12-31"
segment_list: ["1 retail", "2 preferred"]
constraints:
minItems: 1
fields:
- name: label
type: EXPRESSION
description: "Population label expression, e.g. 'Retail' or CASE WHEN type = 'C' THEN age_group ELSE 'N/A' END"
- name: source_table
type: TABLE_REF
description: Fully qualified profile table name (catalog.schema.table)
- name: date_col
type: COLUMN_REF
parent: source_table
description: Date column to filter on (e.g. xtrct_dt)
- name: date
type: CONSTANT
sqlType: DATE
description: Extract date to filter on (YYYY-MM-DD)
- name: segment_list
type: CONSTANT_LIST
sqlType: VARCHAR
description: "Segment values to include, e.g. '1 retail', '2 preferred'"
- name: additional_metrics
type: STRUCT_LIST
required: false
defaultValue: []
description: |
Additional aggregate metrics beyond the standard set. Each metric defines
an aggregate SQL expression and a column alias.
Example:
- expr: "AVG(CASE WHEN chk_fl = 1 THEN chk_bl_am END)"
alias: avg_checking_balance
fields:
- name: expr
type: EXPRESSION
description: "Aggregate SQL expression"
- name: alias
type: ALIAS
description: Column alias for the metric
templateLogic: |
{% macro pct(condition, alias) %}CAST(SUM(CASE WHEN {{ condition }} THEN 1 ELSE 0 END) AS DECIMAL(38,5)) / COUNT(pty_id) * 100.0 AS {{ alias }}{% endmacro %}
WITH base AS (
{% for pop in populations %}
SELECT {{ pop.label }} AS population, *
FROM {{ pop.source_table }}
WHERE CAST({{ pop.date_col }} AS DATE) = {{ pop.date }}
AND segment IN ({{ pop.segment_list }})
{% if not loop.last %}UNION ALL{% endif %}
{% endfor %}
)
SELECT
population,
CAST(xtrct_dt AS DATE) AS extract_date,
COUNT(pty_id) AS client_count,
AVG(tot_rev_3ma_am) AS avg_total_revenue,
{{ pct("dig_actv_in = 1", "pct_digital_active") }},
{{ pct("call_fl = 1", "pct_contact_center") }},
{{ pct("chk_fl = 1", "pct_checking") }},
{{ pct("dep_fl = 1", "pct_deposit") }},
{{ pct("sav_fl = 1", "pct_savings") }},
{{ pct("crcrd_fl = 1", "pct_credit_card") }}{% for m in additional_metrics %},
{{ m.expr }} AS {{ m.alias }}{% endfor %}
FROM base
GROUP BY population, CAST(xtrct_dt AS DATE)
ORDER BY population
Patterns that were demonstrated in the example file:
Pebble macro ({% macro pct %}): Defines a reusable SQL fragment that computes a percentage metric. The macro is invoked multiple times with different conditions and aliases, which avoids duplicating complex aggregate expressions.
STRUCT_LISTiteration: The {% for pop in populations %} loop emits one SELECT per population and combines them with UNION ALL. Each struct element supplies:a
TABLE_REFauto‑quoteda
COLUMN_REFvalidated against the siblingTABLE_REFa
CONSTANTbound as a single valuea
CONSTANT_LISTbound as multiple values
Optional
STRUCT_LISTwithdefaultValue: []: Theadditional_metricsparameter defaults to an empty list, so the standard metrics are always computed. When the AI agent provides additional metrics, they are appended withEXPRESSION, SQL-parser-validated, andALIASsafe identifier fields.EXPRESSIONfields: Used for both the population label, which can be a string literal or aCASEexpression, or for additional metric expressions, which can be any valid aggregate expression.
Example invocation by the AI agent:
{
"toolName": "customer_profile_analysis",
"parametersJson": {
"populations": [
{
"label": "'Overall Consumer'",
"source_table": "analytics.derived.customer_profile",
"date_col": "xtrct_dt",
"date": "2025-12-31",
"segment_list": ["1 retail", "2 preferred"]
},
{
"label": "'Retail Only'",
"source_table": "analytics.derived.customer_profile",
"date_col": "xtrct_dt",
"date": "2025-12-31",
"segment_list": ["1 retail"]
}
],
"additional_metrics": [
{
"expr": "AVG(CASE WHEN chk_fl = 1 THEN chk_bl_am END)",
"alias": "avg_checking_balance"
}
]
}
}