Dune is a blockchain data platform. Use these tools to find tables, write and run DuneSQL (Trino) queries, and turn the results into visualizations and dashboards.
1. Find real table names with searchTables, or searchTablesByContractAddress for a contract. Do not guess table names.
2. Write the SQL and run it with createAndExecuteQuery. Filter on the partition columns that searchTables returns, such as block_date, to reduce cost.
3. Keep the execution ID that a run returns and pass it to getExecutionResults for more rows or status. Do not look it up again.
4. After an execution error, fix the SQL with updateDuneQuery, then rerun it with executeQueryById.
Executions use credits; getUsage shows the balance. Use searchDocs for DuneSQL syntax and functions. Give the user the query link https://dune.com/queries/{query_id}.
This Dune account is read-only. It cannot run queries or create or change content, so createAndExecuteQuery, executeQueryById, createDuneQuery and the other write tools fail with "Your account is read-only". Search and read tools, such as searchTables, getDuneQuery and getDashboard, still work.
Before you write SQL or call a tool that runs a query, tell the user that the account is read-only and that they can upgrade at https://dune.com/settings/teams/manage/mewwts/subscription. Do not retry a call that failed because the account is read-only.
Discoverability
0/6 passed0 of 6 passed0/100
Client listings and public setup information.
mcp.json or server-card.json
Either mcp.json or an MCP Server Card declaring this endpoint passes.
How to fix: For ChatGPT submission, set one exact HTTPS origin such as "https://app.example.com" on every view via _meta.ui.domain (or openai/widgetDomain). Paths are not valid and all views in one app must share the origin.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Record whether the help provided through this server's tools actually worked for the user. Call this when the user reacts to a result from this server, positively ("thanks, that's it", "perfect") or negatively ("that's wrong", "not what I asked", "this didn't work"), or when the user explicitly asks to give feedback. After you finish a multi-step task that relied on this server's tools, you may ask the user once, briefly, whether the result was helpful, and call this with their answer. Do not ask if they already indicated it, and never more than once per task. Report only what the user actually expressed; do not infer a rating from your own judgment of the result. Set helpful to whether it helped, and set reason when it did not. Submitting sends only those fields. No conversation content is sent. This is never required for the task to succeed.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Input documentation gives an agent enough context to populate the arguments.
helpful
Whether the result actually helped the user. True only when the user indicated it helped; false when they indicated it did not.
Clear enough to supply this argument.
reason
Why it did not help, when the user indicated a reason. Omit when they did not say.
Clear enough to supply this argument.
tools
Names of this server's tools the feedback is about, if the user named any.
Clear enough to supply this argument.
solicited
True when you asked the user whether it helped; false when they volunteered the reaction.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "submit_feedback",
"title": "Submit feedback on this server",
"description": "Record whether the help provided through this server's tools actually worked for the user. Call this when the user reacts to a result from this server, positively (\"thanks, that's it\", \"perfect\") or negatively (\"that's wrong\", \"not what I asked\", \"this didn't work\"), or when the user explicitly asks to give feedback. After you finish a multi-step task that relied on this server's tools, you may ask the user once, briefly, whether the result was helpful, and call this with their answer. Do not ask if they already indicated it, and never more than once per task. Report only what the user actually expressed; do not infer a rating from your own judgment of the result. Set helpful to whether it helped, and set reason when it did not. Submitting sends only those fields. No conversation content is sent. This is never required for the task to succeed.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"helpful"
],
"properties": {
"tools": {
"type": "array",
"items": {
"type": "string"
},
"maxItems": 8,
"description": "Names of this server's tools the feedback is about, if the user named any."
},
"reason": {
"enum": [
"wrong_result",
"incomplete",
"too_slow",
"wrong_tool",
"missing_capability",
"other"
],
"type": "string",
"description": "Why it did not help, when the user indicated a reason. Omit when they did not say."
},
"helpful": {
"type": "boolean",
"description": "Whether the result actually helped the user. True only when the user indicated it helped; false when they indicated it did not."
},
"solicited": {
"type": "boolean",
"description": "True when you asked the user whether it helped; false when they volunteered the reaction."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description85/100
Natural-language query of the Dune docs at docs.dune.com. Calls the remote docs MCP search tool.
What this tool is for:
- Grounding answers in first-party Dune documentation.
- Looking up Dune-specific details on tables, datasets, SQL behavior, and API semantics.
- Pulling examples and canonical wording before composing queries or tool calls.
Usage tips:
- Start broad with query, then narrow using apiReferenceOnly or codeOnly.
- Pair with searchTables to move from concept to docs to table selection.
The description explains the capability, when to use it, and what to expect.
Inputs90/100
Input documentation gives an agent enough context to populate the arguments.
query
Natural-language query of the Dune docs. Example: 'decoded tables meaning', 'query pagination'.
Clear enough to supply this argument.
apiReferenceOnly
If true, prioritize API reference pages over conceptual guides.
Clear enough to supply this argument.
codeOnly
If true, prioritize pages with executable examples and snippets.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description91/100
Natural-language table discovery across the Dune catalog. Required first step before writing, running, or executing any DuneSQL query — maps user intent into concrete table names so queries reference real tables instead of guessed names.
This is the best first tool when the user asks:
- What table should I use for X?
- Find me datasets for protocol Y.
- Show me tables for chain Z or topic T.
When to call this tool:
- Useful when you want to check Dune-specific details on tables and datasets.
- Useful when you need to move from vague intent to concrete table names.
- Useful when you need to find uploaded tables or transformation outputs.
Avoid this tool when:
- You already have a specific contract address and want decoded tables tied to it. Use searchTablesByContractAddress.
Fast usage patterns:
- Broad discovery: { "query": "uniswap volume", "limit": 20 }
- Curated-first: { "query": "dex swaps", "categories": ["spell"], "limit": 10 }
- Chain-constrained: { "query": "bridge transfers", "categories": ["decoded"], "blockchains": ["ethereum", "arbitrum"] }
- Uploaded tables: { "query": "*", "categories": ["community"], "datasetTypes": ["uploaded_table"] }
- Transformations: { "query": "retention cohort", "datasetTypes": ["transformation_table", "transformation_view"] }
- My private tables: { "query": "*" } - results include both public and private; use the "visibility" field in each result to distinguish them
Category semantics:
- canonical: base chain tables (transactions, blocks, logs, traces)
- decoded: ABI-decoded contract tables (events/calls)
- spell: curated Spellbook tables
- community: public community/uploaded tables
The description explains the capability, when to use it, and what to expect.
Inputs96/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
query
Natural-language intent or entity hints. Use protocol names, event/function names, or dataset intent. Example: 'uniswap v3 swaps'. Use '*' to browse without keyword bias.
Clear enough to supply this argument.
categories
Precision filter for table families. Use ['spell'] for curated datasets; ['decoded'] for ABI-level events/calls; ['canonical'] for chain primitives; ['community'] for user-contributed datasets.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
datasetTypes
Fine-grained dataset type filter. Values: dune_table (raw chain tables such as transactions and logs), decoded_table (ABI-decoded contract events and calls), spell (curated Spellbook tables), uploaded_table (CSV or API uploads by users), transformation_table and transformation_view (tables and views that users build with SQL transformations). Omit to search all types.
Clear enough to supply this argument.
blockchains
Chain scope to reduce ambiguity and improve ranking. Example: ['ethereum'], ['solana'].
Clear enough to supply this argument.
schemas
Schema/namespace constraint for high precision. Example: ['dex'], ['uniswap_v3_ethereum'].
Clear enough to supply this argument.
limit
Number of results per page. Use 5-15 for fast checks, 20-50 for deeper exploration.
Clear enough to supply this argument.
offset
Pagination offset. Use previous response pagination.nextOffset for next page.
Clear enough to supply this argument.
includeSchema
If true, include the column-level schema (name, type, nullable) for every result. Enable when preparing SQL generation.
Clear enough to supply this argument.
includeMetadata
If true, each result gains a metadata object with category-specific fields:
- All categories: page_rank_score (popularity signal, higher = more used), description (human-written summary).
- decoded tables: abi_type ("event" | "call"), contract_name (e.g. "UniswapV3Pool"), project_name (e.g. "uniswap_v3").
- spell tables: spell_type ("sector" | "project"), spell_metadata { depends_on: string[], tags: string[], description: string, columns: { column, name, description }[] }.
- uploaded/materialized_view: visibility ("private" | "public") is always included regardless of this flag.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"total",
"results",
"pagination"
],
"properties": {
"total": {
"type": "number",
"description": "Total number of matching tables across all pages."
},
"results": {
"type": "array",
"items": {
"type": "object",
"required": [
"full_name",
"category"
],
"properties": {
"schema": {
"type": "object",
"description": "Column-level schema keyed by column name when includeSchema=true. Use this to understand available fields before writing SQL.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"category": {
"enum": [
"canonical",
"decoded",
"spell",
"community"
],
"type": "string",
"description": "Top-level table family: canonical, decoded, spell, or community."
},
"metadata": {
"type": "object",
"properties": {
"abi_type": {
"enum": [
"event",
"call"
],
"type": "string",
"description": "Decoded-table subtype when available, typically \"event\" or \"call\"."
},
"spell_type": {
"enum": [
"sector",
"project"
],
"type": "string",
"description": "Spellbook subtype when available, typically \"sector\" or \"project\"."
},
"description": {
"type": "string",
"description": "Human-written summary of the dataset when available."
},
"project_name": {
"type": "string",
"description": "Protocol or project name associated with a decoded table when available."
},
"contract_name": {
"type": "string",
"description": "Contract name associated with a decoded table when available."
},
"spell_metadata": {
"type": "object",
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"columns": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"name"
],
"properties": {
"name": {
"type": "string"
},
"column": {
"type": "string"
},
"description": {
"type": "string"
}
},
"additionalProperties": false
}
},
"depends_on": {
"type": "array",
"items": {
"type": "string"
}
},
"description": {
"type": "string"
},
"partition_by": {
"type": "array",
"items": {
"type": "string"
}
}
},
"description": "Additional Spellbook metadata when available, such as dependencies, tags, descriptions, or documented columns.",
"additionalProperties": false
},
"page_rank_score": {
"type": "number",
"description": "Popularity or usage signal for ranking. Higher values generally indicate more commonly used tables."
}
},
"description": "Optional category-specific metadata returned when includeMetadata=true.",
"additionalProperties": false
},
"full_name": {
"type": "string",
"description": "Fully qualified table name to use in SQL, such as schema.table or namespace.table."
},
"visibility": {
"enum": [
"public",
"private"
],
"type": "string",
"description": "Visibility for datasets where it applies, especially uploaded or private tables."
},
"blockchains": {
"type": "array",
"items": {
"type": "string"
},
"description": "Blockchains associated with the dataset when the catalog has that mapping."
},
"description": {
"type": "string",
"description": "Short human-readable dataset summary when available."
},
"dataset_type": {
"enum": [
"dune_table",
"decoded_table",
"spell",
"uploaded_table",
"transformation_table",
"transformation_view"
],
"type": "string",
"description": "Fine-grained dataset classification such as dune_table, decoded_table, spell, uploaded_table, transformation_table, or transformation_view."
},
"partition_columns": {
"type": "array",
"items": {
"type": "string"
},
"description": "Columns the table is partitioned by (e.g. ['block_date']). When writing SQL against this table, always include a WHERE filter on these columns to enable partition pruning and reduce query cost."
}
},
"additionalProperties": false
},
"description": "Matching catalog entries ordered by the search backend relevance."
},
"pagination": {
"type": "object",
"required": [
"limit",
"offset",
"nextOffset",
"hasMore"
],
"properties": {
"limit": {
"type": "number",
"description": "The page size used for this response."
},
"offset": {
"type": "number",
"description": "The starting offset used for this response."
},
"hasMore": {
"type": "boolean",
"description": "Whether additional results are available beyond this page."
},
"nextOffset": {
"type": [
"number",
"null"
],
"description": "Offset to request the next page, or null when there are no more results."
}
},
"description": "Pagination state for continuing through additional result pages.",
"additionalProperties": false
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "searchTables",
"title": "Search Tables",
"description": "Natural-language table discovery across the Dune catalog. Required first step before writing, running, or executing any DuneSQL query — maps user intent into concrete table names so queries reference real tables instead of guessed names.\n\nThis is the best first tool when the user asks:\n- What table should I use for X?\n- Find me datasets for protocol Y.\n- Show me tables for chain Z or topic T.\n\nWhen to call this tool:\n- Useful when you want to check Dune-specific details on tables and datasets.\n- Useful when you need to move from vague intent to concrete table names.\n- Useful when you need to find uploaded tables or transformation outputs.\n\nAvoid this tool when:\n- You already have a specific contract address and want decoded tables tied to it. Use searchTablesByContractAddress.\n\nFast usage patterns:\n- Broad discovery: { \"query\": \"uniswap volume\", \"limit\": 20 }\n- Curated-first: { \"query\": \"dex swaps\", \"categories\": [\"spell\"], \"limit\": 10 }\n- Chain-constrained: { \"query\": \"bridge transfers\", \"categories\": [\"decoded\"], \"blockchains\": [\"ethereum\", \"arbitrum\"] }\n- Uploaded tables: { \"query\": \"*\", \"categories\": [\"community\"], \"datasetTypes\": [\"uploaded_table\"] }\n- Transformations: { \"query\": \"retention cohort\", \"datasetTypes\": [\"transformation_table\", \"transformation_view\"] }\n- My private tables: { \"query\": \"*\" } - results include both public and private; use the \"visibility\" field in each result to distinguish them\n\nCategory semantics:\n- canonical: base chain tables (transactions, blocks, logs, traces)\n- decoded: ABI-decoded contract tables (events/calls)\n- spell: curated Spellbook tables\n- community: public community/uploaded tables\n",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"limit": {
"type": "number",
"description": "Number of results per page. Use 5-15 for fast checks, 20-50 for deeper exploration."
},
"query": {
"type": "string",
"description": "Natural-language intent or entity hints. Use protocol names, event/function names, or dataset intent. Example: 'uniswap v3 swaps'. Use '*' to browse without keyword bias."
},
"offset": {
"type": "number",
"description": "Pagination offset. Use previous response pagination.nextOffset for next page."
},
"schemas": {
"type": "array",
"items": {
"type": "string"
},
"description": "Schema/namespace constraint for high precision. Example: ['dex'], ['uniswap_v3_ethereum']."
},
"categories": {
"type": "array",
"items": {
"enum": [
"canonical",
"decoded",
"spell",
"community"
],
"type": "string"
},
"description": "Precision filter for table families. Use ['spell'] for curated datasets; ['decoded'] for ABI-level events/calls; ['canonical'] for chain primitives; ['community'] for user-contributed datasets."
},
"blockchains": {
"type": "array",
"items": {
"type": "string"
},
"description": "Chain scope to reduce ambiguity and improve ranking. Example: ['ethereum'], ['solana']."
},
"datasetTypes": {
"type": "array",
"items": {
"enum": [
"dune_table",
"decoded_table",
"spell",
"uploaded_table",
"transformation_table",
"transformation_view"
],
"type": "string"
},
"description": "Fine-grained dataset type filter. Values: dune_table (raw chain tables such as transactions and logs), decoded_table (ABI-decoded contract events and calls), spell (curated Spellbook tables), uploaded_table (CSV or API uploads by users), transformation_table and transformation_view (tables and views that users build with SQL transformations). Omit to search all types."
},
"includeSchema": {
"type": "boolean",
"description": "If true, include the column-level schema (name, type, nullable) for every result. Enable when preparing SQL generation."
},
"includeMetadata": {
"type": "boolean",
"description": "If true, each result gains a metadata object with category-specific fields:\n- All categories: page_rank_score (popularity signal, higher = more used), description (human-written summary).\n- decoded tables: abi_type (\"event\" | \"call\"), contract_name (e.g. \"UniswapV3Pool\"), project_name (e.g. \"uniswap_v3\").\n- spell tables: spell_type (\"sector\" | \"project\"), spell_metadata { depends_on: string[], tags: string[], description: string, columns: { column, name, description }[] }.\n- uploaded/materialized_view: visibility (\"private\" | \"public\") is always included regardless of this flag."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"total",
"results",
"pagination"
],
"properties": {
"total": {
"type": "number",
"description": "Total number of matching tables across all pages."
},
"results": {
"type": "array",
"items": {
"type": "object",
"required": [
"full_name",
"category"
],
"properties": {
"schema": {
"type": "object",
"description": "Column-level schema keyed by column name when includeSchema=true. Use this to understand available fields before writing SQL.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"category": {
"enum": [
"canonical",
"decoded",
"spell",
"community"
],
"type": "string",
"description": "Top-level table family: canonical, decoded, spell, or community."
},
"metadata": {
"type": "object",
"properties": {
"abi_type": {
"enum": [
"event",
"call"
],
"type": "string",
"description": "Decoded-table subtype when available, typically \"event\" or \"call\"."
},
"spell_type": {
"enum": [
"sector",
"project"
],
"type": "string",
"description": "Spellbook subtype when available, typically \"sector\" or \"project\"."
},
"description": {
"type": "string",
"description": "Human-written summary of the dataset when available."
},
"project_name": {
"type": "string",
"description": "Protocol or project name associated with a decoded table when available."
},
"contract_name": {
"type": "string",
"description": "Contract name associated with a decoded table when available."
},
"spell_metadata": {
"type": "object",
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"columns": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"name"
],
"properties": {
"name": {
"type": "string"
},
"column": {
"type": "string"
},
"description": {
"type": "string"
}
},
"additionalProperties": false
}
},
"depends_on": {
"type": "array",
"items": {
"type": "string"
}
},
"description": {
"type": "string"
},
"partition_by": {
"type": "array",
"items": {
"type": "string"
}
}
},
"description": "Additional Spellbook metadata when available, such as dependencies, tags, descriptions, or documented columns.",
"additionalProperties": false
},
"page_rank_score": {
"type": "number",
"description": "Popularity or usage signal for ranking. Higher values generally indicate more commonly used tables."
}
},
"description": "Optional category-specific metadata returned when includeMetadata=true.",
"additionalProperties": false
},
"full_name": {
"type": "string",
"description": "Fully qualified table name to use in SQL, such as schema.table or namespace.table."
},
"visibility": {
"enum": [
"public",
"private"
],
"type": "string",
"description": "Visibility for datasets where it applies, especially uploaded or private tables."
},
"blockchains": {
"type": "array",
"items": {
"type": "string"
},
"description": "Blockchains associated with the dataset when the catalog has that mapping."
},
"description": {
"type": "string",
"description": "Short human-readable dataset summary when available."
},
"dataset_type": {
"enum": [
"dune_table",
"decoded_table",
"spell",
"uploaded_table",
"transformation_table",
"transformation_view"
],
"type": "string",
"description": "Fine-grained dataset classification such as dune_table, decoded_table, spell, uploaded_table, transformation_table, or transformation_view."
},
"partition_columns": {
"type": "array",
"items": {
"type": "string"
},
"description": "Columns the table is partitioned by (e.g. ['block_date']). When writing SQL against this table, always include a WHERE filter on these columns to enable partition pruning and reduce query cost."
}
},
"additionalProperties": false
},
"description": "Matching catalog entries ordered by the search backend relevance."
},
"pagination": {
"type": "object",
"required": [
"limit",
"offset",
"nextOffset",
"hasMore"
],
"properties": {
"limit": {
"type": "number",
"description": "The page size used for this response."
},
"offset": {
"type": "number",
"description": "The starting offset used for this response."
},
"hasMore": {
"type": "boolean",
"description": "Whether additional results are available beyond this page."
},
"nextOffset": {
"type": [
"number",
"null"
],
"description": "Offset to request the next page, or null when there are no more results."
}
},
"description": "Pagination state for continuing through additional result pages.",
"additionalProperties": false
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description89/100
List indexed blockchain values with table counts, optionally filtered by category/query.
Best use cases:
- Before calling searchTables when chain names are uncertain.
- To detect multi-chain coverage for a topic/category.
- To decide whether a query plan should be cross-chain or chain-specific.
Typical flow:
- Step 1: call listBlockchains with categories and optional query.
- Step 2: pass selected chains into searchTables blockchains parameter.
Parameters:
- categories: Optional category pre-filter (canonical, decoded, spell, community).
- query: Optional semantic pre-filter before faceting. Use '*' for global counts.
- limit: Maximum number of blockchain values returned (default 200).
- offset: Offset for pagination.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
categories
Category pre-filter. Example: ['decoded'] to list chains with decoded coverage.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
query
Semantic pre-filter before faceting. Example: 'lending', 'nft'. Use '*' for global counts.
Clear enough to supply this argument.
limit
Maximum number of blockchains to return. When omitted, returns up to 200.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
offset
Number of blockchains to skip, for the next page. Use pagination.nextOffset from the previous response. Defaults to 0.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"total",
"results",
"pagination"
],
"properties": {
"total": {
"type": "number",
"description": "Number of blockchains that match the filters."
},
"results": {
"type": "array",
"items": {
"type": "object",
"required": [
"blockchain",
"table_count"
],
"properties": {
"blockchain": {
"type": "string",
"description": "Blockchain name to pass to searchTables blockchains, e.g. 'ethereum'."
},
"table_count": {
"type": "number",
"description": "Number of tables for this blockchain that match the filters."
}
},
"additionalProperties": false
}
},
"pagination": {
"type": "object",
"required": [
"limit",
"offset",
"nextOffset",
"hasMore"
],
"properties": {
"limit": {
"type": "number"
},
"offset": {
"type": "number"
},
"hasMore": {
"type": "boolean",
"description": "Whether more blockchains follow."
},
"nextOffset": {
"type": [
"number",
"null"
],
"description": "Offset for the next page, or null on the last page."
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "listBlockchains",
"title": "List Blockchains",
"description": "List indexed blockchain values with table counts, optionally filtered by category/query.\n\nBest use cases:\n- Before calling searchTables when chain names are uncertain.\n- To detect multi-chain coverage for a topic/category.\n- To decide whether a query plan should be cross-chain or chain-specific.\n\nTypical flow:\n- Step 1: call listBlockchains with categories and optional query.\n- Step 2: pass selected chains into searchTables blockchains parameter.\n\nParameters:\n- categories: Optional category pre-filter (canonical, decoded, spell, community).\n- query: Optional semantic pre-filter before faceting. Use '*' for global counts.\n- limit: Maximum number of blockchain values returned (default 200).\n- offset: Offset for pagination.\n",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"limit": {
"type": "number",
"description": "Maximum number of blockchains to return. When omitted, returns up to 200."
},
"query": {
"type": "string",
"description": "Semantic pre-filter before faceting. Example: 'lending', 'nft'. Use '*' for global counts."
},
"offset": {
"type": "number",
"description": "Number of blockchains to skip, for the next page. Use pagination.nextOffset from the previous response. Defaults to 0."
},
"categories": {
"type": "array",
"items": {
"enum": [
"canonical",
"decoded",
"spell",
"community"
],
"type": "string"
},
"description": "Category pre-filter. Example: ['decoded'] to list chains with decoded coverage."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"total",
"results",
"pagination"
],
"properties": {
"total": {
"type": "number",
"description": "Number of blockchains that match the filters."
},
"results": {
"type": "array",
"items": {
"type": "object",
"required": [
"blockchain",
"table_count"
],
"properties": {
"blockchain": {
"type": "string",
"description": "Blockchain name to pass to searchTables blockchains, e.g. 'ethereum'."
},
"table_count": {
"type": "number",
"description": "Number of tables for this blockchain that match the filters."
}
},
"additionalProperties": false
}
},
"pagination": {
"type": "object",
"required": [
"limit",
"offset",
"nextOffset",
"hasMore"
],
"properties": {
"limit": {
"type": "number"
},
"offset": {
"type": "number"
},
"hasMore": {
"type": "boolean",
"description": "Whether more blockchains follow."
},
"nextOffset": {
"type": [
"number",
"null"
],
"description": "Offset for the next page, or null on the last page."
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description92/100
Search for decoded tables associated with a specific contract address.
This tool finds all available decoded tables (events and calls) for a given smart contract address.
When to use this tool:
- You have a specific contract address (EVM or Tron) and want to find its decoded tables.
- You want to analyze on-chain activity for a particular smart contract.
- You need to find event or call tables for a known contract.
Avoid this tool when:
- You want to search tables by project name or keyword across categories. Use searchTables instead.
- You want broader table discovery across multiple categories. Use searchTables instead.
Decoded tables contain blockchain data that has been parsed according to a contract's ABI. They make it easier to analyze on-chain activity by providing a structured view of contract interactions.
Fast usage patterns:
- Find all tables for a contract: { "contractAddress": "0x..." }
- Filter by blockchain: { "contractAddress": "0x...", "blockchains": ["ethereum"] }
- Get schema for SQL: { "contractAddress": "0x...", "includeSchema": true }
- Pagination: { "contractAddress": "0x...", "limit": 20, "offset": 20 }
Table types:
- Event tables: contain parsed event logs emitted by smart contracts
- Call tables: contain parsed function calls made to smart contracts
The description explains the capability, when to use it, and what to expect.
Inputs91/100
Input documentation gives an agent enough context to populate the arguments.
contractAddress
The contract address to search for. Accepts EVM addresses (starting with 0x) or Tron addresses. Example: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984'.
Clear enough to supply this argument.
blockchains
Filter results to specific blockchains. Example: ['ethereum', 'arbitrum']. If not provided, searches across all blockchains where the contract exists.
Clear enough to supply this argument.
limit
Maximum number of results to return. Defaults to 20. Use smaller values (5-10) for quick checks, larger values (50-100) for comprehensive discovery.
Clear enough to supply this argument.
offset
Number of results to skip for pagination. Defaults to 0. Use for paginating through large result sets.
Clear enough to supply this argument.
includeSchema
If true, include the column-level schema (name, type, nullable) for every result. Enable when preparing SQL generation. Defaults to false.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"total",
"results",
"pagination"
],
"properties": {
"total": {
"type": "number"
},
"results": {
"type": "array",
"items": {
"type": "object",
"required": [
"full_name",
"category"
],
"properties": {
"schema": {
"type": "object",
"description": "Column-level schema keyed by column name when includeSchema=true. Use this to understand available fields before writing SQL.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"category": {
"enum": [
"canonical",
"decoded",
"spell",
"community"
],
"type": "string",
"description": "Top-level table family: canonical, decoded, spell, or community."
},
"metadata": {
"type": "object",
"properties": {
"abi_type": {
"enum": [
"event",
"call"
],
"type": "string",
"description": "Decoded-table subtype when available, typically \"event\" or \"call\"."
},
"spell_type": {
"enum": [
"sector",
"project"
],
"type": "string",
"description": "Spellbook subtype when available, typically \"sector\" or \"project\"."
},
"description": {
"type": "string",
"description": "Human-written summary of the dataset when available."
},
"project_name": {
"type": "string",
"description": "Protocol or project name associated with a decoded table when available."
},
"contract_name": {
"type": "string",
"description": "Contract name associated with a decoded table when available."
},
"spell_metadata": {
"type": "object",
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"columns": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"name"
],
"properties": {
"name": {
"type": "string"
},
"column": {
"type": "string"
},
"description": {
"type": "string"
}
},
"additionalProperties": false
}
},
"depends_on": {
"type": "array",
"items": {
"type": "string"
}
},
"description": {
"type": "string"
},
"partition_by": {
"type": "array",
"items": {
"type": "string"
}
}
},
"description": "Additional Spellbook metadata when available, such as dependencies, tags, descriptions, or documented columns.",
"additionalProperties": false
},
"page_rank_score": {
"type": "number",
"description": "Popularity or usage signal for ranking. Higher values generally indicate more commonly used tables."
}
},
"description": "Optional category-specific metadata returned when includeMetadata=true.",
"additionalProperties": false
},
"full_name": {
"type": "string",
"description": "Fully qualified table name to use in SQL, such as schema.table or namespace.table."
},
"visibility": {
"enum": [
"public",
"private"
],
"type": "string",
"description": "Visibility for datasets where it applies, especially uploaded or private tables."
},
"blockchains": {
"type": "array",
"items": {
"type": "string"
},
"description": "Blockchains associated with the dataset when the catalog has that mapping."
},
"description": {
"type": "string",
"description": "Short human-readable dataset summary when available."
},
"dataset_type": {
"enum": [
"dune_table",
"decoded_table",
"spell",
"uploaded_table",
"transformation_table",
"transformation_view"
],
"type": "string",
"description": "Fine-grained dataset classification such as dune_table, decoded_table, spell, uploaded_table, transformation_table, or transformation_view."
},
"partition_columns": {
"type": "array",
"items": {
"type": "string"
},
"description": "Columns the table is partitioned by (e.g. ['block_date']). When writing SQL against this table, always include a WHERE filter on these columns to enable partition pruning and reduce query cost."
}
},
"additionalProperties": false
}
},
"pagination": {
"type": "object",
"required": [
"limit",
"offset",
"nextOffset",
"hasMore"
],
"properties": {
"limit": {
"type": "number",
"description": "The page size used for this response."
},
"offset": {
"type": "number",
"description": "The starting offset used for this response."
},
"hasMore": {
"type": "boolean",
"description": "Whether additional results are available beyond this page."
},
"nextOffset": {
"type": [
"number",
"null"
],
"description": "Offset to request the next page, or null when there are no more results."
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "searchTablesByContractAddress",
"title": "Search Tables by Contract Address",
"description": "Search for decoded tables associated with a specific contract address.\n\nThis tool finds all available decoded tables (events and calls) for a given smart contract address.\n\nWhen to use this tool:\n- You have a specific contract address (EVM or Tron) and want to find its decoded tables.\n- You want to analyze on-chain activity for a particular smart contract.\n- You need to find event or call tables for a known contract.\n\nAvoid this tool when:\n- You want to search tables by project name or keyword across categories. Use searchTables instead.\n- You want broader table discovery across multiple categories. Use searchTables instead.\n\nDecoded tables contain blockchain data that has been parsed according to a contract's ABI. They make it easier to analyze on-chain activity by providing a structured view of contract interactions.\n\nFast usage patterns:\n- Find all tables for a contract: { \"contractAddress\": \"0x...\" }\n- Filter by blockchain: { \"contractAddress\": \"0x...\", \"blockchains\": [\"ethereum\"] }\n- Get schema for SQL: { \"contractAddress\": \"0x...\", \"includeSchema\": true }\n- Pagination: { \"contractAddress\": \"0x...\", \"limit\": 20, \"offset\": 20 }\n\nTable types:\n- Event tables: contain parsed event logs emitted by smart contracts\n- Call tables: contain parsed function calls made to smart contracts\n",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"contractAddress"
],
"properties": {
"limit": {
"type": "number",
"description": "Maximum number of results to return. Defaults to 20. Use smaller values (5-10) for quick checks, larger values (50-100) for comprehensive discovery."
},
"offset": {
"type": "number",
"description": "Number of results to skip for pagination. Defaults to 0. Use for paginating through large result sets."
},
"blockchains": {
"type": "array",
"items": {
"type": "string"
},
"description": "Filter results to specific blockchains. Example: ['ethereum', 'arbitrum']. If not provided, searches across all blockchains where the contract exists."
},
"includeSchema": {
"type": "boolean",
"description": "If true, include the column-level schema (name, type, nullable) for every result. Enable when preparing SQL generation. Defaults to false."
},
"contractAddress": {
"type": "string",
"description": "The contract address to search for. Accepts EVM addresses (starting with 0x) or Tron addresses. Example: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984'."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"total",
"results",
"pagination"
],
"properties": {
"total": {
"type": "number"
},
"results": {
"type": "array",
"items": {
"type": "object",
"required": [
"full_name",
"category"
],
"properties": {
"schema": {
"type": "object",
"description": "Column-level schema keyed by column name when includeSchema=true. Use this to understand available fields before writing SQL.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"category": {
"enum": [
"canonical",
"decoded",
"spell",
"community"
],
"type": "string",
"description": "Top-level table family: canonical, decoded, spell, or community."
},
"metadata": {
"type": "object",
"properties": {
"abi_type": {
"enum": [
"event",
"call"
],
"type": "string",
"description": "Decoded-table subtype when available, typically \"event\" or \"call\"."
},
"spell_type": {
"enum": [
"sector",
"project"
],
"type": "string",
"description": "Spellbook subtype when available, typically \"sector\" or \"project\"."
},
"description": {
"type": "string",
"description": "Human-written summary of the dataset when available."
},
"project_name": {
"type": "string",
"description": "Protocol or project name associated with a decoded table when available."
},
"contract_name": {
"type": "string",
"description": "Contract name associated with a decoded table when available."
},
"spell_metadata": {
"type": "object",
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"columns": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"name"
],
"properties": {
"name": {
"type": "string"
},
"column": {
"type": "string"
},
"description": {
"type": "string"
}
},
"additionalProperties": false
}
},
"depends_on": {
"type": "array",
"items": {
"type": "string"
}
},
"description": {
"type": "string"
},
"partition_by": {
"type": "array",
"items": {
"type": "string"
}
}
},
"description": "Additional Spellbook metadata when available, such as dependencies, tags, descriptions, or documented columns.",
"additionalProperties": false
},
"page_rank_score": {
"type": "number",
"description": "Popularity or usage signal for ranking. Higher values generally indicate more commonly used tables."
}
},
"description": "Optional category-specific metadata returned when includeMetadata=true.",
"additionalProperties": false
},
"full_name": {
"type": "string",
"description": "Fully qualified table name to use in SQL, such as schema.table or namespace.table."
},
"visibility": {
"enum": [
"public",
"private"
],
"type": "string",
"description": "Visibility for datasets where it applies, especially uploaded or private tables."
},
"blockchains": {
"type": "array",
"items": {
"type": "string"
},
"description": "Blockchains associated with the dataset when the catalog has that mapping."
},
"description": {
"type": "string",
"description": "Short human-readable dataset summary when available."
},
"dataset_type": {
"enum": [
"dune_table",
"decoded_table",
"spell",
"uploaded_table",
"transformation_table",
"transformation_view"
],
"type": "string",
"description": "Fine-grained dataset classification such as dune_table, decoded_table, spell, uploaded_table, transformation_table, or transformation_view."
},
"partition_columns": {
"type": "array",
"items": {
"type": "string"
},
"description": "Columns the table is partitioned by (e.g. ['block_date']). When writing SQL against this table, always include a WHERE filter on these columns to enable partition pruning and reduce query cost."
}
},
"additionalProperties": false
}
},
"pagination": {
"type": "object",
"required": [
"limit",
"offset",
"nextOffset",
"hasMore"
],
"properties": {
"limit": {
"type": "number",
"description": "The page size used for this response."
},
"offset": {
"type": "number",
"description": "The starting offset used for this response."
},
"hasMore": {
"type": "boolean",
"description": "Whether additional results are available beyond this page."
},
"nextOffset": {
"type": [
"number",
"null"
],
"description": "Offset to request the next page, or null when there are no more results."
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Create a new Dune query. Returns the query ID on success.
For brand-new analysis where the user wants the query executed, rows returned, or a visualization created, prefer createAndExecuteQuery instead. Use createDuneQuery directly when the user only wants to save SQL without running it.
Use this tool when the user wants to:
- Create a new SQL query on Dune
- Save a query they've been working on
**Important**: If the query targets tables with known partition columns (returned by searchTables or searchTablesByContractAddress), ensure the SQL includes a WHERE filter on those partition columns (e.g. `WHERE block_date >= CURRENT_DATE - INTERVAL '7' DAY`). This enables partition pruning and significantly reduces query cost.
To save into a folder, use **folder_id** (after listDuneFolders, especially when the user names a parent path) or **folder_name** when the name is unique. If several folders share the same name, createDuneQuery returns **folder_ambiguous** with paths and ids—retry with **folder_id** or list with **parent_path** first. Do not pass both folder_id and folder_name.
Ownership is automatically derived from the authenticated API key's customer context.
The description explains the capability, when to use it, and what to expect.
Inputs89/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
name
Human-readable query title. Max 600 characters. Example: 'Daily DEX Volume on Ethereum'
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
folder_id
Optional folder ID to save the query into. Must belong to the authenticated user/team. Use listDuneFolders to discover ids, or use folder_name instead.
Clear enough to supply this argument.
folder_name
Optional folder display name for this user/team (case-insensitive exact match on the folder basename). If multiple folders share this name, the tool errors with folder_ambiguous and lists paths and folder_ids—then pass folder_id or use listDuneFolders(parent_path). Do not set together with folder_id.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
query
The SQL query text in DuneSQL dialect. Max 500,000 characters.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
description
Short description of what the query does. Max 1,000 characters.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
is_private
Whether the query should be private. Defaults to false. May be forced to true by team privacy settings.
Clear enough to supply this argument.
is_temp
Whether the query should be temporary. Defaults to true for MCP-created queries. Temporary queries can be executed and they can have visualizations attached to them but they will not appear on the dune.com library and will not be accessible when shared with others. Set this to false if you intend to create a materialized view from this query (createMaterializedView rejects temporary queries).
Clear enough to supply this argument.
parameters › items › key
Parameter name referenced in the SQL as {{key}}.
Clear enough to supply this argument.
parameters › items › type
Parameter type. Use 'enum' with enumOptions to restrict values.
Clear enough to supply this argument.
parameters › items › value
Default value for the parameter.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"query_id"
],
"properties": {
"query_id": {
"type": "number",
"description": "ID of the new query. Pass it to executeQueryById to run it; the query is at https://dune.com/queries/{query_id}."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "createDuneQuery",
"title": "Create Dune Query",
"description": "Create a new Dune query. Returns the query ID on success.\n\nFor brand-new analysis where the user wants the query executed, rows returned, or a visualization created, prefer createAndExecuteQuery instead. Use createDuneQuery directly when the user only wants to save SQL without running it.\n\nUse this tool when the user wants to:\n- Create a new SQL query on Dune\n- Save a query they've been working on\n\n**Important**: If the query targets tables with known partition columns (returned by searchTables or searchTablesByContractAddress), ensure the SQL includes a WHERE filter on those partition columns (e.g. `WHERE block_date >= CURRENT_DATE - INTERVAL '7' DAY`). This enables partition pruning and significantly reduces query cost.\n\nTo save into a folder, use **folder_id** (after listDuneFolders, especially when the user names a parent path) or **folder_name** when the name is unique. If several folders share the same name, createDuneQuery returns **folder_ambiguous** with paths and ids—retry with **folder_id** or list with **parent_path** first. Do not pass both folder_id and folder_name.\n\nOwnership is automatically derived from the authenticated API key's customer context.\n",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"name",
"query"
],
"properties": {
"name": {
"type": "string",
"description": "Human-readable query title. Max 600 characters. Example: 'Daily DEX Volume on Ethereum'"
},
"query": {
"type": "string",
"description": "The SQL query text in DuneSQL dialect. Max 500,000 characters."
},
"is_temp": {
"type": "boolean",
"default": true,
"description": "Whether the query should be temporary. Defaults to true for MCP-created queries. Temporary queries can be executed and they can have visualizations attached to them but they will not appear on the dune.com library and will not be accessible when shared with others. Set this to false if you intend to create a materialized view from this query (createMaterializedView rejects temporary queries)."
},
"folder_id": {
"type": "string",
"description": "Optional folder ID to save the query into. Must belong to the authenticated user/team. Use listDuneFolders to discover ids, or use folder_name instead."
},
"is_private": {
"type": "boolean",
"description": "Whether the query should be private. Defaults to false. May be forced to true by team privacy settings."
},
"parameters": {
"type": "array",
"items": {
"type": "object",
"required": [
"key",
"type",
"value"
],
"properties": {
"key": {
"type": "string",
"description": "Parameter name referenced in the SQL as {{key}}."
},
"type": {
"enum": [
"text",
"number",
"date",
"enum"
],
"type": "string",
"description": "Parameter type. Use 'enum' with enumOptions to restrict values."
},
"value": {
"type": "string",
"description": "Default value for the parameter."
},
"enumOptions": {
"type": "array",
"items": {
"type": "string"
},
"description": "Allowed values when type is 'enum'."
}
}
},
"description": "Query parameters for parameterized queries. Each parameter includes key, type, value, and optional enumOptions."
},
"description": {
"type": "string",
"description": "Short description of what the query does. Max 1,000 characters."
},
"folder_name": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "Optional folder display name for this user/team (case-insensitive exact match on the folder basename). If multiple folders share this name, the tool errors with folder_ambiguous and lists paths and folder_ids—then pass folder_id or use listDuneFolders(parent_path). Do not set together with folder_id."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"query_id"
],
"properties": {
"query_id": {
"type": "number",
"description": "ID of the new query. Pass it to executeQueryById to run it; the query is at https://dune.com/queries/{query_id}."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Create a new Dune query, execute it, optionally create a visualization, wait for results, and return the query, execution, visualization, and a result preview.
This is the default tool for brand-new SQL analysis requests where the user likely wants results. The model should still discover tables and write DuneSQL itself; this tool handles the deterministic Dune actions after SQL is ready.
Use this tool when the user wants to:
- Create and run a new Dune SQL query
- Create a new query and immediately inspect rows
- Create a new query and chart/table/counter together
Unless the user's question can be fully answered by inspecting raw result rows, provide a visualization. If the user asks for a specific visualization type, use that type; otherwise create a table visualization so the result is ready to render or add to a dashboard. The visualization object reuses generateVisualization's input shape without queryId.
Use lower-level tools for follow-up work:
- updateDuneQuery: fix SQL after an execution error or refine an existing query.
- executeQueryById: rerun an existing query.
- getExecutionResults: fetch more rows or a different slice from an existing execution.
- generateVisualization: add or change a visualization on an existing query.
- renderVisualization: render a returned visualizationId/queryId/executionId when the MCP client supports UI.
The result preview returns at most max_rows_returned rows from offset 0. If the execution is still running at timeout, the response returns the created query and execution, with result_preview showing the current pending/executing state and no rows.
Important: If the query targets tables with known partition columns (returned by searchTables or searchTablesByContractAddress), ensure the SQL includes a WHERE filter on those partition columns (e.g. `WHERE block_date >= CURRENT_DATE - INTERVAL '7' DAY`). This enables partition pruning and significantly reduces query cost.
The description explains the capability, when to use it, and what to expect.
Inputs85/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
name
Human-readable query title. Max 600 characters. Example: 'Daily DEX Volume on Ethereum'
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
folder_id
Optional folder ID to save the query into. Must belong to the authenticated user/team. Use listDuneFolders to discover ids, or use folder_name instead.
Clear enough to supply this argument.
folder_name
Optional folder display name for this user/team (case-insensitive exact match on the folder basename). If multiple folders share this name, the tool errors with folder_ambiguous and lists paths and folder_ids—then pass folder_id or use listDuneFolders(parent_path). Do not set together with folder_id.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
query
The SQL query text in DuneSQL dialect. Max 500,000 characters.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
description
Short description of what the query does. Max 1,000 characters.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
is_private
Whether the query should be private. Defaults to false. May be forced to true by team privacy settings.
Clear enough to supply this argument.
is_temp
Whether the query should be temporary. Defaults to true for MCP-created queries. Temporary queries can be executed and they can have visualizations attached to them but they will not appear on the dune.com library and will not be accessible when shared with others. Set this to false if you intend to create a materialized view from this query (createMaterializedView rejects temporary queries).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
parameters › items › key
Parameter name referenced in the SQL as {{key}}.
Clear enough to supply this argument.
parameters › items › type
Parameter type. Use 'enum' with enumOptions to restrict values.
Clear enough to supply this argument.
parameters › items › value
Default value for the parameter.
Clear enough to supply this argument.
parameters › items › enumOptions
Allowed values when type is 'enum'.
Clear enough to supply this argument.
performance
Engine tier: "free", "small", "medium", or "large". If omitted, defaults to the largest tier available on the caller's plan. Pass a smaller tier for simple or exploratory queries to save credits. Credit cost is returned on `result_preview.resultMetadata.executionCostCredits`.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
timeout
Maximum number of seconds to wait for the execution to complete. Defaults to 60. Set to 0 to return immediately after scheduling execution.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
max_rows_returned
Maximum number of result rows to return in result_preview. Defaults to 20. Maximum allowed is 32000. Use getExecutionResults for later pagination, filtering, ordering, or projection.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
visualization › visualizationName
Name for the visualization (e.g., 'Daily DEX Volume', 'Top 10 Wallets by Balance').
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
visualization › chartType
Chart type to create. Must be one of: column, line, area, scatter, pie, counter, table.
Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order.
Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Clear enough to supply this argument.
visualization › config › oneOf › 0 › y_axes › left › title
Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Clear enough to supply this argument.
visualization › config › oneOf › 0 › y_axes › left › series › items › column
Name of the numeric query result column to plot, exactly as getExecutionResults returns it.
Clear enough to supply this argument.
visualization › config › oneOf › 0 › y_axes › left › series › items › title
Name shown for this series in the legend and tooltip.
Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it.
Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series.
How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts.
Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order.
Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Clear enough to supply this argument.
visualization › config › oneOf › 1 › y_axes › left › title
Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Clear enough to supply this argument.
visualization › config › oneOf › 1 › y_axes › left › series › items › column
Name of the numeric query result column to plot, exactly as getExecutionResults returns it.
Clear enough to supply this argument.
visualization › config › oneOf › 1 › y_axes › left › series › items › title
Name shown for this series in the legend and tooltip.
Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it.
Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order.
Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Clear enough to supply this argument.
visualization › config › oneOf › 2 › y_axes › left › title
Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
visualization › config › oneOf › 2 › y_axes › left › series › items › column
Name of the numeric query result column to plot, exactly as getExecutionResults returns it.
Clear enough to supply this argument.
visualization › config › oneOf › 2 › y_axes › left › series › items › title
Name shown for this series in the legend and tooltip.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it.
Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order.
Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
visualization › config › oneOf › 3 › y_axes › left › title
Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
visualization › config › oneOf › 3 › y_axes › left › series › items › column
Name of the numeric query result column to plot, exactly as getExecutionResults returns it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
visualization › config › oneOf › 3 › y_axes › left › series › items › title
Name shown for this series in the legend and tooltip.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"query"
],
"properties": {
"query": {
"type": "object",
"required": [
"query_id",
"name",
"description",
"query",
"is_private",
"is_temp",
"url"
],
"properties": {
"url": {
"type": "string",
"description": "URL for opening the query in Dune."
},
"name": {
"type": [
"string",
"null"
],
"description": "Human-readable query title."
},
"query": {
"type": "string",
"description": "The SQL text for the query."
},
"is_temp": {
"type": "boolean",
"description": "Whether the query is temporary."
},
"query_id": {
"type": "number",
"description": "The numeric ID of the created query."
},
"is_private": {
"type": "boolean",
"description": "Whether the query is private."
},
"description": {
"type": [
"string",
"null"
],
"description": "Optional query description."
}
},
"additionalProperties": false
},
"execution": {
"type": "object",
"required": [
"execution_id",
"state",
"engine_used"
],
"properties": {
"state": {
"type": "string",
"description": "The initial state of the execution (e.g. QUERY_STATE_PENDING)."
},
"engine_used": {
"enum": [
"free",
"small",
"medium",
"large"
],
"type": "string",
"description": "The engine tier this execution was scheduled on. Matches the caller's explicit `performance` input when provided, otherwise the largest tier available on the caller's plan."
},
"execution_id": {
"type": "string",
"description": "The unique identifier for the execution."
}
},
"description": "Execution created for the query, if execution submission succeeded.",
"additionalProperties": false
},
"visualization": {
"type": "object",
"required": [
"queryId",
"visualizationId",
"chartType",
"visualizationType",
"visualizationName",
"isPrivate",
"interactiveChartUrl",
"chartJpegUrl"
],
"properties": {
"queryId": {
"type": "number",
"description": "The query ID the visualization was created for."
},
"chartType": {
"type": "string",
"description": "The chart type used for the visualization."
},
"isPrivate": {
"type": "boolean",
"description": "Whether the underlying query is private."
},
"chartJpegUrl": {
"type": "string",
"description": "Static JPEG chart image URL suitable for inline preview in chat. This points to https://core-api.dune.com/public/screenshot with the interactive chart URL passed as the encoded `url` query parameter."
},
"visualizationId": {
"type": "number",
"description": "The ID of the created visualization."
},
"visualizationName": {
"type": "string",
"description": "The name of the visualization."
},
"visualizationType": {
"type": "string",
"description": "The DB visualization type: 'chart' (for column/line/area/scatter/pie), 'counter', or 'table'."
},
"interactiveChartUrl": {
"type": "string",
"description": "Interactive chart page URL that renders only this visualization. For private queries, the URL format is /embeds/<query_id>/<visualization_id>/<api_key>."
}
},
"description": "Visualization created for the query, if requested and successful.",
"additionalProperties": false
},
"result_preview": {
"type": "object",
"required": [
"executionId",
"state"
],
"properties": {
"data": {
"type": "object",
"required": [
"rows"
],
"properties": {
"rows": {
"type": "array",
"items": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "Result rows as key-value objects keyed by column name."
}
},
"description": "The actual result data rows for this page.",
"additionalProperties": false
},
"state": {
"type": "string",
"description": "Execution state from the query engine: PENDING, EXECUTING, COMPLETED, FAILED, CANCELLED, or EXPIRED."
},
"executionId": {
"type": "string",
"description": "The execution ID that was queried."
},
"errorMessage": {
"type": "string",
"description": "Human-readable error message when the execution failed or was cancelled."
},
"errorMetadata": {
"type": "object",
"properties": {
"hint": {
"type": "string",
"description": "Hint for fixing the error, if available."
},
"line": {
"type": "number",
"description": "Line number where the error occurred."
},
"column": {
"type": "number",
"description": "Column number where the error occurred."
}
},
"description": "Structured error location info (line, column, hint) for SQL errors.",
"additionalProperties": false
},
"resultMetadata": {
"type": "object",
"required": [
"columns",
"totalRowCount"
],
"properties": {
"columns": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"type"
],
"properties": {
"name": {
"type": "string",
"description": "Column name."
},
"type": {
"type": "string",
"description": "Column data type (e.g. bigint, varchar, double)."
}
},
"additionalProperties": false
},
"description": "Column definitions with name and type."
},
"totalRowCount": {
"type": "number",
"description": "Total number of rows in the full result set."
},
"executionCostCredits": {
"type": "string",
"description": "Execution credit cost."
}
},
"description": "Metadata about the result set including column definitions and total row count.",
"additionalProperties": false
}
},
"description": "Initial execution result page using the getExecutionResults output shape.",
"additionalProperties": false
},
"execution_error": {
"type": "object",
"required": [
"message"
],
"properties": {
"message": {
"type": "string",
"description": "Human-readable error message."
}
},
"description": "Execution submission error, if the query was created but could not be executed.",
"additionalProperties": false
},
"visualization_error": {
"type": "object",
"required": [
"message"
],
"properties": {
"message": {
"type": "string",
"description": "Human-readable error message."
}
},
"description": "Visualization creation error, if visualization was requested but failed.",
"additionalProperties": false
},
"result_preview_error": {
"type": "object",
"required": [
"message"
],
"properties": {
"message": {
"type": "string",
"description": "Human-readable error message."
}
},
"description": "Result preview retrieval error, if execution succeeded but preview retrieval failed.",
"additionalProperties": false
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "createAndExecuteQuery",
"title": "Create And Execute Query",
"description": "Create a new Dune query, execute it, optionally create a visualization, wait for results, and return the query, execution, visualization, and a result preview.\n\nThis is the default tool for brand-new SQL analysis requests where the user likely wants results. The model should still discover tables and write DuneSQL itself; this tool handles the deterministic Dune actions after SQL is ready.\n\nUse this tool when the user wants to:\n- Create and run a new Dune SQL query\n- Create a new query and immediately inspect rows\n- Create a new query and chart/table/counter together\n\nUnless the user's question can be fully answered by inspecting raw result rows, provide a visualization. If the user asks for a specific visualization type, use that type; otherwise create a table visualization so the result is ready to render or add to a dashboard. The visualization object reuses generateVisualization's input shape without queryId.\n\nUse lower-level tools for follow-up work:\n- updateDuneQuery: fix SQL after an execution error or refine an existing query.\n- executeQueryById: rerun an existing query.\n- getExecutionResults: fetch more rows or a different slice from an existing execution.\n- generateVisualization: add or change a visualization on an existing query.\n- renderVisualization: render a returned visualizationId/queryId/executionId when the MCP client supports UI.\n\nThe result preview returns at most max_rows_returned rows from offset 0. If the execution is still running at timeout, the response returns the created query and execution, with result_preview showing the current pending/executing state and no rows.\n\nImportant: If the query targets tables with known partition columns (returned by searchTables or searchTablesByContractAddress), ensure the SQL includes a WHERE filter on those partition columns (e.g. `WHERE block_date >= CURRENT_DATE - INTERVAL '7' DAY`). This enables partition pruning and significantly reduces query cost.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"name",
"query"
],
"properties": {
"name": {
"type": "string",
"description": "Human-readable query title. Max 600 characters. Example: 'Daily DEX Volume on Ethereum'"
},
"query": {
"type": "string",
"description": "The SQL query text in DuneSQL dialect. Max 500,000 characters."
},
"is_temp": {
"type": "boolean",
"default": true,
"description": "Whether the query should be temporary. Defaults to true for MCP-created queries. Temporary queries can be executed and they can have visualizations attached to them but they will not appear on the dune.com library and will not be accessible when shared with others. Set this to false if you intend to create a materialized view from this query (createMaterializedView rejects temporary queries)."
},
"timeout": {
"type": "number",
"default": 60,
"maximum": 14400,
"minimum": 0,
"description": "Maximum number of seconds to wait for the execution to complete. Defaults to 60. Set to 0 to return immediately after scheduling execution."
},
"folder_id": {
"type": "string",
"description": "Optional folder ID to save the query into. Must belong to the authenticated user/team. Use listDuneFolders to discover ids, or use folder_name instead."
},
"is_private": {
"type": "boolean",
"description": "Whether the query should be private. Defaults to false. May be forced to true by team privacy settings."
},
"parameters": {
"type": "array",
"items": {
"type": "object",
"required": [
"key",
"type",
"value"
],
"properties": {
"key": {
"type": "string",
"description": "Parameter name referenced in the SQL as {{key}}."
},
"type": {
"enum": [
"text",
"number",
"date",
"enum"
],
"type": "string",
"description": "Parameter type. Use 'enum' with enumOptions to restrict values."
},
"value": {
"type": "string",
"description": "Default value for the parameter."
},
"enumOptions": {
"type": "array",
"items": {
"type": "string"
},
"description": "Allowed values when type is 'enum'."
}
}
},
"description": "Query parameters for parameterized queries. Each parameter includes key, type, value, and optional enumOptions."
},
"description": {
"type": "string",
"description": "Short description of what the query does. Max 1,000 characters."
},
"folder_name": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "Optional folder display name for this user/team (case-insensitive exact match on the folder basename). If multiple folders share this name, the tool errors with folder_ambiguous and lists paths and folder_ids—then pass folder_id or use listDuneFolders(parent_path). Do not set together with folder_id."
},
"performance": {
"enum": [
"free",
"small",
"medium",
"large"
],
"type": "string",
"description": "Engine tier: \"free\", \"small\", \"medium\", or \"large\". If omitted, defaults to the largest tier available on the caller's plan. Pass a smaller tier for simple or exploratory queries to save credits. Credit cost is returned on `result_preview.resultMetadata.executionCostCredits`."
},
"visualization": {
"type": "object",
"required": [
"visualizationName",
"chartType",
"config"
],
"properties": {
"config": {
"oneOf": [
{
"type": "object",
"required": [
"x_axis",
"y_axes",
"enable_legend",
"stacked",
"chart_type"
],
"properties": {
"x_axis": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Label shown under the x axis. Use an empty string for none."
},
"column": {
"type": "string",
"description": "Query result column for the x axis, usually a time or category column, exactly as getExecutionResults returns it."
},
"sort_x": {
"type": "boolean",
"description": "Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order."
}
}
},
"y_axes": {
"type": "object",
"required": [
"left",
"right_enabled",
"right_label_format",
"right_series"
],
"properties": {
"left": {
"type": "object",
"required": [
"label_format",
"series"
],
"properties": {
"title": {
"type": "string",
"description": "Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Left Y axis series"
},
"tick_format": {
"type": "string",
"description": "Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"label_format": {
"type": "string",
"description": "Numeral.js format for tooltip and data-label values (e.g. 0,0 or $0.0a). Does not format axis ticks; use tick_format for that."
}
}
},
"right_title": {
"type": "string",
"description": "Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"right_series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Right Y axis series (empty if unused)"
},
"right_enabled": {
"type": "boolean",
"description": "Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it."
},
"right_tick_format": {
"type": "string",
"description": "Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"right_label_format": {
"type": "string",
"description": "Numeral.js format for right Y axis tooltip and data-label values (empty if unused). Does not format axis ticks; use right_tick_format for that."
}
}
},
"stacked": {
"type": "boolean",
"description": "Stack series"
},
"chart_type": {
"type": "string",
"const": "column",
"description": "Must match chartType"
},
"enable_legend": {
"type": "boolean",
"description": "Show legend"
},
"group_by_column": {
"type": "string",
"description": "Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series."
},
"when_duplicate_x": {
"enum": [
"first",
"sum",
"all"
],
"type": "string",
"description": "How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts."
},
"normalize_to_percentage": {
"type": "boolean",
"description": "Normalize each x value's series values to percentages of their total (e.g. 100%-stacked area charts). Pair with tick_format '0%'. Defaults to false."
}
}
},
{
"type": "object",
"required": [
"x_axis",
"y_axes",
"enable_legend",
"stacked",
"chart_type"
],
"properties": {
"x_axis": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Label shown under the x axis. Use an empty string for none."
},
"column": {
"type": "string",
"description": "Query result column for the x axis, usually a time or category column, exactly as getExecutionResults returns it."
},
"sort_x": {
"type": "boolean",
"description": "Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order."
}
}
},
"y_axes": {
"type": "object",
"required": [
"left",
"right_enabled",
"right_label_format",
"right_series"
],
"properties": {
"left": {
"type": "object",
"required": [
"label_format",
"series"
],
"properties": {
"title": {
"type": "string",
"description": "Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Left Y axis series"
},
"tick_format": {
"type": "string",
"description": "Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"label_format": {
"type": "string",
"description": "Numeral.js format for tooltip and data-label values (e.g. 0,0 or $0.0a). Does not format axis ticks; use tick_format for that."
}
}
},
"right_title": {
"type": "string",
"description": "Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"right_series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Right Y axis series (empty if unused)"
},
"right_enabled": {
"type": "boolean",
"description": "Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it."
},
"right_tick_format": {
"type": "string",
"description": "Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"right_label_format": {
"type": "string",
"description": "Numeral.js format for right Y axis tooltip and data-label values (empty if unused). Does not format axis ticks; use right_tick_format for that."
}
}
},
"stacked": {
"type": "boolean",
"description": "Stack series"
},
"chart_type": {
"type": "string",
"const": "line",
"description": "Must match chartType"
},
"enable_legend": {
"type": "boolean",
"description": "Show legend"
},
"group_by_column": {
"type": "string",
"description": "Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series."
},
"when_duplicate_x": {
"enum": [
"first",
"sum",
"all"
],
"type": "string",
"description": "How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts."
},
"normalize_to_percentage": {
"type": "boolean",
"description": "Normalize each x value's series values to percentages of their total (e.g. 100%-stacked area charts). Pair with tick_format '0%'. Defaults to false."
}
}
},
{
"type": "object",
"required": [
"x_axis",
"y_axes",
"enable_legend",
"stacked",
"chart_type"
],
"properties": {
"x_axis": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Label shown under the x axis. Use an empty string for none."
},
"column": {
"type": "string",
"description": "Query result column for the x axis, usually a time or category column, exactly as getExecutionResults returns it."
},
"sort_x": {
"type": "boolean",
"description": "Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order."
}
}
},
"y_axes": {
"type": "object",
"required": [
"left",
"right_enabled",
"right_label_format",
"right_series"
],
"properties": {
"left": {
"type": "object",
"required": [
"label_format",
"series"
],
"properties": {
"title": {
"type": "string",
"description": "Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Left Y axis series"
},
"tick_format": {
"type": "string",
"description": "Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"label_format": {
"type": "string",
"description": "Numeral.js format for tooltip and data-label values (e.g. 0,0 or $0.0a). Does not format axis ticks; use tick_format for that."
}
}
},
"right_title": {
"type": "string",
"description": "Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"right_series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Right Y axis series (empty if unused)"
},
"right_enabled": {
"type": "boolean",
"description": "Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it."
},
"right_tick_format": {
"type": "string",
"description": "Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"right_label_format": {
"type": "string",
"description": "Numeral.js format for right Y axis tooltip and data-label values (empty if unused). Does not format axis ticks; use right_tick_format for that."
}
}
},
"stacked": {
"type": "boolean",
"description": "Stack series"
},
"chart_type": {
"type": "string",
"const": "area",
"description": "Must match chartType"
},
"enable_legend": {
"type": "boolean",
"description": "Show legend"
},
"group_by_column": {
"type": "string",
"description": "Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series."
},
"when_duplicate_x": {
"enum": [
"first",
"sum",
"all"
],
"type": "string",
"description": "How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts."
},
"normalize_to_percentage": {
"type": "boolean",
"description": "Normalize each x value's series values to percentages of their total (e.g. 100%-stacked area charts). Pair with tick_format '0%'. Defaults to false."
}
}
},
{
"type": "object",
"required": [
"x_axis",
"y_axes",
"enable_legend",
"stacked",
"chart_type"
],
"properties": {
"x_axis": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Label shown under the x axis. Use an empty string for none."
},
"column": {
"type": "string",
"description": "Query result column for the x axis, usually a time or category column, exactly as getExecutionResults returns it."
},
"sort_x": {
"type": "boolean",
"description": "Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order."
}
}
},
"y_axes": {
"type": "object",
"required": [
"left",
"right_enabled",
"right_label_format",
"right_series"
],
"properties": {
"left": {
"type": "object",
"required": [
"label_format",
"series"
],
"properties": {
"title": {
"type": "string",
"description": "Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Left Y axis series"
},
"tick_format": {
"type": "string",
"description": "Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"label_format": {
"type": "string",
"description": "Numeral.js format for tooltip and data-label values (e.g. 0,0 or $0.0a). Does not format axis ticks; use tick_format for that."
}
}
},
"right_title": {
"type": "string",
"description": "Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"right_series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Right Y axis series (empty if unused)"
},
"right_enabled": {
"type": "boolean",
"description": "Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it."
},
"right_tick_format": {
"type": "string",
"description": "Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"right_label_format": {
"type": "string",
"description": "Numeral.js format for right Y axis tooltip and data-label values (empty if unused). Does not format axis ticks; use right_tick_format for that."
}
}
},
"stacked": {
"type": "boolean",
"description": "Stack series"
},
"chart_type": {
"type": "string",
"const": "scatter",
"description": "Must match chartType"
},
"enable_legend": {
"type": "boolean",
"description": "Show legend"
},
"group_by_column": {
"type": "string",
"description": "Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series."
},
"when_duplicate_x": {
"enum": [
"first",
"sum",
"all"
],
"type": "string",
"description": "How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts."
},
"normalize_to_percentage": {
"type": "boolean",
"description": "Normalize each x value's series values to percentages of their total (e.g. 100%-stacked area charts). Pair with tick_format '0%'. Defaults to false."
}
}
},
{
"type": "object",
"required": [
"chart_type",
"x_axis_column",
"y_axis_column",
"y_axis_title",
"y_axis_label_format",
"show_labels"
],
"properties": {
"chart_type": {
"type": "string",
"const": "pie",
"description": "Must match chartType"
},
"show_labels": {
"type": "boolean",
"description": "Show value labels on slices"
},
"y_axis_title": {
"type": "string",
"description": "Label for values"
},
"enable_legend": {
"type": "boolean",
"default": true,
"description": "Show legend."
},
"x_axis_column": {
"type": "string",
"description": "Column for pie slices"
},
"y_axis_column": {
"type": "string",
"description": "Column for slice values"
},
"y_axis_label_format": {
"type": "string",
"description": "Numeral.js format for values"
}
}
},
{
"type": "object",
"required": [
"chart_type",
"column",
"row_num",
"decimal_places",
"prefix",
"suffix",
"label",
"color_positive",
"color_negative"
],
"properties": {
"label": {
"type": "string",
"description": "Label describing the value"
},
"column": {
"type": "string",
"description": "Column to display"
},
"prefix": {
"type": "string",
"description": "Prefix (e.g. $) or empty"
},
"suffix": {
"type": "string",
"description": "Suffix (e.g. ETH, %) or empty"
},
"row_num": {
"type": "number",
"description": "Row index (1-based)"
},
"chart_type": {
"type": "string",
"const": "counter",
"description": "Must match chartType"
},
"color_negative": {
"type": "boolean",
"description": "Color negatives red"
},
"color_positive": {
"type": "boolean",
"description": "Color positives green"
},
"decimal_places": {
"type": "number",
"description": "Decimal places used to format the counter"
}
}
},
{
"type": "object",
"required": [
"chart_type",
"columns"
],
"properties": {
"columns": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"title",
"column_type",
"data_type",
"align",
"is_hidden",
"color_positive",
"color_negative",
"number_format"
],
"properties": {
"name": {
"type": "string",
"description": "Column name from query"
},
"align": {
"enum": [
"left",
"right",
"center"
],
"type": "string",
"description": "Text alignment"
},
"title": {
"type": "string",
"description": "Display title"
},
"data_type": {
"enum": [
"numeric",
"string",
"date"
],
"type": "string",
"description": "Data type for formatting"
},
"is_hidden": {
"type": "boolean",
"description": "Hide this column"
},
"column_type": {
"enum": [
"normal",
"progressbar"
],
"type": "string",
"description": "Display type"
},
"number_format": {
"type": [
"string",
"null"
],
"description": "Numeral.js format for numeric columns"
},
"color_negative": {
"type": [
"boolean",
"null"
],
"description": "Color negatives red"
},
"color_positive": {
"type": [
"boolean",
"null"
],
"description": "Color positives green"
}
}
},
"description": "Column configurations"
},
"chart_type": {
"type": "string",
"const": "table",
"description": "Must match chartType"
}
}
}
],
"description": "Chart configuration object; must match chartType"
},
"chartType": {
"enum": [
"column",
"line",
"area",
"scatter",
"pie",
"counter",
"table"
],
"type": "string",
"description": "Chart type to create. Must be one of: column, line, area, scatter, pie, counter, table."
},
"visualizationName": {
"type": "string",
"description": "Name for the visualization (e.g., 'Daily DEX Volume', 'Top 10 Wallets by Balance')."
}
},
"description": "Optional visualization to create for the new query before waiting for execution results. Unless raw rows fully answer the user's question, provide this object. Use the user's requested visualization type when specified; otherwise create a table visualization. Reuses generateVisualization's input shape without queryId."
},
"max_rows_returned": {
"type": "integer",
"default": 20,
"maximum": 32000,
"minimum": 0,
"description": "Maximum number of result rows to return in result_preview. Defaults to 20. Maximum allowed is 32000. Use getExecutionResults for later pagination, filtering, ordering, or projection."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"query"
],
"properties": {
"query": {
"type": "object",
"required": [
"query_id",
"name",
"description",
"query",
"is_private",
"is_temp",
"url"
],
"properties": {
"url": {
"type": "string",
"description": "URL for opening the query in Dune."
},
"name": {
"type": [
"string",
"null"
],
"description": "Human-readable query title."
},
"query": {
"type": "string",
"description": "The SQL text for the query."
},
"is_temp": {
"type": "boolean",
"description": "Whether the query is temporary."
},
"query_id": {
"type": "number",
"description": "The numeric ID of the created query."
},
"is_private": {
"type": "boolean",
"description": "Whether the query is private."
},
"description": {
"type": [
"string",
"null"
],
"description": "Optional query description."
}
},
"additionalProperties": false
},
"execution": {
"type": "object",
"required": [
"execution_id",
"state",
"engine_used"
],
"properties": {
"state": {
"type": "string",
"description": "The initial state of the execution (e.g. QUERY_STATE_PENDING)."
},
"engine_used": {
"enum": [
"free",
"small",
"medium",
"large"
],
"type": "string",
"description": "The engine tier this execution was scheduled on. Matches the caller's explicit `performance` input when provided, otherwise the largest tier available on the caller's plan."
},
"execution_id": {
"type": "string",
"description": "The unique identifier for the execution."
}
},
"description": "Execution created for the query, if execution submission succeeded.",
"additionalProperties": false
},
"visualization": {
"type": "object",
"required": [
"queryId",
"visualizationId",
"chartType",
"visualizationType",
"visualizationName",
"isPrivate",
"interactiveChartUrl",
"chartJpegUrl"
],
"properties": {
"queryId": {
"type": "number",
"description": "The query ID the visualization was created for."
},
"chartType": {
"type": "string",
"description": "The chart type used for the visualization."
},
"isPrivate": {
"type": "boolean",
"description": "Whether the underlying query is private."
},
"chartJpegUrl": {
"type": "string",
"description": "Static JPEG chart image URL suitable for inline preview in chat. This points to https://core-api.dune.com/public/screenshot with the interactive chart URL passed as the encoded `url` query parameter."
},
"visualizationId": {
"type": "number",
"description": "The ID of the created visualization."
},
"visualizationName": {
"type": "string",
"description": "The name of the visualization."
},
"visualizationType": {
"type": "string",
"description": "The DB visualization type: 'chart' (for column/line/area/scatter/pie), 'counter', or 'table'."
},
"interactiveChartUrl": {
"type": "string",
"description": "Interactive chart page URL that renders only this visualization. For private queries, the URL format is /embeds/<query_id>/<visualization_id>/<api_key>."
}
},
"description": "Visualization created for the query, if requested and successful.",
"additionalProperties": false
},
"result_preview": {
"type": "object",
"required": [
"executionId",
"state"
],
"properties": {
"data": {
"type": "object",
"required": [
"rows"
],
"properties": {
"rows": {
"type": "array",
"items": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "Result rows as key-value objects keyed by column name."
}
},
"description": "The actual result data rows for this page.",
"additionalProperties": false
},
"state": {
"type": "string",
"description": "Execution state from the query engine: PENDING, EXECUTING, COMPLETED, FAILED, CANCELLED, or EXPIRED."
},
"executionId": {
"type": "string",
"description": "The execution ID that was queried."
},
"errorMessage": {
"type": "string",
"description": "Human-readable error message when the execution failed or was cancelled."
},
"errorMetadata": {
"type": "object",
"properties": {
"hint": {
"type": "string",
"description": "Hint for fixing the error, if available."
},
"line": {
"type": "number",
"description": "Line number where the error occurred."
},
"column": {
"type": "number",
"description": "Column number where the error occurred."
}
},
"description": "Structured error location info (line, column, hint) for SQL errors.",
"additionalProperties": false
},
"resultMetadata": {
"type": "object",
"required": [
"columns",
"totalRowCount"
],
"properties": {
"columns": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"type"
],
"properties": {
"name": {
"type": "string",
"description": "Column name."
},
"type": {
"type": "string",
"description": "Column data type (e.g. bigint, varchar, double)."
}
},
"additionalProperties": false
},
"description": "Column definitions with name and type."
},
"totalRowCount": {
"type": "number",
"description": "Total number of rows in the full result set."
},
"executionCostCredits": {
"type": "string",
"description": "Execution credit cost."
}
},
"description": "Metadata about the result set including column definitions and total row count.",
"additionalProperties": false
}
},
"description": "Initial execution result page using the getExecutionResults output shape.",
"additionalProperties": false
},
"execution_error": {
"type": "object",
"required": [
"message"
],
"properties": {
"message": {
"type": "string",
"description": "Human-readable error message."
}
},
"description": "Execution submission error, if the query was created but could not be executed.",
"additionalProperties": false
},
"visualization_error": {
"type": "object",
"required": [
"message"
],
"properties": {
"message": {
"type": "string",
"description": "Human-readable error message."
}
},
"description": "Visualization creation error, if visualization was requested but failed.",
"additionalProperties": false
},
"result_preview_error": {
"type": "object",
"required": [
"message"
],
"properties": {
"message": {
"type": "string",
"description": "Human-readable error message."
}
},
"description": "Result preview retrieval error, if execution succeeded but preview retrieval failed.",
"additionalProperties": false
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description87/100
List folders the caller may access (same rules as the Dune app: team membership and parent-folder visibility). Use this to find a folder id before createDuneQuery, or to browse the tree. For team credentials, the API key creator or the signed-in OAuth user must be a team member.
The description explains the capability, when to use it, and what to expect.
Inputs91/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
parent_path
Parent folder path. Use '/' for top-level folders. Example: '/my-team-space' for one level down.
Clear enough to supply this argument.
name_contains
Optional case-insensitive substring filter on folder name (same behavior as the app folder list).
Clear enough to supply this argument.
limit
Maximum folders to return (1–100). Default 50.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
offset
Folders to skip. Use next_offset from a previous call.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"folders",
"next_offset"
],
"properties": {
"folders": {
"type": "array",
"items": {
"type": "object",
"required": [
"folder_id",
"name",
"path",
"item_count"
],
"properties": {
"name": {
"type": "string"
},
"path": {
"type": "string"
},
"folder_id": {
"type": "string",
"description": "Use as folder_id in createDuneQuery."
},
"item_count": {
"type": "number",
"description": "Queries and dashboards directly inside the folder."
}
},
"additionalProperties": false
}
},
"next_offset": {
"type": [
"number",
"null"
],
"description": "Pass as offset to get the next page; null on the last page."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "listDuneFolders",
"title": "List Dune folders",
"description": "List folders the caller may access (same rules as the Dune app: team membership and parent-folder visibility). Use this to find a folder id before createDuneQuery, or to browse the tree. For team credentials, the API key creator or the signed-in OAuth user must be a team member.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"limit": {
"type": "integer",
"default": 50,
"maximum": 100,
"minimum": 1,
"description": "Maximum folders to return (1–100). Default 50."
},
"offset": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Folders to skip. Use next_offset from a previous call."
},
"parent_path": {
"type": "string",
"default": "/",
"description": "Parent folder path. Use '/' for top-level folders. Example: '/my-team-space' for one level down."
},
"name_contains": {
"type": "string",
"description": "Optional case-insensitive substring filter on folder name (same behavior as the app folder list)."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"folders",
"next_offset"
],
"properties": {
"folders": {
"type": "array",
"items": {
"type": "object",
"required": [
"folder_id",
"name",
"path",
"item_count"
],
"properties": {
"name": {
"type": "string"
},
"path": {
"type": "string"
},
"folder_id": {
"type": "string",
"description": "Use as folder_id in createDuneQuery."
},
"item_count": {
"type": "number",
"description": "Queries and dashboards directly inside the folder."
}
},
"additionalProperties": false
}
},
"next_offset": {
"type": [
"number",
"null"
],
"description": "Pass as offset to get the next page; null on the last page."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description93/100
Show one folder: its details, its direct subfolders, and the queries and dashboards inside it (not archived), paged with limit and offset. Use listDuneFolders to find a folder_id. A team credential sees that team's folders; a user credential sees the user's own folders.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
folder_id
Folder id from listDuneFolders.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Maximum queries and dashboards to return (1–100). Default 50.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
offset
Items to skip. Use next_offset from a previous call.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Create a folder in the Dune library, at the top level or inside parent_folder_id. A team credential creates it in the team's library (needs an editor or admin behind the key); a user credential creates it in the user's own library. If a folder with the same path already exists, the error is folder_path_already_exists and its metadata carries the existing folder_id, so a retry can use that folder. Save queries into the folder with createDuneQuery (folder_id), or move existing ones with moveContentToFolder.
The description explains the capability, when to use it, and what to expect.
Inputs84/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
name
Folder name. Must not contain '/'.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
parent_folder_id
Create inside this folder. Omit for a top-level folder.
Clear enough to supply this argument.
description
Short text that tells what the folder holds. Omit for none.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Rename a folder or change its description, icon or color. Fields you leave out keep their current value. Renaming updates the paths of every subfolder; queries and dashboards stay where they are. To move a folder use moveDuneFolder.
The description explains the capability, when to use it, and what to expect.
Inputs85/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
folder_id
Folder to change. Get it from listDuneFolders or getDuneFolder.
Clear enough to supply this argument.
name
New name. Must not contain '/'.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description89/100
Move a folder, with everything inside it, under another folder in the same library, or to the top level with parent_folder_id null. A folder cannot move into itself or one of its own subfolders, and the destination must not already hold a folder with the same name.
The description explains the capability, when to use it, and what to expect.
Inputs89/100
Input documentation gives an agent enough context to populate the arguments.
folder_id
The folder to move.
Clear enough to supply this argument.
parent_folder_id
Destination folder id, or null to move to the top level.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description84/100
Move existing queries and dashboards into a folder, or out of any folder with target_folder_id null. Everything listed must belong to the same library as the credential (the team for a team key, the user for a user key); otherwise nothing moves. The move is all or nothing. Find ids with searchDuneQueries, searchDuneDashboards or getDuneFolder.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
query_ids
Query ids to move (up to 100).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
dashboard_ids
Dashboard ids to move (up to 100).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
target_folder_id
Destination folder id, or null to take them out of folders.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Delete a folder. An empty folder is deleted right away. A folder that still has subfolders, queries or dashboards is refused with folder_not_empty, which reports how many of each it holds; set recursive to true only after the user confirms. A recursive delete removes every subfolder and ARCHIVES every query and dashboard inside: they leave the library and can be restored from the archive, but are not moved anywhere. To keep content, move it out first with moveContentToFolder.
The description explains the capability, when to use it, and what to expect.
Inputs91/100
Input documentation gives an agent enough context to populate the arguments.
folder_id
Folder to delete. Get it from listDuneFolders or getDuneFolder.
Clear enough to supply this argument.
recursive
Required to delete a folder that is not empty. Deletes all subfolders and archives the queries and dashboards inside.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"deleted_folder_id",
"path",
"deleted_folder_count",
"archived_query_count",
"archived_dashboard_count"
],
"properties": {
"path": {
"type": "string",
"description": "Path the deleted folder had, e.g. '/Research'."
},
"deleted_folder_id": {
"type": "string",
"description": "ID of the deleted folder."
},
"archived_query_count": {
"type": "number",
"description": "Queries archived by a recursive delete; 0 otherwise."
},
"deleted_folder_count": {
"type": "number",
"description": "The folder plus every subfolder removed with it."
},
"archived_dashboard_count": {
"type": "number",
"description": "Dashboards archived by a recursive delete; 0 otherwise."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "deleteDuneFolder",
"title": "Delete Dune folder",
"description": "Delete a folder. An empty folder is deleted right away. A folder that still has subfolders, queries or dashboards is refused with folder_not_empty, which reports how many of each it holds; set recursive to true only after the user confirms. A recursive delete removes every subfolder and ARCHIVES every query and dashboard inside: they leave the library and can be restored from the archive, but are not moved anywhere. To keep content, move it out first with moveContentToFolder.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"folder_id"
],
"properties": {
"folder_id": {
"type": "string",
"minLength": 1,
"description": "Folder to delete. Get it from listDuneFolders or getDuneFolder."
},
"recursive": {
"type": "boolean",
"default": false,
"description": "Required to delete a folder that is not empty. Deletes all subfolders and archives the queries and dashboards inside."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"deleted_folder_id",
"path",
"deleted_folder_count",
"archived_query_count",
"archived_dashboard_count"
],
"properties": {
"path": {
"type": "string",
"description": "Path the deleted folder had, e.g. '/Research'."
},
"deleted_folder_id": {
"type": "string",
"description": "ID of the deleted folder."
},
"archived_query_count": {
"type": "number",
"description": "Queries archived by a recursive delete; 0 otherwise."
},
"deleted_folder_count": {
"type": "number",
"description": "The folder plus every subfolder removed with it."
},
"archived_dashboard_count": {
"type": "number",
"description": "Dashboards archived by a recursive delete; 0 otherwise."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Fetch a saved Dune query by ID.
Use this tool when the user wants to:
- Retrieve SQL or metadata for an existing query
- Inspect owner/privacy flags before editing or executing
- Discover the latest execution when no execution ID is already known
If you already have an execution ID, use getExecutionResults({ executionId, timeout: 0 }) to check its status instead of calling getDuneQuery to look up the latest execution. Use getExecutionResults with its default timeout to wait for results.
Authorization is enforced based on the authenticated customer context.
Only queries visible to the requester are returned.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
query_id
The numeric ID of the Dune query to fetch.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"query_id",
"user_id",
"team_id",
"version",
"name",
"description",
"tags",
"query",
"parameters",
"is_archived",
"is_private",
"is_temp",
"latest_execution_id",
"latest_execution_state"
],
"properties": {
"name": {
"type": [
"string",
"null"
],
"description": "Human-readable query title."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Ordered query tags."
},
"query": {
"type": "string",
"description": "The SQL text for the query."
},
"is_temp": {
"type": "boolean",
"description": "Whether the query is temporary."
},
"team_id": {
"type": [
"number",
"null"
],
"description": "Team owner ID. Null when the query is user-owned."
},
"user_id": {
"type": [
"number",
"null"
],
"description": "User owner ID. Null when the query is team-owned."
},
"version": {
"type": "number",
"description": "Current query version for optimistic locking updates."
},
"query_id": {
"type": "number",
"description": "The numeric ID of the query."
},
"is_private": {
"type": "boolean",
"description": "Whether the query is private."
},
"parameters": {
"description": "Query parameters that can be injected into the query at execution time without changing the query object."
},
"description": {
"type": [
"string",
"null"
],
"description": "Optional query description."
},
"is_archived": {
"type": "boolean",
"description": "Whether the query is archived."
},
"latest_execution_id": {
"type": [
"string",
"null"
],
"description": "Execution ID of the most recent execution, or null if never executed."
},
"latest_execution_state": {
"type": [
"string",
"null"
],
"description": "State of the most recent execution: QUERY_STATE_COMPLETED, QUERY_STATE_EXECUTING, QUERY_STATE_PENDING, QUERY_STATE_FAILED, QUERY_STATE_CANCELLED, or null if never executed."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "getDuneQuery",
"title": "Get Dune Query",
"description": "Fetch a saved Dune query by ID.\n\nUse this tool when the user wants to:\n- Retrieve SQL or metadata for an existing query\n- Inspect owner/privacy flags before editing or executing\n- Discover the latest execution when no execution ID is already known\n\nIf you already have an execution ID, use getExecutionResults({ executionId, timeout: 0 }) to check its status instead of calling getDuneQuery to look up the latest execution. Use getExecutionResults with its default timeout to wait for results.\n\nAuthorization is enforced based on the authenticated customer context.\nOnly queries visible to the requester are returned.\n",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"query_id"
],
"properties": {
"query_id": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "The numeric ID of the Dune query to fetch."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"query_id",
"user_id",
"team_id",
"version",
"name",
"description",
"tags",
"query",
"parameters",
"is_archived",
"is_private",
"is_temp",
"latest_execution_id",
"latest_execution_state"
],
"properties": {
"name": {
"type": [
"string",
"null"
],
"description": "Human-readable query title."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Ordered query tags."
},
"query": {
"type": "string",
"description": "The SQL text for the query."
},
"is_temp": {
"type": "boolean",
"description": "Whether the query is temporary."
},
"team_id": {
"type": [
"number",
"null"
],
"description": "Team owner ID. Null when the query is user-owned."
},
"user_id": {
"type": [
"number",
"null"
],
"description": "User owner ID. Null when the query is team-owned."
},
"version": {
"type": "number",
"description": "Current query version for optimistic locking updates."
},
"query_id": {
"type": "number",
"description": "The numeric ID of the query."
},
"is_private": {
"type": "boolean",
"description": "Whether the query is private."
},
"parameters": {
"description": "Query parameters that can be injected into the query at execution time without changing the query object."
},
"description": {
"type": [
"string",
"null"
],
"description": "Optional query description."
},
"is_archived": {
"type": "boolean",
"description": "Whether the query is archived."
},
"latest_execution_id": {
"type": [
"string",
"null"
],
"description": "Execution ID of the most recent execution, or null if never executed."
},
"latest_execution_state": {
"type": [
"string",
"null"
],
"description": "State of the most recent execution: QUERY_STATE_COMPLETED, QUERY_STATE_EXECUTING, QUERY_STATE_PENDING, QUERY_STATE_FAILED, QUERY_STATE_CANCELLED, or null if never executed."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description89/100
Search for Dune queries by name (case-insensitive substring match).
Use this when the user does not know a query ID and needs to find saved queries they can open, run, or edit. Results respect the authenticated customer: public content, the user's own and team-accessible private queries, and (for team API keys) that team's queries.
- **all_visible** (default): public queries plus any private queries visible to the caller (same visibility as the Dune app).
- **owned_only**: only queries owned by the user or the authenticated team.
The description explains the capability, when to use it, and what to expect.
Inputs83/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
search_string
Text to find in the query name (partial match).
Clear enough to supply this argument.
scope
all_visible: public plus anything the caller can access; owned_only: only queries owned by the user/team for this key.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Maximum number of results (1–50). Default 20.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Execute a saved Dune query by its ID. Returns the execution ID and state on success.
For brand-new SQL analysis, prefer createAndExecuteQuery so the query is created, executed, and an initial result preview is returned in one call. Use executeQueryById for rerunning an existing query or after updating SQL with updateDuneQuery.
Use this tool when the user wants to:
- Run an existing Dune query
- Trigger a fresh execution of a query
- Execute a query with custom parameters or performance tier
The caller must have permission to execute the target query. Execution is charged based on actual compute resources used.
**Important**: If the query targets tables with known partition columns (returned by searchTables or searchTablesByContractAddress), ensure the SQL includes a WHERE filter on those partition columns (e.g. `WHERE block_date >= CURRENT_DATE - INTERVAL '7' DAY`). This enables partition pruning and significantly reduces query cost.
Note: This tool only schedules execution and returns the execution ID/state. Retain the returned execution_id and pass it as executionId to getExecutionResults for status and rows (timeout: 0 for an immediate status check). Do not call getDuneQuery to rediscover an execution ID you already have. When rendering a visualization, also pass this ID as executionId to renderVisualization to skip the latest-execution lookup. You can also open the query in Dune at "https://dune.com/queries/{query_id}".
The description explains the capability, when to use it, and what to expect.
Inputs85/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
query_id
The numeric ID of the Dune query to execute.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
performance
Engine tier: "free", "small", "medium", or "large". If omitted, defaults to the largest tier available on the caller's plan. Pass a smaller tier for simple or exploratory queries to save credits. Credit cost is returned by getExecutionResults as `resultMetadata.executionCostCredits`.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
query_parameters › items › key
The parameter name as defined in the query.
Clear enough to supply this argument.
query_parameters › items › value
The parameter value as a string. Numbers should be stringified (e.g. "30"). Datetimes use "YYYY-MM-DD HH:mm:ss" format.
Clear enough to supply this argument.
query_parameters › items › type
The parameter type. Must match the type defined in the query. Defaults to text.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"execution_id",
"state",
"engine_used"
],
"properties": {
"state": {
"type": "string",
"description": "The initial state of the execution (e.g. QUERY_STATE_PENDING)."
},
"engine_used": {
"enum": [
"free",
"small",
"medium",
"large"
],
"type": "string",
"description": "The engine tier this execution was scheduled on. Matches the caller's explicit `performance` input when provided, otherwise the largest tier available on the caller's plan."
},
"execution_id": {
"type": "string",
"description": "The unique identifier for the execution."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "executeQueryById",
"title": "Execute Query By ID",
"description": "Execute a saved Dune query by its ID. Returns the execution ID and state on success.\n\nFor brand-new SQL analysis, prefer createAndExecuteQuery so the query is created, executed, and an initial result preview is returned in one call. Use executeQueryById for rerunning an existing query or after updating SQL with updateDuneQuery.\n\nUse this tool when the user wants to:\n- Run an existing Dune query\n- Trigger a fresh execution of a query\n- Execute a query with custom parameters or performance tier\n\nThe caller must have permission to execute the target query. Execution is charged based on actual compute resources used.\n\n**Important**: If the query targets tables with known partition columns (returned by searchTables or searchTablesByContractAddress), ensure the SQL includes a WHERE filter on those partition columns (e.g. `WHERE block_date >= CURRENT_DATE - INTERVAL '7' DAY`). This enables partition pruning and significantly reduces query cost.\n\nNote: This tool only schedules execution and returns the execution ID/state. Retain the returned execution_id and pass it as executionId to getExecutionResults for status and rows (timeout: 0 for an immediate status check). Do not call getDuneQuery to rediscover an execution ID you already have. When rendering a visualization, also pass this ID as executionId to renderVisualization to skip the latest-execution lookup. You can also open the query in Dune at \"https://dune.com/queries/{query_id}\".\n",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"query_id"
],
"properties": {
"query_id": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "The numeric ID of the Dune query to execute."
},
"performance": {
"enum": [
"free",
"small",
"medium",
"large"
],
"type": "string",
"description": "Engine tier: \"free\", \"small\", \"medium\", or \"large\". If omitted, defaults to the largest tier available on the caller's plan. Pass a smaller tier for simple or exploratory queries to save credits. Credit cost is returned by getExecutionResults as `resultMetadata.executionCostCredits`."
},
"query_parameters": {
"type": "array",
"items": {
"type": "object",
"required": [
"key",
"value"
],
"properties": {
"key": {
"type": "string",
"description": "The parameter name as defined in the query."
},
"type": {
"enum": [
"text",
"number",
"datetime",
"enum"
],
"type": "string",
"default": "text",
"description": "The parameter type. Must match the type defined in the query. Defaults to text."
},
"value": {
"type": "string",
"description": "The parameter value as a string. Numbers should be stringified (e.g. \"30\"). Datetimes use \"YYYY-MM-DD HH:mm:ss\" format."
}
}
},
"description": "Typed parameters for the query. Example: [{ \"key\": \"wallet_address\", \"value\": \"0xabc...\", \"type\": \"text\" }, { \"key\": \"days\", \"value\": \"30\", \"type\": \"number\" }]"
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"execution_id",
"state",
"engine_used"
],
"properties": {
"state": {
"type": "string",
"description": "The initial state of the execution (e.g. QUERY_STATE_PENDING)."
},
"engine_used": {
"enum": [
"free",
"small",
"medium",
"large"
],
"type": "string",
"description": "The engine tier this execution was scheduled on. Matches the caller's explicit `performance` input when provided, otherwise the largest tier available on the caller's plan."
},
"execution_id": {
"type": "string",
"description": "The unique identifier for the execution."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description85/100
Update an existing Dune query. Use this tool to modify a query's SQL, title, description, privacy, tags, or parameters.
When to call this tool:
- The user wants to save changes to a query they own (or have edit access to via team membership).
- Updating SQL content, renaming, changing privacy, archiving, or editing tags/parameters.
Important notes:
- queryId is required and must be the numeric ID of the query.
- Only supply the fields you want to change; unchanged fields will be preserved from the existing query.
- The tool performs an optimistic-locking update: if someone else edited the query concurrently you'll get a conflict error.
- Only change queries from private to public if the user explicitly requests it, else ask for confirmation to avoid accidental data exposure.
- Temporary status can be changed with is_temp.
Example usage patterns:
- Update SQL only: { "queryId": 12345, "query": "SELECT * FROM ethereum.transactions LIMIT 10" }
- Rename: { "queryId": 12345, "name": "My Updated Query" }
- Make private: { "queryId": 12345, "is_private": true }
- Update tags: { "queryId": 12345, "tags": ["defi", "uniswap"] }
- Multiple changes: { "queryId": 12345, "name": "New Name", "query": "SELECT 1", "is_private": true }
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
queryId
The numeric ID of the query to update. Required.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
name
New title for the query. Max 600 characters. Omit to keep the current name.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
query
New SQL content for the query. Max 500 000 characters. Omit to keep the current SQL.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
description
New description for the query. Set to null to clear. Omit to keep the current description.
Clear enough to supply this argument.
is_private
Set to true to make the query private, false to make public.
Clear enough to supply this argument.
is_archived
Set to true to archive the query, false to unarchive. Archiving a temporary query also makes it non-temporary.
Clear enough to supply this argument.
is_temp
Set to true to make the query temporary. Temporary queries can be executed and they can have visualizations attached to them but they will not appear on the dune.com library and will not be accessible to anyone other than the user.
Clear enough to supply this argument.
tags
New set of tags for the query. Replaces all existing tags.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
parameters › items › key
Parameter name referenced in the SQL as {{key}}.
Clear enough to supply this argument.
parameters › items › type
Parameter type.
Clear enough to supply this argument.
parameters › items › value
Default value for the parameter.
Clear enough to supply this argument.
parameters › items › enumOptions
Values the user can pick from in the parameter dropdown when type is 'enum'.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"queryId"
],
"properties": {
"queryId": {
"type": "number",
"description": "The numeric ID of the updated query."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "updateDuneQuery",
"title": "Update Dune Query",
"description": "Update an existing Dune query. Use this tool to modify a query's SQL, title, description, privacy, tags, or parameters.\n\nWhen to call this tool:\n- The user wants to save changes to a query they own (or have edit access to via team membership).\n- Updating SQL content, renaming, changing privacy, archiving, or editing tags/parameters.\n\nImportant notes:\n- queryId is required and must be the numeric ID of the query.\n- Only supply the fields you want to change; unchanged fields will be preserved from the existing query.\n- The tool performs an optimistic-locking update: if someone else edited the query concurrently you'll get a conflict error.\n- Only change queries from private to public if the user explicitly requests it, else ask for confirmation to avoid accidental data exposure.\n- Temporary status can be changed with is_temp.\n\nExample usage patterns:\n- Update SQL only: { \"queryId\": 12345, \"query\": \"SELECT * FROM ethereum.transactions LIMIT 10\" }\n- Rename: { \"queryId\": 12345, \"name\": \"My Updated Query\" }\n- Make private: { \"queryId\": 12345, \"is_private\": true }\n- Update tags: { \"queryId\": 12345, \"tags\": [\"defi\", \"uniswap\"] }\n- Multiple changes: { \"queryId\": 12345, \"name\": \"New Name\", \"query\": \"SELECT 1\", \"is_private\": true }\n",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"queryId"
],
"properties": {
"name": {
"type": "string",
"description": "New title for the query. Max 600 characters. Omit to keep the current name."
},
"tags": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"description": "New set of tags for the query. Replaces all existing tags."
},
"query": {
"type": "string",
"description": "New SQL content for the query. Max 500 000 characters. Omit to keep the current SQL."
},
"is_temp": {
"type": "boolean",
"description": "Set to true to make the query temporary. Temporary queries can be executed and they can have visualizations attached to them but they will not appear on the dune.com library and will not be accessible to anyone other than the user."
},
"queryId": {
"type": "number",
"description": "The numeric ID of the query to update. Required."
},
"is_private": {
"type": "boolean",
"description": "Set to true to make the query private, false to make public."
},
"parameters": {
"type": "array",
"items": {
"type": "object",
"required": [
"key",
"type",
"value"
],
"properties": {
"key": {
"type": "string",
"description": "Parameter name referenced in the SQL as {{key}}."
},
"type": {
"enum": [
"text",
"number",
"date",
"enum"
],
"type": "string",
"description": "Parameter type."
},
"value": {
"type": "string",
"description": "Default value for the parameter."
},
"enumOptions": {
"type": "array",
"items": {
"type": "string"
},
"description": "Values the user can pick from in the parameter dropdown when type is 'enum'."
}
}
},
"description": "Query parameters array. Each parameter has key, type, and value. Omit to keep existing."
},
"description": {
"type": [
"string",
"null"
],
"description": "New description for the query. Set to null to clear. Omit to keep the current description."
},
"is_archived": {
"type": "boolean",
"description": "Set to true to archive the query, false to unarchive. Archiving a temporary query also makes it non-temporary."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"queryId"
],
"properties": {
"queryId": {
"type": "number",
"description": "The numeric ID of the updated query."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Get the status and rows of a query execution by its execution ID. Pass the execution_id that executeQueryById or createAndExecuteQuery returned; do not look it up again with getDuneQuery.
By default the tool waits up to `timeout` seconds for the execution to finish and streams progress while it waits. Set `timeout: 0` for an immediate status check. Response types:
- **Pending/Executing**: still running (only when the timeout is reached or set to 0).
- **Completed**: the rows, with the execution credit cost when available.
- **Failed/Cancelled/Expired**: the error details. For expired results, run the query again with executeQueryById.
One call returns up to 32000 rows (default 100); page with `limit` and `offset`. For larger results, link the user to "https://dune.com/queries/{query_id}" or suggest the Dune API (searchDocs covers the SDKs).
Result shaping (optional, all combine; see each field for syntax):
- `outputColumns`: return only the named columns.
- `orderByClauses`: sort with SQL ORDER BY fragments.
- `sampleSize`: a uniform random sample of N rows, in one response without pagination.
- `whereClause`: filter rows with a simple WHERE expression.
Fast usage patterns:
- Wait for results (default): { "executionId": "01ABCD..." }
- Immediate check (no wait): { "executionId": "01ABCD...", "timeout": 0 }
- Project columns + sort: { "executionId": "01ABCD...", "outputColumns": ["time", "amount"], "orderByClauses": ["\"time\" DESC"] }
- Random sample for a chart: { "executionId": "01ABCD...", "sampleSize": 8000 }
- Filter rows: { "executionId": "01ABCD...", "whereClause": "\"amount\" > 0" }
Agent display instructions:
- If you render this data as a chart, table, or any other visualization for the user, include a "Powered by [Dune](https://dune.com/queries/{query_id})" attribution next to it, linking to the underlying query.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
executionId
The execution ID to fetch results for. This is a ULID format string returned when a query is executed. Example: '01JG2A3B4C5D6E7F8G9H0J1K2M'.
Clear enough to supply this argument.
limit
Maximum number of result rows to return. Defaults to 100. Maximum allowed is 32000. Ignored when `sampleSize` is set.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
offset
Number of rows to skip before starting to return results. Used for pagination. Defaults to 0. Ignored when `sampleSize` is set.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
timeout
Maximum number of seconds to wait for the execution to complete. Defaults to 60. Set to 0 to return immediately without waiting (legacy behavior). Timeout is capped by the caller's service-tier operation costs and hard-capped at 14400 seconds (4 hours).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
outputColumns
Optional list of column names to project. When omitted, all columns are returned.
Clear enough to supply this argument.
orderByClauses
Optional list of raw SQL ORDER BY fragments, applied in priority order. Format: `"<column>" [ASC|DESC]`. Quote column names that contain spaces or special characters. Example: ["\"block_time\" DESC"].
Clear enough to supply this argument.
sampleSize
Return a uniform random sample of this many rows from the full result set. Incompatible with pagination — when set, the server returns a single response capped at this value.
Clear enough to supply this argument.
whereClause
Optional SQL-like WHERE expression to filter rows, e.g. `"block_number" > 1000`. Filter syntax: <column> <operator> <literal>, combined with AND/OR and parentheses. Operators: =, <, <=, >, >=, LIKE, IN (...), IS NOT NULL. Values are string or number literals only; write dates as strings, e.g. block_time > '2024-03-01'. Not supported: NOT, NOT IN, NOT LIKE, functions, expressions and subqueries. Double-quote column names with special characters.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"executionId",
"state"
],
"properties": {
"data": {
"type": "object",
"required": [
"rows"
],
"properties": {
"rows": {
"type": "array",
"items": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "Result rows as key-value objects keyed by column name."
}
},
"description": "The actual result data rows for this page.",
"additionalProperties": false
},
"state": {
"type": "string",
"description": "Execution state from the query engine: PENDING, EXECUTING, COMPLETED, FAILED, CANCELLED, or EXPIRED."
},
"executionId": {
"type": "string",
"description": "The execution ID that was queried."
},
"errorMessage": {
"type": "string",
"description": "Human-readable error message when the execution failed or was cancelled."
},
"errorMetadata": {
"type": "object",
"properties": {
"hint": {
"type": "string",
"description": "Hint for fixing the error, if available."
},
"line": {
"type": "number",
"description": "Line number where the error occurred."
},
"column": {
"type": "number",
"description": "Column number where the error occurred."
}
},
"description": "Structured error location info (line, column, hint) for SQL errors.",
"additionalProperties": false
},
"resultMetadata": {
"type": "object",
"required": [
"columns",
"totalRowCount"
],
"properties": {
"columns": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"type"
],
"properties": {
"name": {
"type": "string",
"description": "Column name."
},
"type": {
"type": "string",
"description": "Column data type (e.g. bigint, varchar, double)."
}
},
"additionalProperties": false
},
"description": "Column definitions with name and type."
},
"totalRowCount": {
"type": "number",
"description": "Total number of rows in the full result set."
},
"executionCostCredits": {
"type": "string",
"description": "Execution credit cost."
}
},
"description": "Metadata about the result set including column definitions and total row count.",
"additionalProperties": false
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "getExecutionResults",
"title": "Get Execution Results",
"description": "Get the status and rows of a query execution by its execution ID. Pass the execution_id that executeQueryById or createAndExecuteQuery returned; do not look it up again with getDuneQuery.\n\nBy default the tool waits up to `timeout` seconds for the execution to finish and streams progress while it waits. Set `timeout: 0` for an immediate status check. Response types:\n- **Pending/Executing**: still running (only when the timeout is reached or set to 0).\n- **Completed**: the rows, with the execution credit cost when available.\n- **Failed/Cancelled/Expired**: the error details. For expired results, run the query again with executeQueryById.\n\nOne call returns up to 32000 rows (default 100); page with `limit` and `offset`. For larger results, link the user to \"https://dune.com/queries/{query_id}\" or suggest the Dune API (searchDocs covers the SDKs).\n\nResult shaping (optional, all combine; see each field for syntax):\n- `outputColumns`: return only the named columns.\n- `orderByClauses`: sort with SQL ORDER BY fragments.\n- `sampleSize`: a uniform random sample of N rows, in one response without pagination.\n- `whereClause`: filter rows with a simple WHERE expression.\n\nFast usage patterns:\n- Wait for results (default): { \"executionId\": \"01ABCD...\" }\n- Immediate check (no wait): { \"executionId\": \"01ABCD...\", \"timeout\": 0 }\n- Project columns + sort: { \"executionId\": \"01ABCD...\", \"outputColumns\": [\"time\", \"amount\"], \"orderByClauses\": [\"\\\"time\\\" DESC\"] }\n- Random sample for a chart: { \"executionId\": \"01ABCD...\", \"sampleSize\": 8000 }\n- Filter rows: { \"executionId\": \"01ABCD...\", \"whereClause\": \"\\\"amount\\\" > 0\" }\n\nAgent display instructions:\n- If you render this data as a chart, table, or any other visualization for the user, include a \"Powered by [Dune](https://dune.com/queries/{query_id})\" attribution next to it, linking to the underlying query.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"executionId"
],
"properties": {
"limit": {
"type": "integer",
"default": 100,
"maximum": 32000,
"minimum": 0,
"description": "Maximum number of result rows to return. Defaults to 100. Maximum allowed is 32000. Ignored when `sampleSize` is set."
},
"offset": {
"type": "integer",
"default": 0,
"maximum": 9007199254740991,
"minimum": 0,
"description": "Number of rows to skip before starting to return results. Used for pagination. Defaults to 0. Ignored when `sampleSize` is set."
},
"timeout": {
"type": "number",
"default": 60,
"maximum": 14400,
"minimum": 0,
"description": "Maximum number of seconds to wait for the execution to complete. Defaults to 60. Set to 0 to return immediately without waiting (legacy behavior). Timeout is capped by the caller's service-tier operation costs and hard-capped at 14400 seconds (4 hours)."
},
"sampleSize": {
"type": "integer",
"maximum": 32000,
"description": "Return a uniform random sample of this many rows from the full result set. Incompatible with pagination — when set, the server returns a single response capped at this value.",
"exclusiveMinimum": 0
},
"executionId": {
"type": "string",
"description": "The execution ID to fetch results for. This is a ULID format string returned when a query is executed. Example: '01JG2A3B4C5D6E7F8G9H0J1K2M'."
},
"whereClause": {
"type": "string",
"minLength": 1,
"description": "Optional SQL-like WHERE expression to filter rows, e.g. `\"block_number\" > 1000`. Filter syntax: <column> <operator> <literal>, combined with AND/OR and parentheses. Operators: =, <, <=, >, >=, LIKE, IN (...), IS NOT NULL. Values are string or number literals only; write dates as strings, e.g. block_time > '2024-03-01'. Not supported: NOT, NOT IN, NOT LIKE, functions, expressions and subqueries. Double-quote column names with special characters."
},
"outputColumns": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"description": "Optional list of column names to project. When omitted, all columns are returned."
},
"orderByClauses": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"description": "Optional list of raw SQL ORDER BY fragments, applied in priority order. Format: `\"<column>\" [ASC|DESC]`. Quote column names that contain spaces or special characters. Example: [\"\\\"block_time\\\" DESC\"]."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"executionId",
"state"
],
"properties": {
"data": {
"type": "object",
"required": [
"rows"
],
"properties": {
"rows": {
"type": "array",
"items": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "Result rows as key-value objects keyed by column name."
}
},
"description": "The actual result data rows for this page.",
"additionalProperties": false
},
"state": {
"type": "string",
"description": "Execution state from the query engine: PENDING, EXECUTING, COMPLETED, FAILED, CANCELLED, or EXPIRED."
},
"executionId": {
"type": "string",
"description": "The execution ID that was queried."
},
"errorMessage": {
"type": "string",
"description": "Human-readable error message when the execution failed or was cancelled."
},
"errorMetadata": {
"type": "object",
"properties": {
"hint": {
"type": "string",
"description": "Hint for fixing the error, if available."
},
"line": {
"type": "number",
"description": "Line number where the error occurred."
},
"column": {
"type": "number",
"description": "Column number where the error occurred."
}
},
"description": "Structured error location info (line, column, hint) for SQL errors.",
"additionalProperties": false
},
"resultMetadata": {
"type": "object",
"required": [
"columns",
"totalRowCount"
],
"properties": {
"columns": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"type"
],
"properties": {
"name": {
"type": "string",
"description": "Column name."
},
"type": {
"type": "string",
"description": "Column data type (e.g. bigint, varchar, double)."
}
},
"additionalProperties": false
},
"description": "Column definitions with name and type."
},
"totalRowCount": {
"type": "number",
"description": "Total number of rows in the full result set."
},
"executionCostCredits": {
"type": "string",
"description": "Execution credit cost."
}
},
"description": "Metadata about the result set including column definitions and total row count.",
"additionalProperties": false
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description89/100
Get credit usage for the authenticated customer in the current billing period.
When to call this tool:
- You want to see current-period credit usage for the authenticated user or team.
- You need billing period boundaries, subscription metadata, and quota for that usage.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"billingPeriodStart",
"billingPeriodEnd",
"subscriptionPlanName",
"creditsUsed",
"creditsQuota"
],
"properties": {
"creditsUsed": {
"type": "number",
"description": "Credits used in the current billing period, computed from ClickHouse metering data."
},
"creditsQuota": {
"type": [
"number",
"null"
],
"description": "Included credits quota for the current billing period, or null if the plan has no quota."
},
"billingPeriodEnd": {
"type": [
"string",
"null"
],
"description": "ISO-8601 UTC timestamp for current billing period end, or null for an ongoing period."
},
"billingPeriodStart": {
"type": "string",
"description": "ISO-8601 UTC timestamp for current billing period start."
},
"subscriptionPlanName": {
"type": "string",
"description": "Plan name used for metering during this billing period."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "getUsage",
"title": "Get Usage",
"description": "Get credit usage for the authenticated customer in the current billing period.\n\nWhen to call this tool:\n- You want to see current-period credit usage for the authenticated user or team.\n- You need billing period boundaries, subscription metadata, and quota for that usage.\n",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"billingPeriodStart",
"billingPeriodEnd",
"subscriptionPlanName",
"creditsUsed",
"creditsQuota"
],
"properties": {
"creditsUsed": {
"type": "number",
"description": "Credits used in the current billing period, computed from ClickHouse metering data."
},
"creditsQuota": {
"type": [
"number",
"null"
],
"description": "Included credits quota for the current billing period, or null if the plan has no quota."
},
"billingPeriodEnd": {
"type": [
"string",
"null"
],
"description": "ISO-8601 UTC timestamp for current billing period end, or null for an ongoing period."
},
"billingPeriodStart": {
"type": "string",
"description": "ISO-8601 UTC timestamp for current billing period start."
},
"subscriptionPlanName": {
"type": "string",
"description": "Plan name used for metering during this billing period."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
Create a query visualization and return both static and interactive chart URLs.
Before you build the config:
- The query must have an execution with results. Inspect its columns with getExecutionResults; column names in config must exactly match the query output.
- When an execution ID is already known, check it with getExecutionResults({ executionId, timeout: 0 }) and wait for it if it is still running; do not start another execution. Use getDuneQuery to find the latest execution only when no ID is known, and executeQueryById when the query has no usable execution.
- config.chart_type must match chartType.
For brand-new SQL analysis where the visualization can be specified up front, prefer createAndExecuteQuery with its visualization input. Use generateVisualization to add or change a visualization on an existing query.
Chart types: column, line, area, scatter, pie, counter, table.
Number formats (Numeral.js): 0, 0,0, 0,0.00, 0.0a, $0.0a (currency only), 0%.
Formatting: label_format formats tooltip and data-label values; tick_format / right_tick_format format the y-axis tick labels. Set both for percentage or currency charts.
Duplicate x values: stacked charts keep only the first row per x value within a series by default; set when_duplicate_x 'sum' when the query can return several rows per x value. normalize_to_percentage shows each x value's series as shares of 100% (pair with tick_format '0%').
Dual Y-axis: only line and area charts support a right axis. Column and scatter charts put all series on the left axis.
Agent display instructions:
- Render chartJpegUrl inline as a markdown image if your client supports it; otherwise give it as a link.
- Always include interactiveChartUrl as a clickable link.
- For private queries, the embed URL contains an API key. Treat those links as sensitive and do not share them outside the current user context.
The description explains the capability, when to use it, and what to expect.
Inputs84/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
queryId
The query ID to create a visualization for.
Clear enough to supply this argument.
visualizationName
Name for the visualization (e.g., 'Daily DEX Volume', 'Top 10 Wallets by Balance').
Clear enough to supply this argument.
chartType
Chart type to create. Must be one of: column, line, area, scatter, pie, counter, table.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 0 › x_axis › column
Query result column for the x axis, usually a time or category column, exactly as getExecutionResults returns it.
Clear enough to supply this argument.
config › oneOf › 0 › x_axis › title
Label shown under the x axis. Use an empty string for none.
Clear enough to supply this argument.
config › oneOf › 0 › x_axis › sort_x
Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order.
Clear enough to supply this argument.
config › oneOf › 0 › y_axes › left › label_format
Numeral.js format for tooltip and data-label values (e.g. 0,0 or $0.0a). Does not format axis ticks; use tick_format for that.
Clear enough to supply this argument.
config › oneOf › 0 › y_axes › left › tick_format
Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Clear enough to supply this argument.
config › oneOf › 0 › y_axes › left › title
Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Clear enough to supply this argument.
config › oneOf › 0 › y_axes › left › series › items › column
Name of the numeric query result column to plot, exactly as getExecutionResults returns it.
Clear enough to supply this argument.
config › oneOf › 0 › y_axes › left › series › items › title
Name shown for this series in the legend and tooltip.
Clear enough to supply this argument.
config › oneOf › 0 › y_axes › right_enabled
Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it.
Clear enough to supply this argument.
config › oneOf › 0 › y_axes › right_label_format
Numeral.js format for right Y axis tooltip and data-label values (empty if unused). Does not format axis ticks; use right_tick_format for that.
Clear enough to supply this argument.
config › oneOf › 0 › y_axes › right_tick_format
Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Clear enough to supply this argument.
config › oneOf › 0 › y_axes › right_title
Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Name shown for this series in the legend and tooltip.
Clear enough to supply this argument.
config › oneOf › 0 › group_by_column
Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series.
Clear enough to supply this argument.
config › oneOf › 0 › enable_legend
Show legend
Clear enough to supply this argument.
config › oneOf › 0 › stacked
Stack series
Clear enough to supply this argument.
config › oneOf › 0 › when_duplicate_x
How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts.
Clear enough to supply this argument.
config › oneOf › 0 › normalize_to_percentage
Normalize each x value's series values to percentages of their total (e.g. 100%-stacked area charts). Pair with tick_format '0%'. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 0 › chart_type
Must match chartType
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 1 › x_axis › column
Query result column for the x axis, usually a time or category column, exactly as getExecutionResults returns it.
Clear enough to supply this argument.
config › oneOf › 1 › x_axis › title
Label shown under the x axis. Use an empty string for none.
Clear enough to supply this argument.
config › oneOf › 1 › x_axis › sort_x
Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order.
Clear enough to supply this argument.
config › oneOf › 1 › y_axes › left › label_format
Numeral.js format for tooltip and data-label values (e.g. 0,0 or $0.0a). Does not format axis ticks; use tick_format for that.
Clear enough to supply this argument.
config › oneOf › 1 › y_axes › left › tick_format
Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Clear enough to supply this argument.
config › oneOf › 1 › y_axes › left › title
Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Clear enough to supply this argument.
config › oneOf › 1 › y_axes › left › series › items › column
Name of the numeric query result column to plot, exactly as getExecutionResults returns it.
Clear enough to supply this argument.
config › oneOf › 1 › y_axes › left › series › items › title
Name shown for this series in the legend and tooltip.
Clear enough to supply this argument.
config › oneOf › 1 › y_axes › right_enabled
Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it.
Clear enough to supply this argument.
config › oneOf › 1 › y_axes › right_label_format
Numeral.js format for right Y axis tooltip and data-label values (empty if unused). Does not format axis ticks; use right_tick_format for that.
Clear enough to supply this argument.
config › oneOf › 1 › y_axes › right_tick_format
Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Clear enough to supply this argument.
config › oneOf › 1 › y_axes › right_title
Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Name shown for this series in the legend and tooltip.
Clear enough to supply this argument.
config › oneOf › 1 › group_by_column
Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series.
Clear enough to supply this argument.
config › oneOf › 1 › enable_legend
Show legend
Clear enough to supply this argument.
config › oneOf › 1 › stacked
Stack series
Clear enough to supply this argument.
config › oneOf › 1 › when_duplicate_x
How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 1 › normalize_to_percentage
Normalize each x value's series values to percentages of their total (e.g. 100%-stacked area charts). Pair with tick_format '0%'. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 1 › chart_type
Must match chartType
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › x_axis › column
Query result column for the x axis, usually a time or category column, exactly as getExecutionResults returns it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › x_axis › title
Label shown under the x axis. Use an empty string for none.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › x_axis › sort_x
Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order.
Clear enough to supply this argument.
config › oneOf › 2 › y_axes › left › label_format
Numeral.js format for tooltip and data-label values (e.g. 0,0 or $0.0a). Does not format axis ticks; use tick_format for that.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › y_axes › left › tick_format
Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › y_axes › left › title
Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › y_axes › left › series › items › column
Name of the numeric query result column to plot, exactly as getExecutionResults returns it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › y_axes › left › series › items › title
Name shown for this series in the legend and tooltip.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › y_axes › right_enabled
Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › y_axes › right_label_format
Numeral.js format for right Y axis tooltip and data-label values (empty if unused). Does not format axis ticks; use right_tick_format for that.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › y_axes › right_tick_format
Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › y_axes › right_title
Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Name shown for this series in the legend and tooltip.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › group_by_column
Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › enable_legend
Show legend
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › stacked
Stack series
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › when_duplicate_x
How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › normalize_to_percentage
Normalize each x value's series values to percentages of their total (e.g. 100%-stacked area charts). Pair with tick_format '0%'. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › chart_type
Must match chartType
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › x_axis › column
Query result column for the x axis, usually a time or category column, exactly as getExecutionResults returns it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › x_axis › title
Label shown under the x axis. Use an empty string for none.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › x_axis › sort_x
Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › y_axes › left › label_format
Numeral.js format for tooltip and data-label values (e.g. 0,0 or $0.0a). Does not format axis ticks; use tick_format for that.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › y_axes › left › tick_format
Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › y_axes › left › title
Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › y_axes › left › series › items › column
Name of the numeric query result column to plot, exactly as getExecutionResults returns it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › y_axes › left › series › items › title
Name shown for this series in the legend and tooltip.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › y_axes › right_enabled
Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › y_axes › right_label_format
Numeral.js format for right Y axis tooltip and data-label values (empty if unused). Does not format axis ticks; use right_tick_format for that.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › y_axes › right_tick_format
Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › y_axes › right_title
Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Name shown for this series in the legend and tooltip.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › group_by_column
Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › enable_legend
Show legend
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › stacked
Stack series
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › when_duplicate_x
How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › normalize_to_percentage
Normalize each x value's series values to percentages of their total (e.g. 100%-stacked area charts). Pair with tick_format '0%'. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › chart_type
Must match chartType
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 4 › chart_type
Must match chartType
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 4 › x_axis_column
Column for pie slices
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 4 › y_axis_column
Column for slice values
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 4 › y_axis_title
Label for values
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 4 › y_axis_label_format
Numeral.js format for values
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 4 › enable_legend
Show legend.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 4 › show_labels
Show value labels on slices
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 5 › chart_type
Must match chartType
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 5 › column
Column to display
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 5 › row_num
Row index (1-based)
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 5 › decimal_places
Decimal places used to format the counter
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 5 › prefix
Prefix (e.g. $) or empty
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 5 › suffix
Suffix (e.g. ETH, %) or empty
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 5 › label
Label describing the value
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 5 › color_positive
Color positives green
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 5 › color_negative
Color negatives red
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 6 › chart_type
Must match chartType
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 6 › columns › items › name
Column name from query
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 6 › columns › items › title
Display title
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"queryId",
"visualizationId",
"chartType",
"visualizationType",
"visualizationName",
"isPrivate",
"interactiveChartUrl",
"chartJpegUrl"
],
"properties": {
"queryId": {
"type": "number",
"description": "The query ID the visualization was created for."
},
"chartType": {
"type": "string",
"description": "The chart type used for the visualization."
},
"isPrivate": {
"type": "boolean",
"description": "Whether the underlying query is private."
},
"chartJpegUrl": {
"type": "string",
"description": "Static JPEG chart image URL suitable for inline preview in chat. This points to https://core-api.dune.com/public/screenshot with the interactive chart URL passed as the encoded `url` query parameter."
},
"visualizationId": {
"type": "number",
"description": "The ID of the created visualization."
},
"visualizationName": {
"type": "string",
"description": "The name of the visualization."
},
"visualizationType": {
"type": "string",
"description": "The DB visualization type: 'chart' (for column/line/area/scatter/pie), 'counter', or 'table'."
},
"interactiveChartUrl": {
"type": "string",
"description": "Interactive chart page URL that renders only this visualization. For private queries, the URL format is /embeds/<query_id>/<visualization_id>/<api_key>."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "generateVisualization",
"title": "Generate Visualization",
"description": "Create a query visualization and return both static and interactive chart URLs.\n\nBefore you build the config:\n- The query must have an execution with results. Inspect its columns with getExecutionResults; column names in config must exactly match the query output.\n- When an execution ID is already known, check it with getExecutionResults({ executionId, timeout: 0 }) and wait for it if it is still running; do not start another execution. Use getDuneQuery to find the latest execution only when no ID is known, and executeQueryById when the query has no usable execution.\n- config.chart_type must match chartType.\n\nFor brand-new SQL analysis where the visualization can be specified up front, prefer createAndExecuteQuery with its visualization input. Use generateVisualization to add or change a visualization on an existing query.\n\nChart types: column, line, area, scatter, pie, counter, table.\nNumber formats (Numeral.js): 0, 0,0, 0,0.00, 0.0a, $0.0a (currency only), 0%.\nFormatting: label_format formats tooltip and data-label values; tick_format / right_tick_format format the y-axis tick labels. Set both for percentage or currency charts.\nDuplicate x values: stacked charts keep only the first row per x value within a series by default; set when_duplicate_x 'sum' when the query can return several rows per x value. normalize_to_percentage shows each x value's series as shares of 100% (pair with tick_format '0%').\nDual Y-axis: only line and area charts support a right axis. Column and scatter charts put all series on the left axis.\n\nAgent display instructions:\n- Render chartJpegUrl inline as a markdown image if your client supports it; otherwise give it as a link.\n- Always include interactiveChartUrl as a clickable link.\n- For private queries, the embed URL contains an API key. Treat those links as sensitive and do not share them outside the current user context.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"queryId",
"visualizationName",
"chartType",
"config"
],
"properties": {
"config": {
"oneOf": [
{
"type": "object",
"required": [
"x_axis",
"y_axes",
"enable_legend",
"stacked",
"chart_type"
],
"properties": {
"x_axis": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Label shown under the x axis. Use an empty string for none."
},
"column": {
"type": "string",
"description": "Query result column for the x axis, usually a time or category column, exactly as getExecutionResults returns it."
},
"sort_x": {
"type": "boolean",
"description": "Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order."
}
}
},
"y_axes": {
"type": "object",
"required": [
"left",
"right_enabled",
"right_label_format",
"right_series"
],
"properties": {
"left": {
"type": "object",
"required": [
"label_format",
"series"
],
"properties": {
"title": {
"type": "string",
"description": "Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Left Y axis series"
},
"tick_format": {
"type": "string",
"description": "Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"label_format": {
"type": "string",
"description": "Numeral.js format for tooltip and data-label values (e.g. 0,0 or $0.0a). Does not format axis ticks; use tick_format for that."
}
}
},
"right_title": {
"type": "string",
"description": "Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"right_series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Right Y axis series (empty if unused)"
},
"right_enabled": {
"type": "boolean",
"description": "Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it."
},
"right_tick_format": {
"type": "string",
"description": "Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"right_label_format": {
"type": "string",
"description": "Numeral.js format for right Y axis tooltip and data-label values (empty if unused). Does not format axis ticks; use right_tick_format for that."
}
}
},
"stacked": {
"type": "boolean",
"description": "Stack series"
},
"chart_type": {
"type": "string",
"const": "column",
"description": "Must match chartType"
},
"enable_legend": {
"type": "boolean",
"description": "Show legend"
},
"group_by_column": {
"type": "string",
"description": "Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series."
},
"when_duplicate_x": {
"enum": [
"first",
"sum",
"all"
],
"type": "string",
"description": "How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts."
},
"normalize_to_percentage": {
"type": "boolean",
"description": "Normalize each x value's series values to percentages of their total (e.g. 100%-stacked area charts). Pair with tick_format '0%'. Defaults to false."
}
}
},
{
"type": "object",
"required": [
"x_axis",
"y_axes",
"enable_legend",
"stacked",
"chart_type"
],
"properties": {
"x_axis": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Label shown under the x axis. Use an empty string for none."
},
"column": {
"type": "string",
"description": "Query result column for the x axis, usually a time or category column, exactly as getExecutionResults returns it."
},
"sort_x": {
"type": "boolean",
"description": "Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order."
}
}
},
"y_axes": {
"type": "object",
"required": [
"left",
"right_enabled",
"right_label_format",
"right_series"
],
"properties": {
"left": {
"type": "object",
"required": [
"label_format",
"series"
],
"properties": {
"title": {
"type": "string",
"description": "Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Left Y axis series"
},
"tick_format": {
"type": "string",
"description": "Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"label_format": {
"type": "string",
"description": "Numeral.js format for tooltip and data-label values (e.g. 0,0 or $0.0a). Does not format axis ticks; use tick_format for that."
}
}
},
"right_title": {
"type": "string",
"description": "Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"right_series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Right Y axis series (empty if unused)"
},
"right_enabled": {
"type": "boolean",
"description": "Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it."
},
"right_tick_format": {
"type": "string",
"description": "Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"right_label_format": {
"type": "string",
"description": "Numeral.js format for right Y axis tooltip and data-label values (empty if unused). Does not format axis ticks; use right_tick_format for that."
}
}
},
"stacked": {
"type": "boolean",
"description": "Stack series"
},
"chart_type": {
"type": "string",
"const": "line",
"description": "Must match chartType"
},
"enable_legend": {
"type": "boolean",
"description": "Show legend"
},
"group_by_column": {
"type": "string",
"description": "Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series."
},
"when_duplicate_x": {
"enum": [
"first",
"sum",
"all"
],
"type": "string",
"description": "How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts."
},
"normalize_to_percentage": {
"type": "boolean",
"description": "Normalize each x value's series values to percentages of their total (e.g. 100%-stacked area charts). Pair with tick_format '0%'. Defaults to false."
}
}
},
{
"type": "object",
"required": [
"x_axis",
"y_axes",
"enable_legend",
"stacked",
"chart_type"
],
"properties": {
"x_axis": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Label shown under the x axis. Use an empty string for none."
},
"column": {
"type": "string",
"description": "Query result column for the x axis, usually a time or category column, exactly as getExecutionResults returns it."
},
"sort_x": {
"type": "boolean",
"description": "Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order."
}
}
},
"y_axes": {
"type": "object",
"required": [
"left",
"right_enabled",
"right_label_format",
"right_series"
],
"properties": {
"left": {
"type": "object",
"required": [
"label_format",
"series"
],
"properties": {
"title": {
"type": "string",
"description": "Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Left Y axis series"
},
"tick_format": {
"type": "string",
"description": "Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"label_format": {
"type": "string",
"description": "Numeral.js format for tooltip and data-label values (e.g. 0,0 or $0.0a). Does not format axis ticks; use tick_format for that."
}
}
},
"right_title": {
"type": "string",
"description": "Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"right_series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Right Y axis series (empty if unused)"
},
"right_enabled": {
"type": "boolean",
"description": "Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it."
},
"right_tick_format": {
"type": "string",
"description": "Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"right_label_format": {
"type": "string",
"description": "Numeral.js format for right Y axis tooltip and data-label values (empty if unused). Does not format axis ticks; use right_tick_format for that."
}
}
},
"stacked": {
"type": "boolean",
"description": "Stack series"
},
"chart_type": {
"type": "string",
"const": "area",
"description": "Must match chartType"
},
"enable_legend": {
"type": "boolean",
"description": "Show legend"
},
"group_by_column": {
"type": "string",
"description": "Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series."
},
"when_duplicate_x": {
"enum": [
"first",
"sum",
"all"
],
"type": "string",
"description": "How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts."
},
"normalize_to_percentage": {
"type": "boolean",
"description": "Normalize each x value's series values to percentages of their total (e.g. 100%-stacked area charts). Pair with tick_format '0%'. Defaults to false."
}
}
},
{
"type": "object",
"required": [
"x_axis",
"y_axes",
"enable_legend",
"stacked",
"chart_type"
],
"properties": {
"x_axis": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Label shown under the x axis. Use an empty string for none."
},
"column": {
"type": "string",
"description": "Query result column for the x axis, usually a time or category column, exactly as getExecutionResults returns it."
},
"sort_x": {
"type": "boolean",
"description": "Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order."
}
}
},
"y_axes": {
"type": "object",
"required": [
"left",
"right_enabled",
"right_label_format",
"right_series"
],
"properties": {
"left": {
"type": "object",
"required": [
"label_format",
"series"
],
"properties": {
"title": {
"type": "string",
"description": "Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Left Y axis series"
},
"tick_format": {
"type": "string",
"description": "Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"label_format": {
"type": "string",
"description": "Numeral.js format for tooltip and data-label values (e.g. 0,0 or $0.0a). Does not format axis ticks; use tick_format for that."
}
}
},
"right_title": {
"type": "string",
"description": "Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"right_series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Right Y axis series (empty if unused)"
},
"right_enabled": {
"type": "boolean",
"description": "Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it."
},
"right_tick_format": {
"type": "string",
"description": "Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"right_label_format": {
"type": "string",
"description": "Numeral.js format for right Y axis tooltip and data-label values (empty if unused). Does not format axis ticks; use right_tick_format for that."
}
}
},
"stacked": {
"type": "boolean",
"description": "Stack series"
},
"chart_type": {
"type": "string",
"const": "scatter",
"description": "Must match chartType"
},
"enable_legend": {
"type": "boolean",
"description": "Show legend"
},
"group_by_column": {
"type": "string",
"description": "Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series."
},
"when_duplicate_x": {
"enum": [
"first",
"sum",
"all"
],
"type": "string",
"description": "How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts."
},
"normalize_to_percentage": {
"type": "boolean",
"description": "Normalize each x value's series values to percentages of their total (e.g. 100%-stacked area charts). Pair with tick_format '0%'. Defaults to false."
}
}
},
{
"type": "object",
"required": [
"chart_type",
"x_axis_column",
"y_axis_column",
"y_axis_title",
"y_axis_label_format",
"show_labels"
],
"properties": {
"chart_type": {
"type": "string",
"const": "pie",
"description": "Must match chartType"
},
"show_labels": {
"type": "boolean",
"description": "Show value labels on slices"
},
"y_axis_title": {
"type": "string",
"description": "Label for values"
},
"enable_legend": {
"type": "boolean",
"default": true,
"description": "Show legend."
},
"x_axis_column": {
"type": "string",
"description": "Column for pie slices"
},
"y_axis_column": {
"type": "string",
"description": "Column for slice values"
},
"y_axis_label_format": {
"type": "string",
"description": "Numeral.js format for values"
}
}
},
{
"type": "object",
"required": [
"chart_type",
"column",
"row_num",
"decimal_places",
"prefix",
"suffix",
"label",
"color_positive",
"color_negative"
],
"properties": {
"label": {
"type": "string",
"description": "Label describing the value"
},
"column": {
"type": "string",
"description": "Column to display"
},
"prefix": {
"type": "string",
"description": "Prefix (e.g. $) or empty"
},
"suffix": {
"type": "string",
"description": "Suffix (e.g. ETH, %) or empty"
},
"row_num": {
"type": "number",
"description": "Row index (1-based)"
},
"chart_type": {
"type": "string",
"const": "counter",
"description": "Must match chartType"
},
"color_negative": {
"type": "boolean",
"description": "Color negatives red"
},
"color_positive": {
"type": "boolean",
"description": "Color positives green"
},
"decimal_places": {
"type": "number",
"description": "Decimal places used to format the counter"
}
}
},
{
"type": "object",
"required": [
"chart_type",
"columns"
],
"properties": {
"columns": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"title",
"column_type",
"data_type",
"align",
"is_hidden",
"color_positive",
"color_negative",
"number_format"
],
"properties": {
"name": {
"type": "string",
"description": "Column name from query"
},
"align": {
"enum": [
"left",
"right",
"center"
],
"type": "string",
"description": "Text alignment"
},
"title": {
"type": "string",
"description": "Display title"
},
"data_type": {
"enum": [
"numeric",
"string",
"date"
],
"type": "string",
"description": "Data type for formatting"
},
"is_hidden": {
"type": "boolean",
"description": "Hide this column"
},
"column_type": {
"enum": [
"normal",
"progressbar"
],
"type": "string",
"description": "Display type"
},
"number_format": {
"type": [
"string",
"null"
],
"description": "Numeral.js format for numeric columns"
},
"color_negative": {
"type": [
"boolean",
"null"
],
"description": "Color negatives red"
},
"color_positive": {
"type": [
"boolean",
"null"
],
"description": "Color positives green"
}
}
},
"description": "Column configurations"
},
"chart_type": {
"type": "string",
"const": "table",
"description": "Must match chartType"
}
}
}
],
"description": "Chart configuration object; must match chartType"
},
"queryId": {
"type": "number",
"description": "The query ID to create a visualization for."
},
"chartType": {
"enum": [
"column",
"line",
"area",
"scatter",
"pie",
"counter",
"table"
],
"type": "string",
"description": "Chart type to create. Must be one of: column, line, area, scatter, pie, counter, table."
},
"visualizationName": {
"type": "string",
"description": "Name for the visualization (e.g., 'Daily DEX Volume', 'Top 10 Wallets by Balance')."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"queryId",
"visualizationId",
"chartType",
"visualizationType",
"visualizationName",
"isPrivate",
"interactiveChartUrl",
"chartJpegUrl"
],
"properties": {
"queryId": {
"type": "number",
"description": "The query ID the visualization was created for."
},
"chartType": {
"type": "string",
"description": "The chart type used for the visualization."
},
"isPrivate": {
"type": "boolean",
"description": "Whether the underlying query is private."
},
"chartJpegUrl": {
"type": "string",
"description": "Static JPEG chart image URL suitable for inline preview in chat. This points to https://core-api.dune.com/public/screenshot with the interactive chart URL passed as the encoded `url` query parameter."
},
"visualizationId": {
"type": "number",
"description": "The ID of the created visualization."
},
"visualizationName": {
"type": "string",
"description": "The name of the visualization."
},
"visualizationType": {
"type": "string",
"description": "The DB visualization type: 'chart' (for column/line/area/scatter/pie), 'counter', or 'table'."
},
"interactiveChartUrl": {
"type": "string",
"description": "Interactive chart page URL that renders only this visualization. For private queries, the URL format is /embeds/<query_id>/<visualization_id>/<api_key>."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Fetch a single visualization by ID. Returns the visualization metadata, chart options, and embed URLs.
Use this tool to inspect an existing chart before deciding to update or replace it.
The response includes both a chartType field (LLM-friendly: column, line, area, scatter, pie, counter, table) and the raw Dune options. When calling updateVisualization, use the chartType value. Do not reuse the raw options object as the config parameter.
Agent display instructions:
- If your client supports markdown images, render chartJpegUrl inline using markdown image syntax.
- Always include interactiveChartUrl as a clickable link so users can open and interact with the chart.
- If inline image rendering is not supported, provide both URLs as plain links.
- For private queries, embed URLs contain an API key segment and should be treated as sensitive.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
visualizationId
The ID of the visualization to retrieve.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"id",
"queryId",
"type",
"chartType",
"name",
"options",
"createdAt",
"updatedAt",
"isPrivate",
"interactiveChartUrl",
"chartJpegUrl"
],
"properties": {
"id": {
"type": "number",
"description": "The visualization ID."
},
"name": {
"type": "string",
"description": "The visualization name."
},
"type": {
"type": "string",
"description": "The DB visualization type: 'chart', 'counter', or 'table'."
},
"options": {
"type": "object",
"description": "The raw Dune visualization options. For reference only — do NOT pass this as the config parameter to updateVisualization.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"queryId": {
"type": "number",
"description": "The query ID this visualization belongs to."
},
"chartType": {
"type": "string",
"description": "The chart type in LLM-friendly format: column, line, area, scatter, pie, counter, or table. Use this value when calling updateVisualization."
},
"createdAt": {
"type": "string",
"description": "ISO timestamp of creation."
},
"isPrivate": {
"type": "boolean",
"description": "Whether the underlying query is private."
},
"updatedAt": {
"type": "string",
"description": "ISO timestamp of last update."
},
"chartJpegUrl": {
"type": "string",
"description": "Static JPEG chart image URL suitable for inline preview or markdown image rendering in chat."
},
"interactiveChartUrl": {
"type": "string",
"description": "Interactive chart page URL for this visualization. Use this as the clickable link for chart exploration. For private queries, the URL may include an API-keyed embed segment and should be treated as sensitive."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "getVisualization",
"title": "Get Visualization",
"description": "Fetch a single visualization by ID. Returns the visualization metadata, chart options, and embed URLs.\n\nUse this tool to inspect an existing chart before deciding to update or replace it.\n\nThe response includes both a chartType field (LLM-friendly: column, line, area, scatter, pie, counter, table) and the raw Dune options. When calling updateVisualization, use the chartType value. Do not reuse the raw options object as the config parameter.\n\nAgent display instructions:\n- If your client supports markdown images, render chartJpegUrl inline using markdown image syntax.\n- Always include interactiveChartUrl as a clickable link so users can open and interact with the chart.\n- If inline image rendering is not supported, provide both URLs as plain links.\n- For private queries, embed URLs contain an API key segment and should be treated as sensitive.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"visualizationId"
],
"properties": {
"visualizationId": {
"type": "number",
"description": "The ID of the visualization to retrieve."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"id",
"queryId",
"type",
"chartType",
"name",
"options",
"createdAt",
"updatedAt",
"isPrivate",
"interactiveChartUrl",
"chartJpegUrl"
],
"properties": {
"id": {
"type": "number",
"description": "The visualization ID."
},
"name": {
"type": "string",
"description": "The visualization name."
},
"type": {
"type": "string",
"description": "The DB visualization type: 'chart', 'counter', or 'table'."
},
"options": {
"type": "object",
"description": "The raw Dune visualization options. For reference only — do NOT pass this as the config parameter to updateVisualization.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"queryId": {
"type": "number",
"description": "The query ID this visualization belongs to."
},
"chartType": {
"type": "string",
"description": "The chart type in LLM-friendly format: column, line, area, scatter, pie, counter, or table. Use this value when calling updateVisualization."
},
"createdAt": {
"type": "string",
"description": "ISO timestamp of creation."
},
"isPrivate": {
"type": "boolean",
"description": "Whether the underlying query is private."
},
"updatedAt": {
"type": "string",
"description": "ISO timestamp of last update."
},
"chartJpegUrl": {
"type": "string",
"description": "Static JPEG chart image URL suitable for inline preview or markdown image rendering in chat."
},
"interactiveChartUrl": {
"type": "string",
"description": "Interactive chart page URL for this visualization. Use this as the clickable link for chart exploration. For private queries, the URL may include an API-keyed embed segment and should be treated as sensitive."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
List all visualizations attached to a query.
Use this tool to discover what charts, tables, and counters already exist for a query before creating new ones.
Each result includes the visualization ID, name, type, and timestamps. Use getVisualization with a specific ID to fetch full details including chart options and embed URLs.
The description explains the capability, when to use it, and what to expect.
Inputs81/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
queryId
The query ID to list visualizations for.
Clear enough to supply this argument.
limit
Maximum number of visualizations to return (default 25, max 100).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
offset
Offset for pagination.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description84/100
Update an existing visualization's name, chart type, and/or chart configuration.
Workflow: inspect the current state with getVisualization, then pass only the fields you want to change. Provide visualizationName, or chartType and config together, or both.
Important:
- config uses the same LLM-friendly format as generateVisualization (x_axis, y_axes, chart_type), not the raw Dune options that getVisualization returns. Build it from the query columns (inspect them with getExecutionResults); column names must exactly match the query output.
- config.chart_type must match chartType.
- When the chart type stays the same, options the config does not cover (such as custom colors) are kept; changing the chart type rebuilds options from the config alone.
Chart types: column, line, area, scatter, pie, counter, table.
Number formats (Numeral.js): 0, 0,0, 0,0.00, 0.0a, $0.0a (currency only), 0%.
Formatting: label_format formats tooltip and data-label values; tick_format / right_tick_format format the y-axis tick labels. Set both for percentage or currency charts.
Duplicate x values: stacked charts keep only the first row per x value within a series by default; set when_duplicate_x 'sum' when the query can return several rows per x value. normalize_to_percentage shows each x value's series as shares of 100% (pair with tick_format '0%').
Grouped 2D charts: for long-form results such as date, protocol, volume_usd, put the category column in config.group_by_column and use one left y-axis value series.
Dual Y-axis: only line and area charts support a right axis. Column and scatter charts put all series on the left axis.
Agent display instructions:
- Render chartJpegUrl inline as a markdown image if your client supports it; otherwise give it as a link.
- Always include interactiveChartUrl as a clickable link.
- For private queries, the embed URL contains an API key. Treat those links as sensitive and do not share them outside the current user context.
The description explains the capability, when to use it, and what to expect.
Inputs86/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
visualizationId
The ID of the visualization to update.
Clear enough to supply this argument.
visualizationName
New display name, shown as the widget title on dashboards. Omit to keep the current name.
Clear enough to supply this argument.
chartType
New chart type. Must be provided together with config.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 0 › x_axis › column
Query result column for the x axis, usually a time or category column, exactly as getExecutionResults returns it.
Clear enough to supply this argument.
config › oneOf › 0 › x_axis › title
Label shown under the x axis. Use an empty string for none.
Clear enough to supply this argument.
config › oneOf › 0 › x_axis › sort_x
Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order.
Clear enough to supply this argument.
config › oneOf › 0 › y_axes › left › label_format
Numeral.js format for tooltip and data-label values (e.g. 0,0 or $0.0a). Does not format axis ticks; use tick_format for that.
Clear enough to supply this argument.
config › oneOf › 0 › y_axes › left › tick_format
Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Clear enough to supply this argument.
config › oneOf › 0 › y_axes › left › title
Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Clear enough to supply this argument.
config › oneOf › 0 › y_axes › left › series › items › column
Name of the numeric query result column to plot, exactly as getExecutionResults returns it.
Clear enough to supply this argument.
config › oneOf › 0 › y_axes › left › series › items › title
Name shown for this series in the legend and tooltip.
Clear enough to supply this argument.
config › oneOf › 0 › y_axes › right_enabled
Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it.
Clear enough to supply this argument.
config › oneOf › 0 › y_axes › right_label_format
Numeral.js format for right Y axis tooltip and data-label values (empty if unused). Does not format axis ticks; use right_tick_format for that.
Clear enough to supply this argument.
config › oneOf › 0 › y_axes › right_tick_format
Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Clear enough to supply this argument.
config › oneOf › 0 › y_axes › right_title
Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Name shown for this series in the legend and tooltip.
Clear enough to supply this argument.
config › oneOf › 0 › group_by_column
Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series.
Clear enough to supply this argument.
config › oneOf › 0 › enable_legend
Show legend
Clear enough to supply this argument.
config › oneOf › 0 › stacked
Stack series
Clear enough to supply this argument.
config › oneOf › 0 › when_duplicate_x
How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts.
Clear enough to supply this argument.
config › oneOf › 0 › normalize_to_percentage
Normalize each x value's series values to percentages of their total (e.g. 100%-stacked area charts). Pair with tick_format '0%'. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 0 › chart_type
Must match chartType
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 1 › x_axis › column
Query result column for the x axis, usually a time or category column, exactly as getExecutionResults returns it.
Clear enough to supply this argument.
config › oneOf › 1 › x_axis › title
Label shown under the x axis. Use an empty string for none.
Clear enough to supply this argument.
config › oneOf › 1 › x_axis › sort_x
Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order.
Clear enough to supply this argument.
config › oneOf › 1 › y_axes › left › label_format
Numeral.js format for tooltip and data-label values (e.g. 0,0 or $0.0a). Does not format axis ticks; use tick_format for that.
Clear enough to supply this argument.
config › oneOf › 1 › y_axes › left › tick_format
Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Clear enough to supply this argument.
config › oneOf › 1 › y_axes › left › title
Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Clear enough to supply this argument.
config › oneOf › 1 › y_axes › left › series › items › column
Name of the numeric query result column to plot, exactly as getExecutionResults returns it.
Clear enough to supply this argument.
config › oneOf › 1 › y_axes › left › series › items › title
Name shown for this series in the legend and tooltip.
Clear enough to supply this argument.
config › oneOf › 1 › y_axes › right_enabled
Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it.
Clear enough to supply this argument.
config › oneOf › 1 › y_axes › right_label_format
Numeral.js format for right Y axis tooltip and data-label values (empty if unused). Does not format axis ticks; use right_tick_format for that.
Clear enough to supply this argument.
config › oneOf › 1 › y_axes › right_tick_format
Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Clear enough to supply this argument.
config › oneOf › 1 › y_axes › right_title
Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Name shown for this series in the legend and tooltip.
Clear enough to supply this argument.
config › oneOf › 1 › group_by_column
Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series.
Clear enough to supply this argument.
config › oneOf › 1 › enable_legend
Show legend
Clear enough to supply this argument.
config › oneOf › 1 › stacked
Stack series
Clear enough to supply this argument.
config › oneOf › 1 › when_duplicate_x
How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts.
Clear enough to supply this argument.
config › oneOf › 1 › normalize_to_percentage
Normalize each x value's series values to percentages of their total (e.g. 100%-stacked area charts). Pair with tick_format '0%'. Defaults to false.
Clear enough to supply this argument.
config › oneOf › 1 › chart_type
Must match chartType
Clear enough to supply this argument.
config › oneOf › 2 › x_axis › column
Query result column for the x axis, usually a time or category column, exactly as getExecutionResults returns it.
Clear enough to supply this argument.
config › oneOf › 2 › x_axis › title
Label shown under the x axis. Use an empty string for none.
Clear enough to supply this argument.
config › oneOf › 2 › x_axis › sort_x
Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order.
Clear enough to supply this argument.
config › oneOf › 2 › y_axes › left › label_format
Numeral.js format for tooltip and data-label values (e.g. 0,0 or $0.0a). Does not format axis ticks; use tick_format for that.
Clear enough to supply this argument.
config › oneOf › 2 › y_axes › left › tick_format
Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Clear enough to supply this argument.
config › oneOf › 2 › y_axes › left › title
Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Clear enough to supply this argument.
config › oneOf › 2 › y_axes › left › series › items › column
Name of the numeric query result column to plot, exactly as getExecutionResults returns it.
Clear enough to supply this argument.
config › oneOf › 2 › y_axes › left › series › items › title
Name shown for this series in the legend and tooltip.
Clear enough to supply this argument.
config › oneOf › 2 › y_axes › right_enabled
Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › y_axes › right_label_format
Numeral.js format for right Y axis tooltip and data-label values (empty if unused). Does not format axis ticks; use right_tick_format for that.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › y_axes › right_tick_format
Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › y_axes › right_title
Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Name shown for this series in the legend and tooltip.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › group_by_column
Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › enable_legend
Show legend
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › stacked
Stack series
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › when_duplicate_x
How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › normalize_to_percentage
Normalize each x value's series values to percentages of their total (e.g. 100%-stacked area charts). Pair with tick_format '0%'. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 2 › chart_type
Must match chartType
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › x_axis › column
Query result column for the x axis, usually a time or category column, exactly as getExecutionResults returns it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › x_axis › title
Label shown under the x axis. Use an empty string for none.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › x_axis › sort_x
Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › y_axes › left › label_format
Numeral.js format for tooltip and data-label values (e.g. 0,0 or $0.0a). Does not format axis ticks; use tick_format for that.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › y_axes › left › tick_format
Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › y_axes › left › title
Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › y_axes › left › series › items › column
Name of the numeric query result column to plot, exactly as getExecutionResults returns it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › y_axes › left › series › items › title
Name shown for this series in the legend and tooltip.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › y_axes › right_enabled
Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › y_axes › right_label_format
Numeral.js format for right Y axis tooltip and data-label values (empty if unused). Does not format axis ticks; use right_tick_format for that.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › y_axes › right_tick_format
Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › y_axes › right_title
Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Name shown for this series in the legend and tooltip.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › group_by_column
Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › enable_legend
Show legend
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › stacked
Stack series
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › when_duplicate_x
How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › normalize_to_percentage
Normalize each x value's series values to percentages of their total (e.g. 100%-stacked area charts). Pair with tick_format '0%'. Defaults to false.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 3 › chart_type
Must match chartType
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 4 › chart_type
Must match chartType
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 4 › x_axis_column
Column for pie slices
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 4 › y_axis_column
Column for slice values
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 4 › y_axis_title
Label for values
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 4 › y_axis_label_format
Numeral.js format for values
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 4 › enable_legend
Show legend.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 4 › show_labels
Show value labels on slices
Explain the meaning of this value, not just its name.
config › oneOf › 5 › chart_type
Must match chartType
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 5 › column
Column to display
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 5 › row_num
Row index (1-based)
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 5 › decimal_places
Decimal places used to format the counter
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 5 › prefix
Prefix (e.g. $) or empty
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 5 › suffix
Suffix (e.g. ETH, %) or empty
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 5 › label
Label describing the value
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 5 › color_positive
Color positives green
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 5 › color_negative
Color negatives red
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 6 › chart_type
Must match chartType
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 6 › columns › items › name
Column name from query
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
config › oneOf › 6 › columns › items › title
Display title
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"visualizationId",
"queryId",
"chartType",
"visualizationType",
"visualizationName",
"isPrivate",
"interactiveChartUrl",
"chartJpegUrl"
],
"properties": {
"queryId": {
"type": "number",
"description": "The query ID this visualization belongs to."
},
"chartType": {
"type": "string",
"description": "The current chart type."
},
"isPrivate": {
"type": "boolean",
"description": "Whether the underlying query is private."
},
"chartJpegUrl": {
"type": "string",
"description": "Static JPEG chart image URL for inline preview."
},
"visualizationId": {
"type": "number",
"description": "The updated visualization ID."
},
"visualizationName": {
"type": "string",
"description": "The current visualization name."
},
"visualizationType": {
"type": "string",
"description": "The DB visualization type: 'chart', 'counter', or 'table'."
},
"interactiveChartUrl": {
"type": "string",
"description": "Interactive chart page URL for this visualization."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "updateVisualization",
"title": "Update Visualization",
"description": "Update an existing visualization's name, chart type, and/or chart configuration.\n\nWorkflow: inspect the current state with getVisualization, then pass only the fields you want to change. Provide visualizationName, or chartType and config together, or both.\n\nImportant:\n- config uses the same LLM-friendly format as generateVisualization (x_axis, y_axes, chart_type), not the raw Dune options that getVisualization returns. Build it from the query columns (inspect them with getExecutionResults); column names must exactly match the query output.\n- config.chart_type must match chartType.\n- When the chart type stays the same, options the config does not cover (such as custom colors) are kept; changing the chart type rebuilds options from the config alone.\n\nChart types: column, line, area, scatter, pie, counter, table.\nNumber formats (Numeral.js): 0, 0,0, 0,0.00, 0.0a, $0.0a (currency only), 0%.\nFormatting: label_format formats tooltip and data-label values; tick_format / right_tick_format format the y-axis tick labels. Set both for percentage or currency charts.\nDuplicate x values: stacked charts keep only the first row per x value within a series by default; set when_duplicate_x 'sum' when the query can return several rows per x value. normalize_to_percentage shows each x value's series as shares of 100% (pair with tick_format '0%').\nGrouped 2D charts: for long-form results such as date, protocol, volume_usd, put the category column in config.group_by_column and use one left y-axis value series.\nDual Y-axis: only line and area charts support a right axis. Column and scatter charts put all series on the left axis.\n\nAgent display instructions:\n- Render chartJpegUrl inline as a markdown image if your client supports it; otherwise give it as a link.\n- Always include interactiveChartUrl as a clickable link.\n- For private queries, the embed URL contains an API key. Treat those links as sensitive and do not share them outside the current user context.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"visualizationId"
],
"properties": {
"config": {
"oneOf": [
{
"type": "object",
"required": [
"x_axis",
"y_axes",
"enable_legend",
"stacked",
"chart_type"
],
"properties": {
"x_axis": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Label shown under the x axis. Use an empty string for none."
},
"column": {
"type": "string",
"description": "Query result column for the x axis, usually a time or category column, exactly as getExecutionResults returns it."
},
"sort_x": {
"type": "boolean",
"description": "Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order."
}
}
},
"y_axes": {
"type": "object",
"required": [
"left",
"right_enabled",
"right_label_format",
"right_series"
],
"properties": {
"left": {
"type": "object",
"required": [
"label_format",
"series"
],
"properties": {
"title": {
"type": "string",
"description": "Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Left Y axis series"
},
"tick_format": {
"type": "string",
"description": "Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"label_format": {
"type": "string",
"description": "Numeral.js format for tooltip and data-label values (e.g. 0,0 or $0.0a). Does not format axis ticks; use tick_format for that."
}
}
},
"right_title": {
"type": "string",
"description": "Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"right_series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Right Y axis series (empty if unused)"
},
"right_enabled": {
"type": "boolean",
"description": "Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it."
},
"right_tick_format": {
"type": "string",
"description": "Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"right_label_format": {
"type": "string",
"description": "Numeral.js format for right Y axis tooltip and data-label values (empty if unused). Does not format axis ticks; use right_tick_format for that."
}
}
},
"stacked": {
"type": "boolean",
"description": "Stack series"
},
"chart_type": {
"type": "string",
"const": "column",
"description": "Must match chartType"
},
"enable_legend": {
"type": "boolean",
"description": "Show legend"
},
"group_by_column": {
"type": "string",
"description": "Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series."
},
"when_duplicate_x": {
"enum": [
"first",
"sum",
"all"
],
"type": "string",
"description": "How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts."
},
"normalize_to_percentage": {
"type": "boolean",
"description": "Normalize each x value's series values to percentages of their total (e.g. 100%-stacked area charts). Pair with tick_format '0%'. Defaults to false."
}
}
},
{
"type": "object",
"required": [
"x_axis",
"y_axes",
"enable_legend",
"stacked",
"chart_type"
],
"properties": {
"x_axis": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Label shown under the x axis. Use an empty string for none."
},
"column": {
"type": "string",
"description": "Query result column for the x axis, usually a time or category column, exactly as getExecutionResults returns it."
},
"sort_x": {
"type": "boolean",
"description": "Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order."
}
}
},
"y_axes": {
"type": "object",
"required": [
"left",
"right_enabled",
"right_label_format",
"right_series"
],
"properties": {
"left": {
"type": "object",
"required": [
"label_format",
"series"
],
"properties": {
"title": {
"type": "string",
"description": "Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Left Y axis series"
},
"tick_format": {
"type": "string",
"description": "Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"label_format": {
"type": "string",
"description": "Numeral.js format for tooltip and data-label values (e.g. 0,0 or $0.0a). Does not format axis ticks; use tick_format for that."
}
}
},
"right_title": {
"type": "string",
"description": "Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"right_series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Right Y axis series (empty if unused)"
},
"right_enabled": {
"type": "boolean",
"description": "Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it."
},
"right_tick_format": {
"type": "string",
"description": "Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"right_label_format": {
"type": "string",
"description": "Numeral.js format for right Y axis tooltip and data-label values (empty if unused). Does not format axis ticks; use right_tick_format for that."
}
}
},
"stacked": {
"type": "boolean",
"description": "Stack series"
},
"chart_type": {
"type": "string",
"const": "line",
"description": "Must match chartType"
},
"enable_legend": {
"type": "boolean",
"description": "Show legend"
},
"group_by_column": {
"type": "string",
"description": "Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series."
},
"when_duplicate_x": {
"enum": [
"first",
"sum",
"all"
],
"type": "string",
"description": "How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts."
},
"normalize_to_percentage": {
"type": "boolean",
"description": "Normalize each x value's series values to percentages of their total (e.g. 100%-stacked area charts). Pair with tick_format '0%'. Defaults to false."
}
}
},
{
"type": "object",
"required": [
"x_axis",
"y_axes",
"enable_legend",
"stacked",
"chart_type"
],
"properties": {
"x_axis": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Label shown under the x axis. Use an empty string for none."
},
"column": {
"type": "string",
"description": "Query result column for the x axis, usually a time or category column, exactly as getExecutionResults returns it."
},
"sort_x": {
"type": "boolean",
"description": "Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order."
}
}
},
"y_axes": {
"type": "object",
"required": [
"left",
"right_enabled",
"right_label_format",
"right_series"
],
"properties": {
"left": {
"type": "object",
"required": [
"label_format",
"series"
],
"properties": {
"title": {
"type": "string",
"description": "Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Left Y axis series"
},
"tick_format": {
"type": "string",
"description": "Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"label_format": {
"type": "string",
"description": "Numeral.js format for tooltip and data-label values (e.g. 0,0 or $0.0a). Does not format axis ticks; use tick_format for that."
}
}
},
"right_title": {
"type": "string",
"description": "Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"right_series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Right Y axis series (empty if unused)"
},
"right_enabled": {
"type": "boolean",
"description": "Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it."
},
"right_tick_format": {
"type": "string",
"description": "Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"right_label_format": {
"type": "string",
"description": "Numeral.js format for right Y axis tooltip and data-label values (empty if unused). Does not format axis ticks; use right_tick_format for that."
}
}
},
"stacked": {
"type": "boolean",
"description": "Stack series"
},
"chart_type": {
"type": "string",
"const": "area",
"description": "Must match chartType"
},
"enable_legend": {
"type": "boolean",
"description": "Show legend"
},
"group_by_column": {
"type": "string",
"description": "Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series."
},
"when_duplicate_x": {
"enum": [
"first",
"sum",
"all"
],
"type": "string",
"description": "How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts."
},
"normalize_to_percentage": {
"type": "boolean",
"description": "Normalize each x value's series values to percentages of their total (e.g. 100%-stacked area charts). Pair with tick_format '0%'. Defaults to false."
}
}
},
{
"type": "object",
"required": [
"x_axis",
"y_axes",
"enable_legend",
"stacked",
"chart_type"
],
"properties": {
"x_axis": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Label shown under the x axis. Use an empty string for none."
},
"column": {
"type": "string",
"description": "Query result column for the x axis, usually a time or category column, exactly as getExecutionResults returns it."
},
"sort_x": {
"type": "boolean",
"description": "Whether to sort x-axis values. Defaults to true (Dune's default), which sorts alphabetically for strings and chronologically for dates. Set false to preserve the query's row order, which matters for: (a) leaderboards ranked by value, (b) categorical x-axes where alphabetical sort reorders meaningfully (e.g. ['Jan','Feb','Mar'] becomes ['Feb','Jan','Mar']), (c) any query using ORDER BY to control display order."
}
}
},
"y_axes": {
"type": "object",
"required": [
"left",
"right_enabled",
"right_label_format",
"right_series"
],
"properties": {
"left": {
"type": "object",
"required": [
"label_format",
"series"
],
"properties": {
"title": {
"type": "string",
"description": "Title shown on the left y-axis (e.g. 'USD volume', 'Transactions'). This is the axis label, not a series legend entry. Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Left Y axis series"
},
"tick_format": {
"type": "string",
"description": "Numeral.js format for left y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"label_format": {
"type": "string",
"description": "Numeral.js format for tooltip and data-label values (e.g. 0,0 or $0.0a). Does not format axis ticks; use tick_format for that."
}
}
},
"right_title": {
"type": "string",
"description": "Title shown on the right y-axis (when enabled). Omit for no title on create; on update, omitting keeps the current title — pass an empty string to remove it."
},
"right_series": {
"type": "array",
"items": {
"type": "object",
"required": [
"column",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Name shown for this series in the legend and tooltip."
},
"column": {
"type": "string",
"description": "Name of the numeric query result column to plot, exactly as getExecutionResults returns it."
}
}
},
"description": "Right Y axis series (empty if unused)"
},
"right_enabled": {
"type": "boolean",
"description": "Set true to plot right_series on a second y axis with its own scale, for series with very different magnitudes (e.g. volume and price). Only line and area charts support it."
},
"right_tick_format": {
"type": "string",
"description": "Numeral.js format for right y-axis tick labels (e.g. 0% or $0.0a). Omit for automatic formatting on create; on update, omitting keeps the current tick format — pass an empty string to reset to automatic."
},
"right_label_format": {
"type": "string",
"description": "Numeral.js format for right Y axis tooltip and data-label values (empty if unused). Does not format axis ticks; use right_tick_format for that."
}
}
},
"stacked": {
"type": "boolean",
"description": "Stack series"
},
"chart_type": {
"type": "string",
"const": "scatter",
"description": "Must match chartType"
},
"enable_legend": {
"type": "boolean",
"description": "Show legend"
},
"group_by_column": {
"type": "string",
"description": "Column whose distinct values become chart series. Use this when you have a column that classifies a rowinto a group and you want all of the rows in that group to render as a single series.For example you might have a timeseries chart of daily volumes and in one column you specifythe blockchain in which the volume was transacted. If you set group_by_column to blockchain,then all of the rows with the same blockchain will be grouped together and rendered as a single series."
},
"when_duplicate_x": {
"enum": [
"first",
"sum",
"all"
],
"type": "string",
"description": "How to handle multiple rows with the same x value within a series: 'first' keeps only the first row, 'sum' adds them up, 'all' plots every row. Defaults to 'first' for stacked charts (silently dropping duplicates) and 'all' otherwise. Set 'sum' when the query can return several rows per x value. 'all' is not supported for stacked charts."
},
"normalize_to_percentage": {
"type": "boolean",
"description": "Normalize each x value's series values to percentages of their total (e.g. 100%-stacked area charts). Pair with tick_format '0%'. Defaults to false."
}
}
},
{
"type": "object",
"required": [
"chart_type",
"x_axis_column",
"y_axis_column",
"y_axis_title",
"y_axis_label_format",
"show_labels"
],
"properties": {
"chart_type": {
"type": "string",
"const": "pie",
"description": "Must match chartType"
},
"show_labels": {
"type": "boolean",
"description": "Show value labels on slices"
},
"y_axis_title": {
"type": "string",
"description": "Label for values"
},
"enable_legend": {
"type": "boolean",
"default": true,
"description": "Show legend."
},
"x_axis_column": {
"type": "string",
"description": "Column for pie slices"
},
"y_axis_column": {
"type": "string",
"description": "Column for slice values"
},
"y_axis_label_format": {
"type": "string",
"description": "Numeral.js format for values"
}
}
},
{
"type": "object",
"required": [
"chart_type",
"column",
"row_num",
"decimal_places",
"prefix",
"suffix",
"label",
"color_positive",
"color_negative"
],
"properties": {
"label": {
"type": "string",
"description": "Label describing the value"
},
"column": {
"type": "string",
"description": "Column to display"
},
"prefix": {
"type": "string",
"description": "Prefix (e.g. $) or empty"
},
"suffix": {
"type": "string",
"description": "Suffix (e.g. ETH, %) or empty"
},
"row_num": {
"type": "number",
"description": "Row index (1-based)"
},
"chart_type": {
"type": "string",
"const": "counter",
"description": "Must match chartType"
},
"color_negative": {
"type": "boolean",
"description": "Color negatives red"
},
"color_positive": {
"type": "boolean",
"description": "Color positives green"
},
"decimal_places": {
"type": "number",
"description": "Decimal places used to format the counter"
}
}
},
{
"type": "object",
"required": [
"chart_type",
"columns"
],
"properties": {
"columns": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"title",
"column_type",
"data_type",
"align",
"is_hidden",
"color_positive",
"color_negative",
"number_format"
],
"properties": {
"name": {
"type": "string",
"description": "Column name from query"
},
"align": {
"enum": [
"left",
"right",
"center"
],
"type": "string",
"description": "Text alignment"
},
"title": {
"type": "string",
"description": "Display title"
},
"data_type": {
"enum": [
"numeric",
"string",
"date"
],
"type": "string",
"description": "Data type for formatting"
},
"is_hidden": {
"type": "boolean",
"description": "Hide this column"
},
"column_type": {
"enum": [
"normal",
"progressbar"
],
"type": "string",
"description": "Display type"
},
"number_format": {
"type": [
"string",
"null"
],
"description": "Numeral.js format for numeric columns"
},
"color_negative": {
"type": [
"boolean",
"null"
],
"description": "Color negatives red"
},
"color_positive": {
"type": [
"boolean",
"null"
],
"description": "Color positives green"
}
}
},
"description": "Column configurations"
},
"chart_type": {
"type": "string",
"const": "table",
"description": "Must match chartType"
}
}
}
],
"description": "New chart configuration. Must be provided together with chartType."
},
"chartType": {
"enum": [
"column",
"line",
"area",
"scatter",
"pie",
"counter",
"table"
],
"type": "string",
"description": "New chart type. Must be provided together with config."
},
"visualizationId": {
"type": "number",
"description": "The ID of the visualization to update."
},
"visualizationName": {
"type": "string",
"description": "New display name, shown as the widget title on dashboards. Omit to keep the current name."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"visualizationId",
"queryId",
"chartType",
"visualizationType",
"visualizationName",
"isPrivate",
"interactiveChartUrl",
"chartJpegUrl"
],
"properties": {
"queryId": {
"type": "number",
"description": "The query ID this visualization belongs to."
},
"chartType": {
"type": "string",
"description": "The current chart type."
},
"isPrivate": {
"type": "boolean",
"description": "Whether the underlying query is private."
},
"chartJpegUrl": {
"type": "string",
"description": "Static JPEG chart image URL for inline preview."
},
"visualizationId": {
"type": "number",
"description": "The updated visualization ID."
},
"visualizationName": {
"type": "string",
"description": "The current visualization name."
},
"visualizationType": {
"type": "string",
"description": "The DB visualization type: 'chart', 'counter', or 'table'."
},
"interactiveChartUrl": {
"type": "string",
"description": "Interactive chart page URL for this visualization."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description93/100
Delete a visualization by ID.
This permanently removes the visualization. If the visualization is featured on a team profile, it must be unfeatured first. If it is on a dashboard, remove it from the dashboard with updateDashboard first.
Use listQueryVisualizations to find visualization IDs for a given query.
The description explains the capability, when to use it, and what to expect.
Inputs81/100
Clarify ID sources, units, or usage conventions not already expressed in the schema.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"ok",
"visualizationId"
],
"properties": {
"ok": {
"type": "boolean",
"description": "Whether the deletion succeeded."
},
"visualizationId": {
"type": "number",
"description": "The ID of the deleted visualization."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "deleteVisualization",
"title": "Delete Visualization",
"description": "Delete a visualization by ID.\n\nThis permanently removes the visualization. If the visualization is featured on a team profile, it must be unfeatured first. If it is on a dashboard, remove it from the dashboard with updateDashboard first.\n\nUse listQueryVisualizations to find visualization IDs for a given query.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"visualizationId"
],
"properties": {
"visualizationId": {
"type": "number",
"description": "The ID of the visualization to delete."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"ok",
"visualizationId"
],
"properties": {
"ok": {
"type": "boolean",
"description": "Whether the deletion succeeded."
},
"visualizationId": {
"type": "number",
"description": "The ID of the deleted visualization."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Get the total storage size of a Dune table by analyzing its underlying physical tables. Returns the total size in bytes and GB, and the size of each underlying physical table. It does not return row counts or column details; use searchTables for the schema.
This tool:
1. Runs EXPLAIN directly on QES to discover underlying physical tables
2. Queries size metadata for each underlying table
3. Aggregates and returns total size information
Use this tool when you need to:
- Understand the storage footprint of a table or view
- Debug query performance (larger tables = longer scans)
- Plan capacity or estimate costs
- Investigate which underlying tables a view references
Note: Views and spells (like dex.trades) may have multiple underlying tables - all are summed.
The description explains the capability, when to use it, and what to expect.
Inputs98/100
Input documentation gives an agent enough context to populate the arguments.
table_name
Fully qualified table name. Use "schema.table" for standard datasets (e.g., "ethereum.transactions", "dex.trades") or "dune.schema.table" for dune catalog datasets (e.g., "dune.stablecore.stablecoins_evm_activity_enriched").
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"table_name",
"underlying_tables"
],
"properties": {
"warnings": {
"type": "array",
"items": {
"type": "string"
},
"description": "Any warnings encountered during execution."
},
"table_name": {
"type": "string",
"description": "The table name that was queried."
},
"total_size_gb": {
"type": "number",
"description": "Total size in GB across all underlying tables."
},
"total_size_bytes": {
"type": "number",
"description": "Total size in bytes across all underlying tables."
},
"underlying_tables": {
"type": "array",
"items": {
"type": "object",
"required": [
"table_name",
"schema",
"table"
],
"properties": {
"error": {
"type": "string",
"description": "Error message if size query failed."
},
"table": {
"type": "string",
"description": "Table name without schema."
},
"schema": {
"type": "string",
"description": "Schema name extracted from the table."
},
"catalog": {
"type": "string",
"description": "Catalog name if the table is qualified (e.g., \"dune\" for dune catalog datasets)."
},
"size_gb": {
"type": "number",
"description": "Size in GB if successfully retrieved."
},
"size_bytes": {
"type": "number",
"description": "Size in bytes if successfully retrieved."
},
"table_name": {
"type": "string",
"description": "Full table reference from the query plan."
}
},
"additionalProperties": false
},
"description": "Details for each underlying physical table."
},
"explain_execution_id": {
"type": "string",
"description": "Execution ID used for the EXPLAIN execution."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "getTableSize",
"title": "Get Table Size",
"description": "Get the total storage size of a Dune table by analyzing its underlying physical tables. Returns the total size in bytes and GB, and the size of each underlying physical table. It does not return row counts or column details; use searchTables for the schema.\n\nThis tool:\n1. Runs EXPLAIN directly on QES to discover underlying physical tables\n2. Queries size metadata for each underlying table\n3. Aggregates and returns total size information\n\nUse this tool when you need to:\n- Understand the storage footprint of a table or view\n- Debug query performance (larger tables = longer scans)\n- Plan capacity or estimate costs\n- Investigate which underlying tables a view references\n\nNote: Views and spells (like dex.trades) may have multiple underlying tables - all are summed.\n",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"table_name"
],
"properties": {
"table_name": {
"type": "string",
"description": "Fully qualified table name. Use \"schema.table\" for standard datasets (e.g., \"ethereum.transactions\", \"dex.trades\") or \"dune.schema.table\" for dune catalog datasets (e.g., \"dune.stablecore.stablecoins_evm_activity_enriched\")."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"table_name",
"underlying_tables"
],
"properties": {
"warnings": {
"type": "array",
"items": {
"type": "string"
},
"description": "Any warnings encountered during execution."
},
"table_name": {
"type": "string",
"description": "The table name that was queried."
},
"total_size_gb": {
"type": "number",
"description": "Total size in GB across all underlying tables."
},
"total_size_bytes": {
"type": "number",
"description": "Total size in bytes across all underlying tables."
},
"underlying_tables": {
"type": "array",
"items": {
"type": "object",
"required": [
"table_name",
"schema",
"table"
],
"properties": {
"error": {
"type": "string",
"description": "Error message if size query failed."
},
"table": {
"type": "string",
"description": "Table name without schema."
},
"schema": {
"type": "string",
"description": "Schema name extracted from the table."
},
"catalog": {
"type": "string",
"description": "Catalog name if the table is qualified (e.g., \"dune\" for dune catalog datasets)."
},
"size_gb": {
"type": "number",
"description": "Size in GB if successfully retrieved."
},
"size_bytes": {
"type": "number",
"description": "Size in bytes if successfully retrieved."
},
"table_name": {
"type": "string",
"description": "Full table reference from the query plan."
}
},
"additionalProperties": false
},
"description": "Details for each underlying physical table."
},
"explain_execution_id": {
"type": "string",
"description": "Execution ID used for the EXPLAIN execution."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description88/100
Create a Dune dashboard that bundles queries and visualizations into a shareable page. Use it whenever a user wants a dashboard or report for onchain data: DeFi, NFTs, DEX trading, token transfers, wallets, protocol metrics or gas, on Ethereum, Solana, Base and 20+ other chains.
This is the final assembly step. How to use it depends on what the user has already prepared:
Scenario 1: a dashboard from scratch.
1. Break the topic into 3-6 logical sections.
2. Find datasets with searchTables and searchTablesByContractAddress. Use searchDocs for DuneSQL syntax and functions.
3. Build the section queries with createDuneQuery.
4. Run each query with executeQueryById and check the results with getExecutionResults.
5. Create a chart for each query with generateVisualization.
6. Call this tool with the visualization IDs and any text widgets.
Scenario 2: queries and visualizations are ready. Pass the visualization IDs from earlier generateVisualization calls, and add text widgets for headers or descriptions.
Scenario 3: an empty dashboard to fill later. Call this tool with just a name.
Tips:
- Start with a text widget that has a title and a short description.
- Put counters for key metrics at the top and detailed charts below. The auto-layout places widgets in order, so group related ones.
- Add text widgets between sections to give context or explain the method.
Agent display instructions:
- Present dashboardUrl as a clickable "Powered by [Dune](dashboardUrl)" link so the user can open the full dashboard on Dune.
The description explains the capability, when to use it, and what to expect.
Inputs90/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
name
Display name for the dashboard (e.g., 'Ethereum DEX Overview', 'Top NFT Collections').
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
isPrivate
Whether the dashboard should be private. Defaults to false.
Clear enough to supply this argument.
visualizationIds
Array of visualization IDs to add to the dashboard. These come from generateVisualization output.
Clear enough to supply this argument.
textWidgets › items › text
Markdown text content for the widget.
Clear enough to supply this argument.
columnsPerRow
Number of visualization columns per row (1, 2, or 3). Defaults to 2. Use 1 for full-width detailed charts, 2 for balanced layout, 3 for compact overview.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"dashboardId",
"name",
"slug",
"isPrivate",
"tags",
"dashboardUrl",
"visualizationWidgets",
"textWidgets",
"paramWidgets"
],
"properties": {
"name": {
"type": "string",
"description": "The display name of the dashboard."
},
"slug": {
"type": "string",
"description": "The URL slug of the dashboard."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Tags applied to the dashboard."
},
"isPrivate": {
"type": "boolean",
"description": "Whether the dashboard is private."
},
"dashboardId": {
"type": "number",
"description": "The ID of the dashboard."
},
"textWidgets": {
"type": "array",
"items": {
"type": "object",
"required": [
"widgetId",
"text",
"position"
],
"properties": {
"text": {
"type": "string",
"description": "The markdown text content of the widget."
},
"position": {
"type": "object",
"required": [
"row",
"col",
"sizeX",
"sizeY"
],
"properties": {
"col": {
"type": "number",
"description": "Left edge, in grid columns from the left (0 to 5; the grid has 6 columns)."
},
"row": {
"type": "number",
"description": "Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px."
},
"sizeX": {
"type": "number",
"description": "Width in grid columns (1 to 6; 6 is the full width)."
},
"sizeY": {
"type": "number",
"description": "Height in grid rows. Charts are 8 rows high by default."
}
},
"description": "Position and size in the dashboard grid.",
"additionalProperties": false
},
"widgetId": {
"type": "number",
"description": "The widget ID on the dashboard."
}
},
"additionalProperties": false
},
"description": "Current text widgets on the dashboard with their content."
},
"dashboardUrl": {
"type": "string",
"description": "Full URL to the dashboard on dune.com."
},
"paramWidgets": {
"type": "array",
"items": {
"type": "object",
"required": [
"widgetId",
"key",
"queryId",
"visualizationWidgetId",
"position"
],
"properties": {
"key": {
"type": "string",
"description": "The parameter key name."
},
"queryId": {
"type": "number",
"description": "The query ID this parameter belongs to."
},
"position": {
"type": "object",
"required": [
"row",
"col",
"sizeX",
"sizeY"
],
"properties": {
"col": {
"type": "number",
"description": "Left edge, in grid columns from the left (0 to 5; the grid has 6 columns)."
},
"row": {
"type": "number",
"description": "Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px."
},
"sizeX": {
"type": "number",
"description": "Width in grid columns (1 to 6; 6 is the full width)."
},
"sizeY": {
"type": "number",
"description": "Height in grid rows. Charts are 8 rows high by default."
}
},
"description": "Position and size in the dashboard grid.",
"additionalProperties": false
},
"widgetId": {
"type": "string",
"description": "The param widget ID (UUID)."
},
"visualizationWidgetId": {
"type": "number",
"description": "The visualization widget ID this parameter is attached to."
}
},
"additionalProperties": false
},
"description": "Current parameter widgets on the dashboard. These are interactive controls (dropdowns, text inputs) for query parameters."
},
"visualizationWidgets": {
"type": "array",
"items": {
"type": "object",
"required": [
"widgetId",
"visualizationId",
"position"
],
"properties": {
"position": {
"type": "object",
"required": [
"row",
"col",
"sizeX",
"sizeY"
],
"properties": {
"col": {
"type": "number",
"description": "Left edge, in grid columns from the left (0 to 5; the grid has 6 columns)."
},
"row": {
"type": "number",
"description": "Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px."
},
"sizeX": {
"type": "number",
"description": "Width in grid columns (1 to 6; 6 is the full width)."
},
"sizeY": {
"type": "number",
"description": "Height in grid rows. Charts are 8 rows high by default."
}
},
"description": "Position and size in the dashboard grid.",
"additionalProperties": false
},
"widgetId": {
"type": "number",
"description": "The widget ID on the dashboard."
},
"visualizationId": {
"type": "number",
"description": "The visualization ID this widget displays."
}
},
"additionalProperties": false
},
"description": "Current visualization widgets on the dashboard."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "createDashboard",
"title": "Create Dashboard",
"description": "Create a Dune dashboard that bundles queries and visualizations into a shareable page. Use it whenever a user wants a dashboard or report for onchain data: DeFi, NFTs, DEX trading, token transfers, wallets, protocol metrics or gas, on Ethereum, Solana, Base and 20+ other chains.\n\nThis is the final assembly step. How to use it depends on what the user has already prepared:\n\nScenario 1: a dashboard from scratch.\n1. Break the topic into 3-6 logical sections.\n2. Find datasets with searchTables and searchTablesByContractAddress. Use searchDocs for DuneSQL syntax and functions.\n3. Build the section queries with createDuneQuery.\n4. Run each query with executeQueryById and check the results with getExecutionResults.\n5. Create a chart for each query with generateVisualization.\n6. Call this tool with the visualization IDs and any text widgets.\n\nScenario 2: queries and visualizations are ready. Pass the visualization IDs from earlier generateVisualization calls, and add text widgets for headers or descriptions.\n\nScenario 3: an empty dashboard to fill later. Call this tool with just a name.\n\nTips:\n- Start with a text widget that has a title and a short description.\n- Put counters for key metrics at the top and detailed charts below. The auto-layout places widgets in order, so group related ones.\n- Add text widgets between sections to give context or explain the method.\n\nAgent display instructions:\n- Present dashboardUrl as a clickable \"Powered by [Dune](dashboardUrl)\" link so the user can open the full dashboard on Dune.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "Display name for the dashboard (e.g., 'Ethereum DEX Overview', 'Top NFT Collections')."
},
"isPrivate": {
"type": "boolean",
"description": "Whether the dashboard should be private. Defaults to false."
},
"textWidgets": {
"type": "array",
"items": {
"type": "object",
"required": [
"text"
],
"properties": {
"text": {
"type": "string",
"description": "Markdown text content for the widget."
}
}
},
"description": "Array of text widgets with markdown content. Placed at full width above visualizations."
},
"columnsPerRow": {
"type": "integer",
"maximum": 3,
"minimum": 1,
"description": "Number of visualization columns per row (1, 2, or 3). Defaults to 2. Use 1 for full-width detailed charts, 2 for balanced layout, 3 for compact overview."
},
"visualizationIds": {
"type": "array",
"items": {
"type": "number"
},
"description": "Array of visualization IDs to add to the dashboard. These come from generateVisualization output."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"dashboardId",
"name",
"slug",
"isPrivate",
"tags",
"dashboardUrl",
"visualizationWidgets",
"textWidgets",
"paramWidgets"
],
"properties": {
"name": {
"type": "string",
"description": "The display name of the dashboard."
},
"slug": {
"type": "string",
"description": "The URL slug of the dashboard."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Tags applied to the dashboard."
},
"isPrivate": {
"type": "boolean",
"description": "Whether the dashboard is private."
},
"dashboardId": {
"type": "number",
"description": "The ID of the dashboard."
},
"textWidgets": {
"type": "array",
"items": {
"type": "object",
"required": [
"widgetId",
"text",
"position"
],
"properties": {
"text": {
"type": "string",
"description": "The markdown text content of the widget."
},
"position": {
"type": "object",
"required": [
"row",
"col",
"sizeX",
"sizeY"
],
"properties": {
"col": {
"type": "number",
"description": "Left edge, in grid columns from the left (0 to 5; the grid has 6 columns)."
},
"row": {
"type": "number",
"description": "Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px."
},
"sizeX": {
"type": "number",
"description": "Width in grid columns (1 to 6; 6 is the full width)."
},
"sizeY": {
"type": "number",
"description": "Height in grid rows. Charts are 8 rows high by default."
}
},
"description": "Position and size in the dashboard grid.",
"additionalProperties": false
},
"widgetId": {
"type": "number",
"description": "The widget ID on the dashboard."
}
},
"additionalProperties": false
},
"description": "Current text widgets on the dashboard with their content."
},
"dashboardUrl": {
"type": "string",
"description": "Full URL to the dashboard on dune.com."
},
"paramWidgets": {
"type": "array",
"items": {
"type": "object",
"required": [
"widgetId",
"key",
"queryId",
"visualizationWidgetId",
"position"
],
"properties": {
"key": {
"type": "string",
"description": "The parameter key name."
},
"queryId": {
"type": "number",
"description": "The query ID this parameter belongs to."
},
"position": {
"type": "object",
"required": [
"row",
"col",
"sizeX",
"sizeY"
],
"properties": {
"col": {
"type": "number",
"description": "Left edge, in grid columns from the left (0 to 5; the grid has 6 columns)."
},
"row": {
"type": "number",
"description": "Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px."
},
"sizeX": {
"type": "number",
"description": "Width in grid columns (1 to 6; 6 is the full width)."
},
"sizeY": {
"type": "number",
"description": "Height in grid rows. Charts are 8 rows high by default."
}
},
"description": "Position and size in the dashboard grid.",
"additionalProperties": false
},
"widgetId": {
"type": "string",
"description": "The param widget ID (UUID)."
},
"visualizationWidgetId": {
"type": "number",
"description": "The visualization widget ID this parameter is attached to."
}
},
"additionalProperties": false
},
"description": "Current parameter widgets on the dashboard. These are interactive controls (dropdowns, text inputs) for query parameters."
},
"visualizationWidgets": {
"type": "array",
"items": {
"type": "object",
"required": [
"widgetId",
"visualizationId",
"position"
],
"properties": {
"position": {
"type": "object",
"required": [
"row",
"col",
"sizeX",
"sizeY"
],
"properties": {
"col": {
"type": "number",
"description": "Left edge, in grid columns from the left (0 to 5; the grid has 6 columns)."
},
"row": {
"type": "number",
"description": "Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px."
},
"sizeX": {
"type": "number",
"description": "Width in grid columns (1 to 6; 6 is the full width)."
},
"sizeY": {
"type": "number",
"description": "Height in grid rows. Charts are 8 rows high by default."
}
},
"description": "Position and size in the dashboard grid.",
"additionalProperties": false
},
"widgetId": {
"type": "number",
"description": "The widget ID on the dashboard."
},
"visualizationId": {
"type": "number",
"description": "The visualization ID this widget displays."
}
},
"additionalProperties": false
},
"description": "Current visualization widgets on the dashboard."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description93/100
Retrieve the full current state of a Dune dashboard.
IMPORTANT: always call this before updateDashboard. The updateDashboard tool uses all-or-nothing widget replacement. When you provide widget fields, all existing widgets are replaced. To preserve widgets you do not want to change, first fetch the current state with this tool, modify what you need, and send the complete state back to updateDashboard.
Typical workflow:
1. Call getDashboard to fetch the current dashboard state.
2. Modify the fields you need.
3. Call updateDashboard with the full desired state.
Lookup options:
- Use id when you already have the numeric dashboard ID.
- Use ownerHandle + slug when you are starting from a Dune dashboard URL.
Provide either id or both ownerHandle and slug.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
id
The numeric ID of the dashboard. Provide this OR ownerHandle + slug.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
ownerHandle
The username or team handle that owns the dashboard (from the URL path). Must be provided together with slug.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
slug
The dashboard slug (from the URL path). Must be provided together with ownerHandle.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"dashboardId",
"name",
"slug",
"isPrivate",
"tags",
"dashboardUrl",
"visualizationWidgets",
"textWidgets",
"paramWidgets"
],
"properties": {
"name": {
"type": "string",
"description": "The display name of the dashboard."
},
"slug": {
"type": "string",
"description": "The URL slug of the dashboard."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Tags applied to the dashboard."
},
"isPrivate": {
"type": "boolean",
"description": "Whether the dashboard is private."
},
"dashboardId": {
"type": "number",
"description": "The ID of the dashboard."
},
"textWidgets": {
"type": "array",
"items": {
"type": "object",
"required": [
"widgetId",
"text",
"position"
],
"properties": {
"text": {
"type": "string",
"description": "The markdown text content of the widget."
},
"position": {
"type": "object",
"required": [
"row",
"col",
"sizeX",
"sizeY"
],
"properties": {
"col": {
"type": "number",
"description": "Left edge, in grid columns from the left (0 to 5; the grid has 6 columns)."
},
"row": {
"type": "number",
"description": "Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px."
},
"sizeX": {
"type": "number",
"description": "Width in grid columns (1 to 6; 6 is the full width)."
},
"sizeY": {
"type": "number",
"description": "Height in grid rows. Charts are 8 rows high by default."
}
},
"description": "Position and size in the dashboard grid.",
"additionalProperties": false
},
"widgetId": {
"type": "number",
"description": "The widget ID on the dashboard."
}
},
"additionalProperties": false
},
"description": "Current text widgets on the dashboard with their content."
},
"dashboardUrl": {
"type": "string",
"description": "Full URL to the dashboard on dune.com."
},
"paramWidgets": {
"type": "array",
"items": {
"type": "object",
"required": [
"widgetId",
"key",
"queryId",
"visualizationWidgetId",
"position"
],
"properties": {
"key": {
"type": "string",
"description": "The parameter key name."
},
"queryId": {
"type": "number",
"description": "The query ID this parameter belongs to."
},
"position": {
"type": "object",
"required": [
"row",
"col",
"sizeX",
"sizeY"
],
"properties": {
"col": {
"type": "number",
"description": "Left edge, in grid columns from the left (0 to 5; the grid has 6 columns)."
},
"row": {
"type": "number",
"description": "Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px."
},
"sizeX": {
"type": "number",
"description": "Width in grid columns (1 to 6; 6 is the full width)."
},
"sizeY": {
"type": "number",
"description": "Height in grid rows. Charts are 8 rows high by default."
}
},
"description": "Position and size in the dashboard grid.",
"additionalProperties": false
},
"widgetId": {
"type": "string",
"description": "The param widget ID (UUID)."
},
"visualizationWidgetId": {
"type": "number",
"description": "The visualization widget ID this parameter is attached to."
}
},
"additionalProperties": false
},
"description": "Current parameter widgets on the dashboard. These are interactive controls (dropdowns, text inputs) for query parameters."
},
"visualizationWidgets": {
"type": "array",
"items": {
"type": "object",
"required": [
"widgetId",
"visualizationId",
"position"
],
"properties": {
"position": {
"type": "object",
"required": [
"row",
"col",
"sizeX",
"sizeY"
],
"properties": {
"col": {
"type": "number",
"description": "Left edge, in grid columns from the left (0 to 5; the grid has 6 columns)."
},
"row": {
"type": "number",
"description": "Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px."
},
"sizeX": {
"type": "number",
"description": "Width in grid columns (1 to 6; 6 is the full width)."
},
"sizeY": {
"type": "number",
"description": "Height in grid rows. Charts are 8 rows high by default."
}
},
"description": "Position and size in the dashboard grid.",
"additionalProperties": false
},
"widgetId": {
"type": "number",
"description": "The widget ID on the dashboard."
},
"visualizationId": {
"type": "number",
"description": "The visualization ID this widget displays."
}
},
"additionalProperties": false
},
"description": "Current visualization widgets on the dashboard."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "getDashboard",
"title": "Get Dashboard",
"description": "Retrieve the full current state of a Dune dashboard.\n\nIMPORTANT: always call this before updateDashboard. The updateDashboard tool uses all-or-nothing widget replacement. When you provide widget fields, all existing widgets are replaced. To preserve widgets you do not want to change, first fetch the current state with this tool, modify what you need, and send the complete state back to updateDashboard.\n\nTypical workflow:\n1. Call getDashboard to fetch the current dashboard state.\n2. Modify the fields you need.\n3. Call updateDashboard with the full desired state.\n\nLookup options:\n- Use id when you already have the numeric dashboard ID.\n- Use ownerHandle + slug when you are starting from a Dune dashboard URL.\n\nProvide either id or both ownerHandle and slug.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"id": {
"type": "number",
"description": "The numeric ID of the dashboard. Provide this OR ownerHandle + slug."
},
"slug": {
"type": "string",
"minLength": 1,
"description": "The dashboard slug (from the URL path). Must be provided together with ownerHandle."
},
"ownerHandle": {
"type": "string",
"minLength": 1,
"description": "The username or team handle that owns the dashboard (from the URL path). Must be provided together with slug."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"dashboardId",
"name",
"slug",
"isPrivate",
"tags",
"dashboardUrl",
"visualizationWidgets",
"textWidgets",
"paramWidgets"
],
"properties": {
"name": {
"type": "string",
"description": "The display name of the dashboard."
},
"slug": {
"type": "string",
"description": "The URL slug of the dashboard."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Tags applied to the dashboard."
},
"isPrivate": {
"type": "boolean",
"description": "Whether the dashboard is private."
},
"dashboardId": {
"type": "number",
"description": "The ID of the dashboard."
},
"textWidgets": {
"type": "array",
"items": {
"type": "object",
"required": [
"widgetId",
"text",
"position"
],
"properties": {
"text": {
"type": "string",
"description": "The markdown text content of the widget."
},
"position": {
"type": "object",
"required": [
"row",
"col",
"sizeX",
"sizeY"
],
"properties": {
"col": {
"type": "number",
"description": "Left edge, in grid columns from the left (0 to 5; the grid has 6 columns)."
},
"row": {
"type": "number",
"description": "Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px."
},
"sizeX": {
"type": "number",
"description": "Width in grid columns (1 to 6; 6 is the full width)."
},
"sizeY": {
"type": "number",
"description": "Height in grid rows. Charts are 8 rows high by default."
}
},
"description": "Position and size in the dashboard grid.",
"additionalProperties": false
},
"widgetId": {
"type": "number",
"description": "The widget ID on the dashboard."
}
},
"additionalProperties": false
},
"description": "Current text widgets on the dashboard with their content."
},
"dashboardUrl": {
"type": "string",
"description": "Full URL to the dashboard on dune.com."
},
"paramWidgets": {
"type": "array",
"items": {
"type": "object",
"required": [
"widgetId",
"key",
"queryId",
"visualizationWidgetId",
"position"
],
"properties": {
"key": {
"type": "string",
"description": "The parameter key name."
},
"queryId": {
"type": "number",
"description": "The query ID this parameter belongs to."
},
"position": {
"type": "object",
"required": [
"row",
"col",
"sizeX",
"sizeY"
],
"properties": {
"col": {
"type": "number",
"description": "Left edge, in grid columns from the left (0 to 5; the grid has 6 columns)."
},
"row": {
"type": "number",
"description": "Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px."
},
"sizeX": {
"type": "number",
"description": "Width in grid columns (1 to 6; 6 is the full width)."
},
"sizeY": {
"type": "number",
"description": "Height in grid rows. Charts are 8 rows high by default."
}
},
"description": "Position and size in the dashboard grid.",
"additionalProperties": false
},
"widgetId": {
"type": "string",
"description": "The param widget ID (UUID)."
},
"visualizationWidgetId": {
"type": "number",
"description": "The visualization widget ID this parameter is attached to."
}
},
"additionalProperties": false
},
"description": "Current parameter widgets on the dashboard. These are interactive controls (dropdowns, text inputs) for query parameters."
},
"visualizationWidgets": {
"type": "array",
"items": {
"type": "object",
"required": [
"widgetId",
"visualizationId",
"position"
],
"properties": {
"position": {
"type": "object",
"required": [
"row",
"col",
"sizeX",
"sizeY"
],
"properties": {
"col": {
"type": "number",
"description": "Left edge, in grid columns from the left (0 to 5; the grid has 6 columns)."
},
"row": {
"type": "number",
"description": "Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px."
},
"sizeX": {
"type": "number",
"description": "Width in grid columns (1 to 6; 6 is the full width)."
},
"sizeY": {
"type": "number",
"description": "Height in grid rows. Charts are 8 rows high by default."
}
},
"description": "Position and size in the dashboard grid.",
"additionalProperties": false
},
"widgetId": {
"type": "number",
"description": "The widget ID on the dashboard."
},
"visualizationId": {
"type": "number",
"description": "The visualization ID this widget displays."
}
},
"additionalProperties": false
},
"description": "Current visualization widgets on the dashboard."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description87/100
Search for Dune dashboards by name (case-insensitive substring match).
Use this when the user does not know a dashboard ID and needs to find saved dashboards. Results respect the authenticated customer: public dashboards, the user's and team-accessible private dashboards, and (for team API keys) that team's private dashboards.
- **all_visible** (default): public dashboards plus any private dashboards visible to the caller.
- **owned_only**: only dashboards owned by the user or the authenticated team.
The description explains the capability, when to use it, and what to expect.
Inputs83/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
search_string
Text to find in the dashboard name (partial match).
Clear enough to supply this argument.
scope
all_visible: public plus anything the caller can access; owned_only: only dashboards owned by the user/team for this key.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Maximum number of results (1–50). Default 20.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description90/100
Update an existing Dune dashboard — change metadata, replace widgets, or both.
Use this tool to modify dashboards containing blockchain and crypto data — DeFi metrics, NFT analytics, DEX trading, token transfers, protocol dashboards, and any onchain data visualizations.
IMPORTANT: call getDashboard first. Widget updates use all-or-nothing replacement. When you provide visualizationWidgets, textWidgets, or paramWidgets, all existing widgets are replaced. To avoid losing widgets you want to keep:
1. Call getDashboard to fetch the current state.
2. Modify the fields you need.
3. Send the complete desired state to this tool.
All fields except dashboardId are optional. Only provided metadata fields are updated. Omitted metadata fields are preserved.
Widget replacement behavior:
- If none of visualizationWidgets, textWidgets, or paramWidgets is provided, existing widgets are preserved.
- If any of those widget fields is provided, the dashboard widget state is rebuilt from the supplied widget arrays.
- Widget types that are omitted during a widget update are cleared.
Preserving layout:
- Pass positions through from getDashboard to preserve the existing layout.
- Omit positions to auto-layout visualizations using columnsPerRow.
The description explains the capability, when to use it, and what to expect.
Inputs90/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
dashboardId
The ID of the dashboard to update.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
name
New display name for the dashboard.
Clear enough to supply this argument.
slug
New URL slug. If omitted and name is changed, slug is auto-generated from the new name.
Clear enough to supply this argument.
isPrivate
Whether the dashboard should be private.
Explain the meaning of this value, not just its name.
tags
Replace all tags on the dashboard. Provide the full list of desired tags.
Clear enough to supply this argument.
visualizationWidgets › items › visualizationId
The visualization to display. Get IDs from generateVisualization, createAndExecuteQuery or listQueryVisualizations.
Clear enough to supply this argument.
visualizationWidgets › items › position › row
Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px.
Clear enough to supply this argument.
visualizationWidgets › items › position › col
Left edge, in grid columns from the left (0 to 5; the grid has 6 columns).
Clear enough to supply this argument.
visualizationWidgets › items › position › sizeX
Width in grid columns (1 to 6; 6 is the full width).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
visualizationWidgets › items › position › sizeY
Height in grid rows. Charts are 8 rows high by default.
Clear enough to supply this argument.
textWidgets › items › text
Markdown text content for the widget.
Clear enough to supply this argument.
textWidgets › items › position › row
Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px.
Clear enough to supply this argument.
textWidgets › items › position › col
Left edge, in grid columns from the left (0 to 5; the grid has 6 columns).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
textWidgets › items › position › sizeX
Width in grid columns (1 to 6; 6 is the full width).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
textWidgets › items › position › sizeY
Height in grid rows. Charts are 8 rows high by default.
Clear enough to supply this argument.
paramWidgets › items › key
The parameter key name.
Clear enough to supply this argument.
paramWidgets › items › queryId
The query ID this parameter belongs to.
Clear enough to supply this argument.
paramWidgets › items › visualizationWidgetId
The visualization widget ID this parameter is attached to. Use the value from getDashboard output.
Clear enough to supply this argument.
paramWidgets › items › position › row
Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px.
Clear enough to supply this argument.
paramWidgets › items › position › col
Left edge, in grid columns from the left (0 to 5; the grid has 6 columns).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
paramWidgets › items › position › sizeX
Width in grid columns (1 to 6; 6 is the full width).
Clear enough to supply this argument.
paramWidgets › items › position › sizeY
Height in grid rows. Charts are 8 rows high by default.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
columnsPerRow
Number of visualization columns per row (1, 2, or 3). Defaults to 2. Only applies when auto-laying out visualizations (when position is omitted). Use 1 for full-width charts, 2 for balanced layout, 3 for compact overview.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"dashboardId",
"name",
"slug",
"isPrivate",
"tags",
"dashboardUrl",
"visualizationWidgets",
"textWidgets",
"paramWidgets"
],
"properties": {
"name": {
"type": "string",
"description": "The display name of the dashboard."
},
"slug": {
"type": "string",
"description": "The URL slug of the dashboard."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Tags applied to the dashboard."
},
"isPrivate": {
"type": "boolean",
"description": "Whether the dashboard is private."
},
"dashboardId": {
"type": "number",
"description": "The ID of the dashboard."
},
"textWidgets": {
"type": "array",
"items": {
"type": "object",
"required": [
"widgetId",
"text",
"position"
],
"properties": {
"text": {
"type": "string",
"description": "The markdown text content of the widget."
},
"position": {
"type": "object",
"required": [
"row",
"col",
"sizeX",
"sizeY"
],
"properties": {
"col": {
"type": "number",
"description": "Left edge, in grid columns from the left (0 to 5; the grid has 6 columns)."
},
"row": {
"type": "number",
"description": "Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px."
},
"sizeX": {
"type": "number",
"description": "Width in grid columns (1 to 6; 6 is the full width)."
},
"sizeY": {
"type": "number",
"description": "Height in grid rows. Charts are 8 rows high by default."
}
},
"description": "Position and size in the dashboard grid.",
"additionalProperties": false
},
"widgetId": {
"type": "number",
"description": "The widget ID on the dashboard."
}
},
"additionalProperties": false
},
"description": "Current text widgets on the dashboard with their content."
},
"dashboardUrl": {
"type": "string",
"description": "Full URL to the dashboard on dune.com."
},
"paramWidgets": {
"type": "array",
"items": {
"type": "object",
"required": [
"widgetId",
"key",
"queryId",
"visualizationWidgetId",
"position"
],
"properties": {
"key": {
"type": "string",
"description": "The parameter key name."
},
"queryId": {
"type": "number",
"description": "The query ID this parameter belongs to."
},
"position": {
"type": "object",
"required": [
"row",
"col",
"sizeX",
"sizeY"
],
"properties": {
"col": {
"type": "number",
"description": "Left edge, in grid columns from the left (0 to 5; the grid has 6 columns)."
},
"row": {
"type": "number",
"description": "Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px."
},
"sizeX": {
"type": "number",
"description": "Width in grid columns (1 to 6; 6 is the full width)."
},
"sizeY": {
"type": "number",
"description": "Height in grid rows. Charts are 8 rows high by default."
}
},
"description": "Position and size in the dashboard grid.",
"additionalProperties": false
},
"widgetId": {
"type": "string",
"description": "The param widget ID (UUID)."
},
"visualizationWidgetId": {
"type": "number",
"description": "The visualization widget ID this parameter is attached to."
}
},
"additionalProperties": false
},
"description": "Current parameter widgets on the dashboard. These are interactive controls (dropdowns, text inputs) for query parameters."
},
"visualizationWidgets": {
"type": "array",
"items": {
"type": "object",
"required": [
"widgetId",
"visualizationId",
"position"
],
"properties": {
"position": {
"type": "object",
"required": [
"row",
"col",
"sizeX",
"sizeY"
],
"properties": {
"col": {
"type": "number",
"description": "Left edge, in grid columns from the left (0 to 5; the grid has 6 columns)."
},
"row": {
"type": "number",
"description": "Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px."
},
"sizeX": {
"type": "number",
"description": "Width in grid columns (1 to 6; 6 is the full width)."
},
"sizeY": {
"type": "number",
"description": "Height in grid rows. Charts are 8 rows high by default."
}
},
"description": "Position and size in the dashboard grid.",
"additionalProperties": false
},
"widgetId": {
"type": "number",
"description": "The widget ID on the dashboard."
},
"visualizationId": {
"type": "number",
"description": "The visualization ID this widget displays."
}
},
"additionalProperties": false
},
"description": "Current visualization widgets on the dashboard."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "updateDashboard",
"title": "Update Dashboard",
"description": "Update an existing Dune dashboard — change metadata, replace widgets, or both.\n\nUse this tool to modify dashboards containing blockchain and crypto data — DeFi metrics, NFT analytics, DEX trading, token transfers, protocol dashboards, and any onchain data visualizations.\n\nIMPORTANT: call getDashboard first. Widget updates use all-or-nothing replacement. When you provide visualizationWidgets, textWidgets, or paramWidgets, all existing widgets are replaced. To avoid losing widgets you want to keep:\n1. Call getDashboard to fetch the current state.\n2. Modify the fields you need.\n3. Send the complete desired state to this tool.\n\nAll fields except dashboardId are optional. Only provided metadata fields are updated. Omitted metadata fields are preserved.\n\nWidget replacement behavior:\n- If none of visualizationWidgets, textWidgets, or paramWidgets is provided, existing widgets are preserved.\n- If any of those widget fields is provided, the dashboard widget state is rebuilt from the supplied widget arrays.\n- Widget types that are omitted during a widget update are cleared.\n\nPreserving layout:\n- Pass positions through from getDashboard to preserve the existing layout.\n- Omit positions to auto-layout visualizations using columnsPerRow.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"dashboardId"
],
"properties": {
"name": {
"type": "string",
"description": "New display name for the dashboard."
},
"slug": {
"type": "string",
"description": "New URL slug. If omitted and name is changed, slug is auto-generated from the new name."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Replace all tags on the dashboard. Provide the full list of desired tags."
},
"isPrivate": {
"type": "boolean",
"description": "Whether the dashboard should be private."
},
"dashboardId": {
"type": "number",
"description": "The ID of the dashboard to update."
},
"textWidgets": {
"type": "array",
"items": {
"type": "object",
"required": [
"text"
],
"properties": {
"text": {
"type": "string",
"description": "Markdown text content for the widget."
},
"position": {
"type": "object",
"required": [
"row",
"col",
"sizeX",
"sizeY"
],
"properties": {
"col": {
"type": "number",
"description": "Left edge, in grid columns from the left (0 to 5; the grid has 6 columns)."
},
"row": {
"type": "number",
"description": "Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px."
},
"sizeX": {
"type": "number",
"description": "Width in grid columns (1 to 6; 6 is the full width)."
},
"sizeY": {
"type": "number",
"description": "Height in grid rows. Charts are 8 rows high by default."
}
},
"description": "Grid position and size. Pass this through from getDashboard output to preserve layout. Omit to auto-layout."
}
}
},
"description": "Complete set of text widgets for the dashboard. When provided, all existing widgets are replaced. Pass position from getDashboard to preserve layout."
},
"paramWidgets": {
"type": "array",
"items": {
"type": "object",
"required": [
"key",
"queryId",
"visualizationWidgetId"
],
"properties": {
"key": {
"type": "string",
"description": "The parameter key name."
},
"queryId": {
"type": "number",
"description": "The query ID this parameter belongs to."
},
"position": {
"type": "object",
"required": [
"row",
"col",
"sizeX",
"sizeY"
],
"properties": {
"col": {
"type": "number",
"description": "Left edge, in grid columns from the left (0 to 5; the grid has 6 columns)."
},
"row": {
"type": "number",
"description": "Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px."
},
"sizeX": {
"type": "number",
"description": "Width in grid columns (1 to 6; 6 is the full width)."
},
"sizeY": {
"type": "number",
"description": "Height in grid rows. Charts are 8 rows high by default."
}
},
"description": "Grid position and size. Pass this through from getDashboard output to preserve layout."
},
"visualizationWidgetId": {
"type": "number",
"description": "The visualization widget ID this parameter is attached to. Use the value from getDashboard output."
}
}
},
"description": "Complete set of parameter widgets for the dashboard. When provided, all existing param widgets are replaced. Pass these through from getDashboard output to preserve interactive query parameter controls."
},
"columnsPerRow": {
"type": "integer",
"maximum": 3,
"minimum": 1,
"description": "Number of visualization columns per row (1, 2, or 3). Defaults to 2. Only applies when auto-laying out visualizations (when position is omitted). Use 1 for full-width charts, 2 for balanced layout, 3 for compact overview."
},
"visualizationWidgets": {
"type": "array",
"items": {
"type": "object",
"required": [
"visualizationId"
],
"properties": {
"position": {
"type": "object",
"required": [
"row",
"col",
"sizeX",
"sizeY"
],
"properties": {
"col": {
"type": "number",
"description": "Left edge, in grid columns from the left (0 to 5; the grid has 6 columns)."
},
"row": {
"type": "number",
"description": "Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px."
},
"sizeX": {
"type": "number",
"description": "Width in grid columns (1 to 6; 6 is the full width)."
},
"sizeY": {
"type": "number",
"description": "Height in grid rows. Charts are 8 rows high by default."
}
},
"description": "Grid position and size. Pass this through from getDashboard output to preserve layout. Omit to auto-layout."
},
"visualizationId": {
"type": "number",
"description": "The visualization to display. Get IDs from generateVisualization, createAndExecuteQuery or listQueryVisualizations."
}
}
},
"description": "Complete set of visualization widgets for the dashboard. When provided, all existing widgets are replaced. Pass position from getDashboard to preserve layout."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"dashboardId",
"name",
"slug",
"isPrivate",
"tags",
"dashboardUrl",
"visualizationWidgets",
"textWidgets",
"paramWidgets"
],
"properties": {
"name": {
"type": "string",
"description": "The display name of the dashboard."
},
"slug": {
"type": "string",
"description": "The URL slug of the dashboard."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Tags applied to the dashboard."
},
"isPrivate": {
"type": "boolean",
"description": "Whether the dashboard is private."
},
"dashboardId": {
"type": "number",
"description": "The ID of the dashboard."
},
"textWidgets": {
"type": "array",
"items": {
"type": "object",
"required": [
"widgetId",
"text",
"position"
],
"properties": {
"text": {
"type": "string",
"description": "The markdown text content of the widget."
},
"position": {
"type": "object",
"required": [
"row",
"col",
"sizeX",
"sizeY"
],
"properties": {
"col": {
"type": "number",
"description": "Left edge, in grid columns from the left (0 to 5; the grid has 6 columns)."
},
"row": {
"type": "number",
"description": "Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px."
},
"sizeX": {
"type": "number",
"description": "Width in grid columns (1 to 6; 6 is the full width)."
},
"sizeY": {
"type": "number",
"description": "Height in grid rows. Charts are 8 rows high by default."
}
},
"description": "Position and size in the dashboard grid.",
"additionalProperties": false
},
"widgetId": {
"type": "number",
"description": "The widget ID on the dashboard."
}
},
"additionalProperties": false
},
"description": "Current text widgets on the dashboard with their content."
},
"dashboardUrl": {
"type": "string",
"description": "Full URL to the dashboard on dune.com."
},
"paramWidgets": {
"type": "array",
"items": {
"type": "object",
"required": [
"widgetId",
"key",
"queryId",
"visualizationWidgetId",
"position"
],
"properties": {
"key": {
"type": "string",
"description": "The parameter key name."
},
"queryId": {
"type": "number",
"description": "The query ID this parameter belongs to."
},
"position": {
"type": "object",
"required": [
"row",
"col",
"sizeX",
"sizeY"
],
"properties": {
"col": {
"type": "number",
"description": "Left edge, in grid columns from the left (0 to 5; the grid has 6 columns)."
},
"row": {
"type": "number",
"description": "Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px."
},
"sizeX": {
"type": "number",
"description": "Width in grid columns (1 to 6; 6 is the full width)."
},
"sizeY": {
"type": "number",
"description": "Height in grid rows. Charts are 8 rows high by default."
}
},
"description": "Position and size in the dashboard grid.",
"additionalProperties": false
},
"widgetId": {
"type": "string",
"description": "The param widget ID (UUID)."
},
"visualizationWidgetId": {
"type": "number",
"description": "The visualization widget ID this parameter is attached to."
}
},
"additionalProperties": false
},
"description": "Current parameter widgets on the dashboard. These are interactive controls (dropdowns, text inputs) for query parameters."
},
"visualizationWidgets": {
"type": "array",
"items": {
"type": "object",
"required": [
"widgetId",
"visualizationId",
"position"
],
"properties": {
"position": {
"type": "object",
"required": [
"row",
"col",
"sizeX",
"sizeY"
],
"properties": {
"col": {
"type": "number",
"description": "Left edge, in grid columns from the left (0 to 5; the grid has 6 columns)."
},
"row": {
"type": "number",
"description": "Top edge, in grid rows from the top of the dashboard (0 is the top). One row is 32 px."
},
"sizeX": {
"type": "number",
"description": "Width in grid columns (1 to 6; 6 is the full width)."
},
"sizeY": {
"type": "number",
"description": "Height in grid rows. Charts are 8 rows high by default."
}
},
"description": "Position and size in the dashboard grid.",
"additionalProperties": false
},
"widgetId": {
"type": "number",
"description": "The widget ID on the dashboard."
},
"visualizationId": {
"type": "number",
"description": "The visualization ID this widget displays."
}
},
"additionalProperties": false
},
"description": "Current visualization widgets on the dashboard."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Archive a Dune dashboard by ID.
This archives the dashboard, removing it from public view. The dashboard can be restored later via Dune support or by unarchiving.
Use this when a dashboard is no longer needed but you want to keep it recoverable.
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
dashboardId
The numeric ID of the dashboard to archive, from createDashboard, getDashboard or searchDuneDashboards (not the URL slug).
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"ok",
"dashboardId"
],
"properties": {
"ok": {
"type": "boolean",
"description": "Whether the archiving succeeded."
},
"dashboardId": {
"type": "number",
"description": "The ID of the archived dashboard."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "archiveDashboard",
"title": "Archive Dashboard",
"description": "Archive a Dune dashboard by ID.\n\nThis archives the dashboard, removing it from public view. The dashboard can be restored later via Dune support or by unarchiving.\n\nUse this when a dashboard is no longer needed but you want to keep it recoverable.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"dashboardId"
],
"properties": {
"dashboardId": {
"type": "number",
"description": "The numeric ID of the dashboard to archive, from createDashboard, getDashboard or searchDuneDashboards (not the URL slug)."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"ok",
"dashboardId"
],
"properties": {
"ok": {
"type": "boolean",
"description": "Whether the archiving succeeded."
},
"dashboardId": {
"type": "number",
"description": "The ID of the archived dashboard."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Create a materialized view from an existing Dune query. Returns the matview ID, SQL table names, and the execution ID. Use it to store a query's results as a queryable table, optionally refreshed on a schedule.
Constraints:
- The source query must be saved as non-temporary (is_temp: false), have no parameters, not be archived, and be owned by the same user or team. Queries from createDuneQuery are temporary by default, so set is_temp: false there when you intend to materialize.
- Each query can have at most one materialized view. If one already exists, this call fails; use refreshMaterializedView to re-run it.
- The matview is owned by your authenticated context (team or personal). Its privacy is not settable: it inherits the privacy of the source query, and the returned is_private is that inherited value.
- The name must start with "result_", contain only lowercase letters, numbers, and underscores, be at least 8 characters, and not end with an underscore. It cannot be changed after creation.
- The performance tier ("small", "medium", or "large") must be available on the plan; "small" is typically free-plan only. Larger tiers cost more compute.
- Creation runs the source query immediately. A cron_expression adds periodic refreshes; only the expressions below are accepted.
Supported cron expressions (5-part, UTC):
- "*/15 * * * *", "*/20 * * * *", "*/30 * * * *": every 15, 20 or 30 minutes
- "0 * * * *": hourly
- "0 */N * * *" with N in 2, 3, 4, 6, 8, 12: every N hours
- "M H * * *": daily at H:M
- "M H * * D": weekly on day D (0 = Sunday) at H:M
where M is 0 or 30 and H is 0-23.
The description explains the capability, when to use it, and what to expect.
Inputs80/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
query_id
ID of the source query to materialize.
Clear enough to supply this argument.
name
SQL-safe name for the materialized view. Must start with "result_", lowercase alphanumeric + underscores, min 8 chars, no trailing underscore. Example: "result_token_summary".
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
performance
Performance tier for the execution: "small", "medium", or "large". Availability depends on the plan ("small" is typically free-plan only); validated against it. Larger tiers cost more compute.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
cron_expression
Cron schedule for periodic refresh, as a supported UTC cron expression (see the tool description), e.g. "0 */6 * * *". Null or omitted = no schedule.
Clear enough to supply this argument.
expires_at
ISO 8601 datetime for schedule expiration. Null = no expiration.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"matview_id",
"query_id",
"sql_names",
"execution_id",
"is_private"
],
"properties": {
"query_id": {
"type": "number",
"description": "Source query ID."
},
"sql_names": {
"type": "array",
"items": {
"type": "string"
},
"description": "Fully-qualified SQL table names (e.g. dune.team_name.result_my_matview)."
},
"is_private": {
"type": "boolean",
"description": "Effective privacy of the materialized view. Always inherited from the source query's privacy; it cannot be set on the matview."
},
"matview_id": {
"type": "string",
"description": "UUID of the created materialized view."
},
"execution_id": {
"type": "string",
"description": "Execution ID triggered by the creation. To wait for it to finish, pass it to getExecutionResults, which waits; do not poll getMaterializedView."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "createMaterializedView",
"title": "Create Materialized View",
"description": "Create a materialized view from an existing Dune query. Returns the matview ID, SQL table names, and the execution ID. Use it to store a query's results as a queryable table, optionally refreshed on a schedule.\n\nConstraints:\n- The source query must be saved as non-temporary (is_temp: false), have no parameters, not be archived, and be owned by the same user or team. Queries from createDuneQuery are temporary by default, so set is_temp: false there when you intend to materialize.\n- Each query can have at most one materialized view. If one already exists, this call fails; use refreshMaterializedView to re-run it.\n- The matview is owned by your authenticated context (team or personal). Its privacy is not settable: it inherits the privacy of the source query, and the returned is_private is that inherited value.\n- The name must start with \"result_\", contain only lowercase letters, numbers, and underscores, be at least 8 characters, and not end with an underscore. It cannot be changed after creation.\n- The performance tier (\"small\", \"medium\", or \"large\") must be available on the plan; \"small\" is typically free-plan only. Larger tiers cost more compute.\n- Creation runs the source query immediately. A cron_expression adds periodic refreshes; only the expressions below are accepted.\n\nSupported cron expressions (5-part, UTC):\n- \"*/15 * * * *\", \"*/20 * * * *\", \"*/30 * * * *\": every 15, 20 or 30 minutes\n- \"0 * * * *\": hourly\n- \"0 */N * * *\" with N in 2, 3, 4, 6, 8, 12: every N hours\n- \"M H * * *\": daily at H:M\n- \"M H * * D\": weekly on day D (0 = Sunday) at H:M\nwhere M is 0 or 30 and H is 0-23.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"query_id",
"name",
"performance"
],
"properties": {
"name": {
"type": "string",
"pattern": "^result_([a-z0-9_]{0,}[a-z0-9]+)?$",
"maxLength": 128,
"minLength": 8,
"description": "SQL-safe name for the materialized view. Must start with \"result_\", lowercase alphanumeric + underscores, min 8 chars, no trailing underscore. Example: \"result_token_summary\"."
},
"query_id": {
"type": "integer",
"maximum": 9007199254740991,
"description": "ID of the source query to materialize.",
"exclusiveMinimum": 0
},
"expires_at": {
"type": [
"string",
"null"
],
"description": "ISO 8601 datetime for schedule expiration. Null = no expiration."
},
"performance": {
"enum": [
"small",
"medium",
"large"
],
"type": "string",
"description": "Performance tier for the execution: \"small\", \"medium\", or \"large\". Availability depends on the plan (\"small\" is typically free-plan only); validated against it. Larger tiers cost more compute."
},
"cron_expression": {
"type": [
"string",
"null"
],
"description": "Cron schedule for periodic refresh, as a supported UTC cron expression (see the tool description), e.g. \"0 */6 * * *\". Null or omitted = no schedule."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"matview_id",
"query_id",
"sql_names",
"execution_id",
"is_private"
],
"properties": {
"query_id": {
"type": "number",
"description": "Source query ID."
},
"sql_names": {
"type": "array",
"items": {
"type": "string"
},
"description": "Fully-qualified SQL table names (e.g. dune.team_name.result_my_matview)."
},
"is_private": {
"type": "boolean",
"description": "Effective privacy of the materialized view. Always inherited from the source query's privacy; it cannot be set on the matview."
},
"matview_id": {
"type": "string",
"description": "UUID of the created materialized view."
},
"execution_id": {
"type": "string",
"description": "Execution ID triggered by the creation. To wait for it to finish, pass it to getExecutionResults, which waits; do not poll getMaterializedView."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Update an existing materialized view's settings. Returns the matview ID, SQL table names, and the execution ID.
Use this tool when the user wants to:
- Change the performance tier of an existing materialized view
- Add, change, or remove a periodic refresh schedule
Important constraints:
- The query must already have a materialized view (create one first with createMaterializedView). If it does not, the call fails.
- The matview is identified by query_id; you can obtain it from createMaterializedView or getMaterializedView output.
- The name cannot be changed — it is immutable after creation.
- Privacy is NOT settable here: a materialized view always inherits the privacy of its source query. To change a matview's privacy, change the source query's privacy. The returned is_private reflects this effective, inherited value.
- Performance tier ("small", "medium", or "large") is validated against the plan; availability depends on it ("small" is typically free-plan only). Larger tiers cost more compute.
- The update overwrites the refresh schedule, so pass the full intended state: cron_expression null/omitted removes any existing schedule, and expires_at null/omitted clears any existing expiration.
- Updating triggers an immediate re-execution of the source query.
Supported cron expressions (5-part, UTC):
- "*/15 * * * *", "*/20 * * * *", "*/30 * * * *": every 15, 20 or 30 minutes
- "0 * * * *": hourly
- "0 */N * * *" with N in 2, 3, 4, 6, 8, 12: every N hours
- "M H * * *": daily at H:M
- "M H * * D": weekly on day D (0 = Sunday) at H:M
where M is 0 or 30 and H is 0-23.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
query_id
ID of the query whose materialized view to update.
Clear enough to supply this argument.
performance
Performance tier for the execution: "small", "medium", or "large". Availability depends on the plan ("small" is typically free-plan only); validated against it. Larger tiers cost more compute.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
cron_expression
Cron schedule for periodic refresh, as a supported UTC cron expression (see the tool description), e.g. "0 */6 * * *". Null or omitted removes any existing schedule.
Clear enough to supply this argument.
expires_at
ISO 8601 datetime for schedule expiration. Null = no expiration.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"matview_id",
"query_id",
"sql_names",
"execution_id",
"is_private"
],
"properties": {
"query_id": {
"type": "number",
"description": "Source query ID."
},
"sql_names": {
"type": "array",
"items": {
"type": "string"
},
"description": "Fully-qualified SQL table names (e.g. dune.team_name.result_my_matview)."
},
"is_private": {
"type": "boolean",
"description": "Effective privacy of the materialized view. Always inherited from the source query's privacy; it cannot be set on the matview."
},
"matview_id": {
"type": "string",
"description": "UUID of the materialized view."
},
"execution_id": {
"type": "string",
"description": "Execution ID triggered by the update. To wait for it to finish, pass it to getExecutionResults, which waits; do not poll getMaterializedView."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "updateMaterializedView",
"title": "Update Materialized View",
"description": "Update an existing materialized view's settings. Returns the matview ID, SQL table names, and the execution ID.\n\nUse this tool when the user wants to:\n- Change the performance tier of an existing materialized view\n- Add, change, or remove a periodic refresh schedule\n\nImportant constraints:\n- The query must already have a materialized view (create one first with createMaterializedView). If it does not, the call fails.\n- The matview is identified by query_id; you can obtain it from createMaterializedView or getMaterializedView output.\n- The name cannot be changed — it is immutable after creation.\n- Privacy is NOT settable here: a materialized view always inherits the privacy of its source query. To change a matview's privacy, change the source query's privacy. The returned is_private reflects this effective, inherited value.\n- Performance tier (\"small\", \"medium\", or \"large\") is validated against the plan; availability depends on it (\"small\" is typically free-plan only). Larger tiers cost more compute.\n- The update overwrites the refresh schedule, so pass the full intended state: cron_expression null/omitted removes any existing schedule, and expires_at null/omitted clears any existing expiration.\n- Updating triggers an immediate re-execution of the source query.\n\nSupported cron expressions (5-part, UTC):\n- \"*/15 * * * *\", \"*/20 * * * *\", \"*/30 * * * *\": every 15, 20 or 30 minutes\n- \"0 * * * *\": hourly\n- \"0 */N * * *\" with N in 2, 3, 4, 6, 8, 12: every N hours\n- \"M H * * *\": daily at H:M\n- \"M H * * D\": weekly on day D (0 = Sunday) at H:M\nwhere M is 0 or 30 and H is 0-23.\n",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"query_id",
"performance"
],
"properties": {
"query_id": {
"type": "integer",
"maximum": 9007199254740991,
"description": "ID of the query whose materialized view to update.",
"exclusiveMinimum": 0
},
"expires_at": {
"type": [
"string",
"null"
],
"description": "ISO 8601 datetime for schedule expiration. Null = no expiration."
},
"performance": {
"enum": [
"small",
"medium",
"large"
],
"type": "string",
"description": "Performance tier for the execution: \"small\", \"medium\", or \"large\". Availability depends on the plan (\"small\" is typically free-plan only); validated against it. Larger tiers cost more compute."
},
"cron_expression": {
"type": [
"string",
"null"
],
"description": "Cron schedule for periodic refresh, as a supported UTC cron expression (see the tool description), e.g. \"0 */6 * * *\". Null or omitted removes any existing schedule."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"matview_id",
"query_id",
"sql_names",
"execution_id",
"is_private"
],
"properties": {
"query_id": {
"type": "number",
"description": "Source query ID."
},
"sql_names": {
"type": "array",
"items": {
"type": "string"
},
"description": "Fully-qualified SQL table names (e.g. dune.team_name.result_my_matview)."
},
"is_private": {
"type": "boolean",
"description": "Effective privacy of the materialized view. Always inherited from the source query's privacy; it cannot be set on the matview."
},
"matview_id": {
"type": "string",
"description": "UUID of the materialized view."
},
"execution_id": {
"type": "string",
"description": "Execution ID triggered by the update. To wait for it to finish, pass it to getExecutionResults, which waits; do not poll getMaterializedView."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description88/100
Fetch a materialized view by its fully-qualified SQL name or by its matview_id.
Use this tool when the user wants to:
- Check the status or metadata of an existing materialized view
- Get the SQL table names to query a materialized view
- Verify ownership or privacy settings
- Check the table size of a materialized view
Provide exactly one of:
- name: a fully-qualified SQL identifier in the format `dune.<team_or_user>.<name>` (e.g. `dune.my_team.result_token_summary`).
- matview_id: the UUID that createMaterializedView and updateMaterializedView return as matview_id, and listMaterializedViews returns as id.
Authorization is enforced — only matviews visible to the requester are returned.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
name
Fully-qualified SQL name of the materialized view (e.g. "dune.my_team.result_token_summary"). Provide this OR matview_id.
Clear enough to supply this argument.
matview_id
UUID of the materialized view. Provide this OR name.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"matview_id",
"query_id",
"sql_names",
"is_private",
"table_size_bytes",
"last_execution_ids"
],
"properties": {
"query_id": {
"type": "number",
"description": "ID of the source query."
},
"sql_names": {
"type": "array",
"items": {
"type": "string"
},
"description": "Fully-qualified SQL table names for querying this materialized view."
},
"is_private": {
"type": "boolean",
"description": "Whether the materialized view is private."
},
"matview_id": {
"type": "string",
"description": "UUID of the materialized view."
},
"table_size_bytes": {
"type": "number",
"description": "Storage size of the materialized view in bytes."
},
"last_execution_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "IDs of recent executions that refreshed this materialized view."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "getMaterializedView",
"title": "Get Materialized View",
"description": "Fetch a materialized view by its fully-qualified SQL name or by its matview_id.\n\nUse this tool when the user wants to:\n- Check the status or metadata of an existing materialized view\n- Get the SQL table names to query a materialized view\n- Verify ownership or privacy settings\n- Check the table size of a materialized view\n\nProvide exactly one of:\n- name: a fully-qualified SQL identifier in the format `dune.<team_or_user>.<name>` (e.g. `dune.my_team.result_token_summary`).\n- matview_id: the UUID that createMaterializedView and updateMaterializedView return as matview_id, and listMaterializedViews returns as id.\n\nAuthorization is enforced — only matviews visible to the requester are returned.\n",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"name": {
"type": "string",
"description": "Fully-qualified SQL name of the materialized view (e.g. \"dune.my_team.result_token_summary\"). Provide this OR matview_id."
},
"matview_id": {
"type": "string",
"description": "UUID of the materialized view. Provide this OR name."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"matview_id",
"query_id",
"sql_names",
"is_private",
"table_size_bytes",
"last_execution_ids"
],
"properties": {
"query_id": {
"type": "number",
"description": "ID of the source query."
},
"sql_names": {
"type": "array",
"items": {
"type": "string"
},
"description": "Fully-qualified SQL table names for querying this materialized view."
},
"is_private": {
"type": "boolean",
"description": "Whether the materialized view is private."
},
"matview_id": {
"type": "string",
"description": "UUID of the materialized view."
},
"table_size_bytes": {
"type": "number",
"description": "Storage size of the materialized view in bytes."
},
"last_execution_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "IDs of recent executions that refreshed this materialized view."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Delete a materialized view. This permanently removes the materialized table and any associated refresh schedules.
Use this tool when the user wants to:
- Remove a materialized view they no longer need
- Clean up unused materialized views
This action is irreversible. The materialized view's SQL table names will no longer be queryable after deletion.
Only the owner (or team members with appropriate permissions) can delete a materialized view.
The name must be a fully-qualified SQL identifier (e.g. "dune.my_team.result_token_summary").
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Input documentation gives an agent enough context to populate the arguments.
name
Fully-qualified SQL name of the materialized view to delete (e.g. "dune.my_team.result_token_summary").
{
"name": "deleteMaterializedView",
"title": "Delete Materialized View",
"description": "Delete a materialized view. This permanently removes the materialized table and any associated refresh schedules.\n\nUse this tool when the user wants to:\n- Remove a materialized view they no longer need\n- Clean up unused materialized views\n\nThis action is irreversible. The materialized view's SQL table names will no longer be queryable after deletion.\nOnly the owner (or team members with appropriate permissions) can delete a materialized view.\n\nThe name must be a fully-qualified SQL identifier (e.g. \"dune.my_team.result_token_summary\").\n",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "Fully-qualified SQL name of the materialized view to delete (e.g. \"dune.my_team.result_token_summary\")."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"ok"
],
"properties": {
"ok": {
"type": "boolean",
"description": "True if deletion succeeded."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description93/100
List materialized views owned by the authenticated user or team.
Use this tool when the user wants to:
- See all their materialized views
- Find a materialized view by browsing their list
- Check storage usage across materialized views
Returns a paginated list. Use limit and offset for pagination.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Number of materialized views to return. Default 100, max 1000.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
offset
Offset for pagination. Use next_offset from a previous response. Default 0.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description82/100
Trigger a refresh of an existing materialized view. This re-executes the source query and updates the materialized table with fresh results.
Use this tool when the user wants to:
- Manually refresh a materialized view with the latest data
- Trigger an on-demand update outside of the scheduled cron
The name must be a fully-qualified SQL identifier (e.g. "dune.my_team.result_token_summary").
Only the owner (or team members with appropriate permissions) can refresh a materialized view.
The refresh consumes credits based on actual compute resources used.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
name
Fully-qualified SQL name of the materialized view to refresh (e.g. "dune.my_team.result_token_summary").
Clear enough to supply this argument.
performance
Performance tier for the refresh execution: "small", "medium", or "large". Defaults to "medium". Availability depends on the plan ("small" is typically free-plan only). Larger tiers cost more compute.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"execution_id",
"sql_names"
],
"properties": {
"sql_names": {
"type": "array",
"items": {
"type": "string"
},
"description": "Fully-qualified SQL table names of the refreshed materialized view."
},
"execution_id": {
"type": "string",
"description": "Execution ID of the triggered refresh. To wait for it to finish, pass it to getExecutionResults, which waits; do not poll getMaterializedView."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "refreshMaterializedView",
"title": "Refresh Materialized View",
"description": "Trigger a refresh of an existing materialized view. This re-executes the source query and updates the materialized table with fresh results.\n\nUse this tool when the user wants to:\n- Manually refresh a materialized view with the latest data\n- Trigger an on-demand update outside of the scheduled cron\n\nThe name must be a fully-qualified SQL identifier (e.g. \"dune.my_team.result_token_summary\").\nOnly the owner (or team members with appropriate permissions) can refresh a materialized view.\nThe refresh consumes credits based on actual compute resources used.\n",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "Fully-qualified SQL name of the materialized view to refresh (e.g. \"dune.my_team.result_token_summary\")."
},
"performance": {
"enum": [
"small",
"medium",
"large"
],
"type": "string",
"default": "medium",
"description": "Performance tier for the refresh execution: \"small\", \"medium\", or \"large\". Defaults to \"medium\". Availability depends on the plan (\"small\" is typically free-plan only). Larger tiers cost more compute."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"execution_id",
"sql_names"
],
"properties": {
"sql_names": {
"type": "array",
"items": {
"type": "string"
},
"description": "Fully-qualified SQL table names of the refreshed materialized view."
},
"execution_id": {
"type": "string",
"description": "Execution ID of the triggered refresh. To wait for it to finish, pass it to getExecutionResults, which waits; do not poll getMaterializedView."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
List the schedules owned by the authenticated user or team: scheduled query executions, scheduled dashboard refreshes, and materialized view refreshes.
Use this tool when the user wants to:
- See what runs automatically and how often
- Read the current settings of a schedule before changing it with setSchedule
A schedule belongs to the owner of its query or dashboard, so a personal credential lists personal schedules and a team credential lists the team's schedules. Returns a paginated list; use limit and offset for pagination.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Number of schedules to return. Default 20, max 100.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
offset
Number of schedules to skip. Default 0.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"schedules",
"total"
],
"properties": {
"total": {
"type": "number",
"description": "Total number of schedules across all pages."
},
"schedules": {
"type": "array",
"items": {
"type": "object",
"required": [
"type"
],
"properties": {
"type": {
"enum": [
"query",
"dashboard",
"materialized_view"
],
"type": "string",
"description": "What the schedule runs. Change query and dashboard schedules with setSchedule and deleteSchedule, and materialized view refreshes with updateMaterializedView."
},
"query_id": {
"type": "number",
"description": "The scheduled query, when the schedule runs a query."
},
"expires_at": {
"type": "string",
"description": "ISO 8601 datetime after which the schedule stops running."
},
"performance": {
"type": "string",
"description": "Performance tier of each run: \"small\", \"medium\", or \"large\"."
},
"dashboard_id": {
"type": "number",
"description": "The scheduled dashboard, when the schedule refreshes one."
},
"cron_expression": {
"type": "string",
"description": "When the schedule runs, as a UTC cron expression."
},
"next_execution_time": {
"type": "string",
"description": "ISO 8601 datetime of the next run."
}
},
"additionalProperties": false
}
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "listSchedules",
"title": "List Schedules",
"description": "List the schedules owned by the authenticated user or team: scheduled query executions, scheduled dashboard refreshes, and materialized view refreshes.\n\nUse this tool when the user wants to:\n- See what runs automatically and how often\n- Read the current settings of a schedule before changing it with setSchedule\n\nA schedule belongs to the owner of its query or dashboard, so a personal credential lists personal schedules and a team credential lists the team's schedules. Returns a paginated list; use limit and offset for pagination.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"limit": {
"type": "integer",
"default": 20,
"maximum": 100,
"description": "Number of schedules to return. Default 20, max 100.",
"exclusiveMinimum": 0
},
"offset": {
"type": "integer",
"default": 0,
"maximum": 9007199254740991,
"minimum": 0,
"description": "Number of schedules to skip. Default 0."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"schedules",
"total"
],
"properties": {
"total": {
"type": "number",
"description": "Total number of schedules across all pages."
},
"schedules": {
"type": "array",
"items": {
"type": "object",
"required": [
"type"
],
"properties": {
"type": {
"enum": [
"query",
"dashboard",
"materialized_view"
],
"type": "string",
"description": "What the schedule runs. Change query and dashboard schedules with setSchedule and deleteSchedule, and materialized view refreshes with updateMaterializedView."
},
"query_id": {
"type": "number",
"description": "The scheduled query, when the schedule runs a query."
},
"expires_at": {
"type": "string",
"description": "ISO 8601 datetime after which the schedule stops running."
},
"performance": {
"type": "string",
"description": "Performance tier of each run: \"small\", \"medium\", or \"large\"."
},
"dashboard_id": {
"type": "number",
"description": "The scheduled dashboard, when the schedule refreshes one."
},
"cron_expression": {
"type": "string",
"description": "When the schedule runs, as a UTC cron expression."
},
"next_execution_time": {
"type": "string",
"description": "ISO 8601 datetime of the next run."
}
},
"additionalProperties": false
}
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Set the schedule of a saved Dune query or dashboard. Creates the schedule when there is none and replaces it when there is one. Returns the schedule as stored.
Use this tool when the user wants to:
- Run a saved query automatically on a schedule
- Refresh all queries of a dashboard on a schedule
- Change the frequency, performance tier, or expiration of an existing schedule
Important constraints:
- Set exactly one of query_id and dashboard_id.
- A query or a dashboard has at most one schedule. This call replaces all of its settings, so pass the current values of the settings you want to keep (listSchedules returns them).
- Every scheduled run is charged credits at the chosen performance tier, so prefer the smallest tier and the lowest frequency that meet the need.
- The schedule belongs to the owner of the query or dashboard. You need to own it or be an editor or admin of the team that owns it; a team credential can only schedule its own team's content. The owner's plan limits how many schedules it can have.
- On the free plan a schedule expires after at most 3 months; a later or omitted expires_at is capped to that.
- To schedule a materialized view refresh, use createMaterializedView or updateMaterializedView instead.
Supported cron expressions (5-part, UTC):
- "*/15 * * * *", "*/20 * * * *", "*/30 * * * *": every 15, 20 or 30 minutes
- "0 * * * *": hourly
- "0 */N * * *" with N in 2, 3, 4, 6, 8, 12: every N hours
- "M H * * *": daily at H:M
- "M H * * D": weekly on day D (0 = Sunday) at H:M
where M is 0 or 30 and H is 0-23.
The description explains the capability, when to use it, and what to expect.
Inputs77/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
query_id
ID of the query whose scheduled execution to change. Set exactly one of query_id and dashboard_id.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
dashboard_id
ID of the dashboard whose scheduled refresh to change. Set exactly one of query_id and dashboard_id.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
cron_expression
When to run, as a supported UTC cron expression, e.g. "0 6 * * *".
Clear enough to supply this argument.
performance
Performance tier for each run: "small", "medium", or "large". It must be available to the API on the owner's plan. Larger tiers cost more credits.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
expires_at
ISO 8601 datetime after which the schedule stops running. Null or omitted means no expiration, which the free plan caps at 3 months.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"created"
],
"properties": {
"created": {
"type": "boolean",
"description": "True when this call created the schedule, false when it replaced an existing one."
},
"query_id": {
"type": "number",
"description": "The scheduled query, when the schedule runs a query."
},
"expires_at": {
"type": "string",
"description": "ISO 8601 datetime after which the schedule stops running."
},
"performance": {
"type": "string",
"description": "Performance tier of each run: \"small\", \"medium\", or \"large\"."
},
"dashboard_id": {
"type": "number",
"description": "The scheduled dashboard, when the schedule refreshes one."
},
"cron_expression": {
"type": "string",
"description": "When the schedule runs, as a UTC cron expression."
},
"next_execution_time": {
"type": "string",
"description": "ISO 8601 datetime of the next run."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "setSchedule",
"title": "Set Schedule",
"description": "Set the schedule of a saved Dune query or dashboard. Creates the schedule when there is none and replaces it when there is one. Returns the schedule as stored.\n\nUse this tool when the user wants to:\n- Run a saved query automatically on a schedule\n- Refresh all queries of a dashboard on a schedule\n- Change the frequency, performance tier, or expiration of an existing schedule\n\nImportant constraints:\n- Set exactly one of query_id and dashboard_id.\n- A query or a dashboard has at most one schedule. This call replaces all of its settings, so pass the current values of the settings you want to keep (listSchedules returns them).\n- Every scheduled run is charged credits at the chosen performance tier, so prefer the smallest tier and the lowest frequency that meet the need.\n- The schedule belongs to the owner of the query or dashboard. You need to own it or be an editor or admin of the team that owns it; a team credential can only schedule its own team's content. The owner's plan limits how many schedules it can have.\n- On the free plan a schedule expires after at most 3 months; a later or omitted expires_at is capped to that.\n- To schedule a materialized view refresh, use createMaterializedView or updateMaterializedView instead.\n\nSupported cron expressions (5-part, UTC):\n- \"*/15 * * * *\", \"*/20 * * * *\", \"*/30 * * * *\": every 15, 20 or 30 minutes\n- \"0 * * * *\": hourly\n- \"0 */N * * *\" with N in 2, 3, 4, 6, 8, 12: every N hours\n- \"M H * * *\": daily at H:M\n- \"M H * * D\": weekly on day D (0 = Sunday) at H:M\nwhere M is 0 or 30 and H is 0-23.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"cron_expression",
"performance"
],
"properties": {
"query_id": {
"type": "integer",
"maximum": 9007199254740991,
"description": "ID of the query whose scheduled execution to change. Set exactly one of query_id and dashboard_id.",
"exclusiveMinimum": 0
},
"expires_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
],
"description": "ISO 8601 datetime after which the schedule stops running. Null or omitted means no expiration, which the free plan caps at 3 months."
},
"performance": {
"enum": [
"small",
"medium",
"large"
],
"type": "string",
"description": "Performance tier for each run: \"small\", \"medium\", or \"large\". It must be available to the API on the owner's plan. Larger tiers cost more credits."
},
"dashboard_id": {
"type": "integer",
"maximum": 9007199254740991,
"description": "ID of the dashboard whose scheduled refresh to change. Set exactly one of query_id and dashboard_id.",
"exclusiveMinimum": 0
},
"cron_expression": {
"type": "string",
"description": "When to run, as a supported UTC cron expression, e.g. \"0 6 * * *\"."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"created"
],
"properties": {
"created": {
"type": "boolean",
"description": "True when this call created the schedule, false when it replaced an existing one."
},
"query_id": {
"type": "number",
"description": "The scheduled query, when the schedule runs a query."
},
"expires_at": {
"type": "string",
"description": "ISO 8601 datetime after which the schedule stops running."
},
"performance": {
"type": "string",
"description": "Performance tier of each run: \"small\", \"medium\", or \"large\"."
},
"dashboard_id": {
"type": "number",
"description": "The scheduled dashboard, when the schedule refreshes one."
},
"cron_expression": {
"type": "string",
"description": "When the schedule runs, as a UTC cron expression."
},
"next_execution_time": {
"type": "string",
"description": "ISO 8601 datetime of the next run."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description89/100
Delete the schedule of a saved Dune query or dashboard, so it stops running automatically. Alerts that depend on the query schedule are deleted with it.
Use this tool when the user wants to stop a scheduled query execution or a scheduled dashboard refresh.
- Set exactly one of query_id and dashboard_id.
- You need to own the query or dashboard or be an editor or admin of the team that owns it; a team credential can only change its own team's content.
- Deleting when there is no schedule succeeds with deleted: false.
- To stop a materialized view refresh, use updateMaterializedView or deleteMaterializedView instead.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
query_id
ID of the query whose scheduled execution to change. Set exactly one of query_id and dashboard_id.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
dashboard_id
ID of the dashboard whose scheduled refresh to change. Set exactly one of query_id and dashboard_id.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"deleted"
],
"properties": {
"deleted": {
"type": "boolean",
"description": "True when a schedule was deleted, false when there was no schedule."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "deleteSchedule",
"title": "Delete Schedule",
"description": "Delete the schedule of a saved Dune query or dashboard, so it stops running automatically. Alerts that depend on the query schedule are deleted with it.\n\nUse this tool when the user wants to stop a scheduled query execution or a scheduled dashboard refresh.\n\n- Set exactly one of query_id and dashboard_id.\n- You need to own the query or dashboard or be an editor or admin of the team that owns it; a team credential can only change its own team's content.\n- Deleting when there is no schedule succeeds with deleted: false.\n- To stop a materialized view refresh, use updateMaterializedView or deleteMaterializedView instead.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"query_id": {
"type": "integer",
"maximum": 9007199254740991,
"description": "ID of the query whose scheduled execution to change. Set exactly one of query_id and dashboard_id.",
"exclusiveMinimum": 0
},
"dashboard_id": {
"type": "integer",
"maximum": 9007199254740991,
"description": "ID of the dashboard whose scheduled refresh to change. Set exactly one of query_id and dashboard_id.",
"exclusiveMinimum": 0
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"deleted"
],
"properties": {
"deleted": {
"type": "boolean",
"description": "True when a schedule was deleted, false when there was no schedule."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Render a Dune visualization inside the MCP App.
For brand-new SQL analysis, prefer createAndExecuteQuery with visualization input first, then call renderVisualization with the returned visualizationId/queryId/executionId when the client supports UI rendering.
When called, the MCP client mounts the Dune visualization app (an interactive HTML
resource served at `ui://dune/visualization.html`). The app reads the input
arguments, fetches the visualization config via `getVisualization`, resolves
the execution to render (using `executionId` if supplied, otherwise the latest
successful execution for `queryId`), and pulls the data via
`getExecutionResults`. The app may also re-execute the query against
`queryId` if needed.
Use this tool when the user wants to *see* a chart, counter, or table rendered
in their client. For inspecting the underlying config or data without rendering,
prefer `getVisualization` / `getExecutionResults`.
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
visualizationId
The Dune visualization ID to render.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
queryId
The query ID backing the visualization. The MCP App uses it to re-execute the query when no executionId is supplied or the latest execution is stale.
Clear enough to supply this argument.
executionId
Pass the execution ID returned by executeQueryById or createAndExecuteQuery whenever available. Supplying it skips the latest-execution lookup via getDuneQuery. If omitted, the MCP App looks up the latest execution for the query.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"visualizationId",
"queryId"
],
"properties": {
"queryId": {
"type": "number",
"description": "The query ID forwarded to the MCP App."
},
"executionId": {
"type": "string",
"description": "The execution ID forwarded to the MCP App, when supplied by the caller."
},
"visualizationId": {
"type": "number",
"description": "The visualization ID forwarded to the MCP App."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "renderVisualization",
"title": "Render Visualization",
"description": "Render a Dune visualization inside the MCP App.\n\nFor brand-new SQL analysis, prefer createAndExecuteQuery with visualization input first, then call renderVisualization with the returned visualizationId/queryId/executionId when the client supports UI rendering.\n\nWhen called, the MCP client mounts the Dune visualization app (an interactive HTML\nresource served at `ui://dune/visualization.html`). The app reads the input\narguments, fetches the visualization config via `getVisualization`, resolves\nthe execution to render (using `executionId` if supplied, otherwise the latest\nsuccessful execution for `queryId`), and pulls the data via\n`getExecutionResults`. The app may also re-execute the query against\n`queryId` if needed.\n\nUse this tool when the user wants to *see* a chart, counter, or table rendered\nin their client. For inspecting the underlying config or data without rendering,\nprefer `getVisualization` / `getExecutionResults`.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"visualizationId",
"queryId"
],
"properties": {
"queryId": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "The query ID backing the visualization. The MCP App uses it to re-execute the query when no executionId is supplied or the latest execution is stale."
},
"executionId": {
"type": "string",
"description": "Pass the execution ID returned by executeQueryById or createAndExecuteQuery whenever available. Supplying it skips the latest-execution lookup via getDuneQuery. If omitted, the MCP App looks up the latest execution for the query."
},
"visualizationId": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "The Dune visualization ID to render."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"visualizationId",
"queryId"
],
"properties": {
"queryId": {
"type": "number",
"description": "The query ID forwarded to the MCP App."
},
"executionId": {
"type": "string",
"description": "The execution ID forwarded to the MCP App, when supplied by the caller."
},
"visualizationId": {
"type": "number",
"description": "The visualization ID forwarded to the MCP App."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Submit up to 100 smart contracts for decoding on Dune. Each contract is validated and queued independently, and the result reports one entry per submission matched by index, so a bad ABI in one item does not fail the others. This is the same path as the form at dune.com/contracts/new.
Use this tool when the user wants to:
- Get decoded event and function-call tables for a contract (project_name_<chain>.ContractName_evt_<Event> / _call_<Function>).
- Refresh the ABI of an already decoded contract (submission_type "upgrade").
- Rename or delete a decoded contract they own, or ask for something else ("other").
Before submitting:
- Use listBlockchains for valid blockchain_name values, and searchTablesByContractAddress to check whether the address is already decoded (a new submission for an already decoded address is rejected).
- Provide the ABI. For verified contracts fetch it from the block explorer; for proxies submit the implementation's ABI and set is_proxy.
Important constraints:
- Submissions are attributed to the user behind this session. In a team context that user must be a member of the team.
- Free plans can submit new contracts for one blockchain per call. Batches spanning several blockchains, and any upgrade/rename/delete/other, require a paid plan (the team's plan in a team context).
- Upgrades, renames, deletions and protected namespaces always go to manual review; expect status "needs_manual_review" rather than automatic processing.
- project_name and contract_name are case-sensitive and become part of the table names; reuse the exact same values when submitting the same contract on more chains.
- Set idempotency_key (unique per account) when a client may retry: resubmitting a used key returns the existing submission with replayed=true instead of creating a duplicate.
Track progress with listContractSubmissions or at the returned status_url.
The description explains the capability, when to use it, and what to expect.
Inputs93/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
submissions › items › blockchain_name
Blockchain the contract is deployed on, e.g. "ethereum", "base". Must match a chain from listBlockchains.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
submissions › items › address
Contract address. 0x-prefixed hex for EVM chains; Tron base58 is accepted when blockchain_name is tron.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
submissions › items › project_name
Project (namespace) the decoded tables are grouped under, e.g. "uniswap". Case-sensitive.
Clear enough to supply this argument.
submissions › items › contract_name
Contract name used in the decoded table names, e.g. "UniswapToken". Case-sensitive.
Clear enough to supply this argument.
submissions › items › abi
The contract ABI: a non-empty JSON array of fragments, or a JSON string containing that array.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
submissions › items › has_multiple_instances
True for a dynamic contract with several deployed instances sharing this ABI.
Clear enough to supply this argument.
submissions › items › is_created_by_factory
True when the instances are created by a factory contract.
Clear enough to supply this argument.
submissions › items › is_manual_abi
True when the ABI was written or edited by hand rather than fetched from a block explorer.
Clear enough to supply this argument.
submissions › items › is_proxy
True when the address is a proxy and the ABI belongs to its implementation.
Clear enough to supply this argument.
submissions › items › submission_type
"new" (default) decodes a contract not yet decoded under this name; "upgrade" replaces the ABI; "rename" moves it to the new project_name/contract_name (old names required); "delete" removes the contract named by project_name/contract_name; "other" is a free-form request. Everything but "new" goes to manual review.
Clear enough to supply this argument.
submissions › items › resubmission_reason
Why the contract is being resubmitted. Required for "delete" and "other"; optional for "upgrade" and "rename".
Clear enough to supply this argument.
submissions › items › old_project_name
Current project name of the decoded contract. Required for "rename".
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
submissions › items › old_contract_name
Current contract name of the decoded contract. Required for "rename".
Clear enough to supply this argument.
submissions › items › idempotency_key
Client-chosen key, unique per account, that makes this item safe to retry. A key already used returns the existing submission with replayed=true.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"results",
"status_url"
],
"properties": {
"results": {
"type": "array",
"items": {
"type": "object",
"required": [
"index"
],
"properties": {
"error": {
"type": "string",
"description": "Why the item was rejected; set on failure."
},
"index": {
"type": "number",
"description": "Position of the corresponding item in the request."
},
"status": {
"enum": [
"pending",
"rejected",
"approved",
"processed",
"in_progress",
"cancelled",
"needs_manual_review"
],
"type": "string",
"description": "\"pending\" for a new submission, or the current status of the earlier submission when replayed; poll listContractSubmissions for progress."
},
"replayed": {
"type": "boolean",
"description": "True when idempotency_key matched an earlier submission and nothing new was created."
},
"submission_id": {
"type": "string",
"description": "Id of the submission; set on success."
}
},
"additionalProperties": false
},
"description": "One result per submitted item, in request order."
},
"status_url": {
"type": "string",
"description": "Page where the user can follow their submissions in the Dune UI."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "submitContractsForDecoding",
"title": "Submit Contracts for Decoding",
"description": "Submit up to 100 smart contracts for decoding on Dune. Each contract is validated and queued independently, and the result reports one entry per submission matched by index, so a bad ABI in one item does not fail the others. This is the same path as the form at dune.com/contracts/new.\n\nUse this tool when the user wants to:\n- Get decoded event and function-call tables for a contract (project_name_<chain>.ContractName_evt_<Event> / _call_<Function>).\n- Refresh the ABI of an already decoded contract (submission_type \"upgrade\").\n- Rename or delete a decoded contract they own, or ask for something else (\"other\").\n\nBefore submitting:\n- Use listBlockchains for valid blockchain_name values, and searchTablesByContractAddress to check whether the address is already decoded (a new submission for an already decoded address is rejected).\n- Provide the ABI. For verified contracts fetch it from the block explorer; for proxies submit the implementation's ABI and set is_proxy.\n\nImportant constraints:\n- Submissions are attributed to the user behind this session. In a team context that user must be a member of the team.\n- Free plans can submit new contracts for one blockchain per call. Batches spanning several blockchains, and any upgrade/rename/delete/other, require a paid plan (the team's plan in a team context).\n- Upgrades, renames, deletions and protected namespaces always go to manual review; expect status \"needs_manual_review\" rather than automatic processing.\n- project_name and contract_name are case-sensitive and become part of the table names; reuse the exact same values when submitting the same contract on more chains.\n- Set idempotency_key (unique per account) when a client may retry: resubmitting a used key returns the existing submission with replayed=true instead of creating a duplicate.\n\nTrack progress with listContractSubmissions or at the returned status_url.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"submissions"
],
"properties": {
"submissions": {
"type": "array",
"items": {
"type": "object",
"required": [
"blockchain_name",
"address",
"project_name",
"contract_name",
"abi"
],
"properties": {
"abi": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"minItems": 1
},
{
"type": "string",
"minLength": 1
}
],
"description": "The contract ABI: a non-empty JSON array of fragments, or a JSON string containing that array."
},
"address": {
"type": "string",
"minLength": 1,
"description": "Contract address. 0x-prefixed hex for EVM chains; Tron base58 is accepted when blockchain_name is tron."
},
"is_proxy": {
"type": "boolean",
"default": false,
"description": "True when the address is a proxy and the ABI belongs to its implementation."
},
"project_name": {
"type": "string",
"minLength": 1,
"description": "Project (namespace) the decoded tables are grouped under, e.g. \"uniswap\". Case-sensitive."
},
"contract_name": {
"type": "string",
"minLength": 1,
"description": "Contract name used in the decoded table names, e.g. \"UniswapToken\". Case-sensitive."
},
"is_manual_abi": {
"type": "boolean",
"default": false,
"description": "True when the ABI was written or edited by hand rather than fetched from a block explorer."
},
"blockchain_name": {
"type": "string",
"minLength": 1,
"description": "Blockchain the contract is deployed on, e.g. \"ethereum\", \"base\". Must match a chain from listBlockchains."
},
"idempotency_key": {
"type": "string",
"maxLength": 128,
"minLength": 1,
"description": "Client-chosen key, unique per account, that makes this item safe to retry. A key already used returns the existing submission with replayed=true."
},
"submission_type": {
"enum": [
"new",
"upgrade",
"rename",
"delete",
"other"
],
"type": "string",
"default": "new",
"description": "\"new\" (default) decodes a contract not yet decoded under this name; \"upgrade\" replaces the ABI; \"rename\" moves it to the new project_name/contract_name (old names required); \"delete\" removes the contract named by project_name/contract_name; \"other\" is a free-form request. Everything but \"new\" goes to manual review."
},
"old_project_name": {
"type": "string",
"description": "Current project name of the decoded contract. Required for \"rename\"."
},
"old_contract_name": {
"type": "string",
"description": "Current contract name of the decoded contract. Required for \"rename\"."
},
"resubmission_reason": {
"type": "string",
"maxLength": 1000,
"description": "Why the contract is being resubmitted. Required for \"delete\" and \"other\"; optional for \"upgrade\" and \"rename\"."
},
"is_created_by_factory": {
"type": "boolean",
"default": false,
"description": "True when the instances are created by a factory contract."
},
"has_multiple_instances": {
"type": "boolean",
"default": false,
"description": "True for a dynamic contract with several deployed instances sharing this ABI."
}
}
},
"maxItems": 100,
"minItems": 1,
"description": "Between 1 and 100 contracts to submit."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"results",
"status_url"
],
"properties": {
"results": {
"type": "array",
"items": {
"type": "object",
"required": [
"index"
],
"properties": {
"error": {
"type": "string",
"description": "Why the item was rejected; set on failure."
},
"index": {
"type": "number",
"description": "Position of the corresponding item in the request."
},
"status": {
"enum": [
"pending",
"rejected",
"approved",
"processed",
"in_progress",
"cancelled",
"needs_manual_review"
],
"type": "string",
"description": "\"pending\" for a new submission, or the current status of the earlier submission when replayed; poll listContractSubmissions for progress."
},
"replayed": {
"type": "boolean",
"description": "True when idempotency_key matched an earlier submission and nothing new was created."
},
"submission_id": {
"type": "string",
"description": "Id of the submission; set on success."
}
},
"additionalProperties": false
},
"description": "One result per submitted item, in request order."
},
"status_url": {
"type": "string",
"description": "Page where the user can follow their submissions in the Dune UI."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
List the contract decoding submissions made by the user behind this session, newest first. Use it to check the status of contracts submitted with submitContractsForDecoding (or through the Dune UI).
Statuses: "pending" (queued, picked up within about a minute), "approved" (about to be decoded), "processed" (decoded tables are available), "needs_manual_review" (waiting for a Dune team member; always the case for upgrades, renames, deletions and protected namespaces), "rejected" (see comment for why), "in_progress" and "cancelled" (manual handling).
Filters are combined with AND. Results are paged: pass next_cursor from a response back as cursor to fetch the next page.
Do not call this tool in a loop to wait for a status change. Decoding takes minutes, and manual review can take days. While a submission is "pending" or "approved", check again no sooner than a few minutes later. Stop checking once a submission is "processed", "rejected", "needs_manual_review" or "cancelled": tell the user the status instead.
The description explains the capability, when to use it, and what to expect.
Inputs82/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
blockchain_name
Filter by blockchain, e.g. "ethereum".
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
address
Filter by the full contract address (0x...), as submitted. The match is exact but not case-sensitive.
Clear enough to supply this argument.
project_name
Filter by project (namespace) name, the first part of the decoded table names (e.g. uniswap_v3 in uniswap_v3_ethereum.Factory_evt_PoolCreated). The match is exact and case-sensitive.
Clear enough to supply this argument.
contract_name
Filter by contract name.
Explain the meaning of this value, not just its name.
status
Filter by submission status.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Maximum number of submissions to return (default 50, max 250).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
cursor
next_cursor from a previous response, to fetch the next page.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"submissions",
"total"
],
"properties": {
"total": {
"type": "number",
"description": "Total number of submissions matching the filters across all pages."
},
"next_cursor": {
"type": "string",
"description": "Present when more results exist; pass it back as cursor."
},
"submissions": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"blockchain_name",
"address",
"project_name",
"contract_name",
"status",
"submission_type",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string"
},
"status": {
"enum": [
"pending",
"rejected",
"approved",
"processed",
"in_progress",
"cancelled",
"needs_manual_review"
],
"type": "string"
},
"address": {
"type": "string"
},
"comment": {
"type": "string",
"description": "Reviewer or system comment explaining the current status."
},
"created_at": {
"type": "string",
"description": "ISO 8601 timestamp."
},
"updated_at": {
"type": "string",
"description": "ISO 8601 timestamp."
},
"project_name": {
"type": "string"
},
"contract_name": {
"type": "string"
},
"blockchain_name": {
"type": "string"
},
"idempotency_key": {
"type": "string",
"description": "The idempotency key the submission was created with, if any."
},
"submission_type": {
"enum": [
"new",
"upgrade",
"rename",
"delete",
"other"
],
"type": "string"
}
},
"additionalProperties": false
}
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "listContractSubmissions",
"title": "List Contract Submissions",
"description": "List the contract decoding submissions made by the user behind this session, newest first. Use it to check the status of contracts submitted with submitContractsForDecoding (or through the Dune UI).\n\nStatuses: \"pending\" (queued, picked up within about a minute), \"approved\" (about to be decoded), \"processed\" (decoded tables are available), \"needs_manual_review\" (waiting for a Dune team member; always the case for upgrades, renames, deletions and protected namespaces), \"rejected\" (see comment for why), \"in_progress\" and \"cancelled\" (manual handling).\n\nFilters are combined with AND. Results are paged: pass next_cursor from a response back as cursor to fetch the next page.\n\nDo not call this tool in a loop to wait for a status change. Decoding takes minutes, and manual review can take days. While a submission is \"pending\" or \"approved\", check again no sooner than a few minutes later. Stop checking once a submission is \"processed\", \"rejected\", \"needs_manual_review\" or \"cancelled\": tell the user the status instead.",
"inputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"limit": {
"type": "integer",
"default": 50,
"maximum": 250,
"minimum": 1,
"description": "Maximum number of submissions to return (default 50, max 250)."
},
"cursor": {
"type": "string",
"description": "next_cursor from a previous response, to fetch the next page."
},
"status": {
"enum": [
"pending",
"rejected",
"approved",
"processed",
"in_progress",
"cancelled",
"needs_manual_review"
],
"type": "string",
"description": "Filter by submission status."
},
"address": {
"type": "string",
"description": "Filter by the full contract address (0x...), as submitted. The match is exact but not case-sensitive."
},
"project_name": {
"type": "string",
"description": "Filter by project (namespace) name, the first part of the decoded table names (e.g. uniswap_v3 in uniswap_v3_ethereum.Factory_evt_PoolCreated). The match is exact and case-sensitive."
},
"contract_name": {
"type": "string",
"description": "Filter by contract name."
},
"blockchain_name": {
"type": "string",
"description": "Filter by blockchain, e.g. \"ethereum\"."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"submissions",
"total"
],
"properties": {
"total": {
"type": "number",
"description": "Total number of submissions matching the filters across all pages."
},
"next_cursor": {
"type": "string",
"description": "Present when more results exist; pass it back as cursor."
},
"submissions": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"blockchain_name",
"address",
"project_name",
"contract_name",
"status",
"submission_type",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string"
},
"status": {
"enum": [
"pending",
"rejected",
"approved",
"processed",
"in_progress",
"cancelled",
"needs_manual_review"
],
"type": "string"
},
"address": {
"type": "string"
},
"comment": {
"type": "string",
"description": "Reviewer or system comment explaining the current status."
},
"created_at": {
"type": "string",
"description": "ISO 8601 timestamp."
},
"updated_at": {
"type": "string",
"description": "ISO 8601 timestamp."
},
"project_name": {
"type": "string"
},
"contract_name": {
"type": "string"
},
"blockchain_name": {
"type": "string"
},
"idempotency_key": {
"type": "string",
"description": "The idempotency key the submission was created with, if any."
},
"submission_type": {
"enum": [
"new",
"upgrade",
"rename",
"delete",
"other"
],
"type": "string"
}
},
"additionalProperties": false
}
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
Loading score analytics…
Put your MCP to the test
A few tasks worth trying with this server, chosen from its reviewed tools. These have not been run.
01Search TablesNatural-language table discovery across the Dune catalog.
02Search Dune DocsNatural-language query of the Dune docs at docs.dune.com.
03List BlockchainsList indexed blockchain values with table counts, optionally filtered by category/query.
04List Dune foldersList folders the caller may access (same rules as the Dune app: team membership and parent-folder visibility).
05Search Dune queriesSearch for Dune queries by name (case-insensitive substring match).
Want to run these tasks against your MCP server with us?
Dune setup, tools, quality score, publishing readiness, and alternatives.
How do I add Dune to Claude, ChatGPT, or Cursor?
Add Dune to Claude, ChatGPT, or Cursor by connecting its remote MCP URL in each client's MCP settings. In Claude, add a custom connector. In ChatGPT, add an MCP app. In Cursor, add an MCP server under Settings. The MCP URL is https://api.dune.com/mcp/v1.
Is Dune MCP ready for ChatGPT and Claude?
As of November 12, 2026, Dune scores 96/100 on Manufact's MCP publishing checklist. The scan does not yet meet ChatGPT publishing checks and meets Claude publishing checks. Passing these checks does not guarantee marketplace approval.
How clear is Dune's MCP tool documentation?
As of November 12, 2026, Dune scores 92/100 in Manufact's review of tool titles, descriptions, input and output schemas, and behavior annotations. The review covers 43 of 43 discovered tools. The quality score measures documentation clarity; runtime behavior and marketplace readiness require separate checks.
What are the best alternatives to Dune?
As of November 13, 2026, alternatives to Dune in data-analytics on the Manufact MCP leaderboard include Polygraph, Neon, ClickHouse Cloud MCP Server, Crash Round Lab, and Ploti.
Not your MCP?
Review any public or OAuth MCP server for protocol compatibility, tool documentation, and ChatGPT and Claude publishing readiness. No account required.