Skip to content
Eden Engine

Custom On-Chain SQL Query (ClickHouse, Read-Only)

omnial/onchain-sql

Runs a customer-supplied, read-only ClickHouse SQL query (SELECT/WITH only) against curated on-chain datasets such as Ethereum DEX trades and token transfers, and returns the matching rows. A non-SELECT query (e.g. DELETE, UPDATE) is rejected before it runs.

activeper callv4

Price

$0.0328 per call

You pay the price shown. If a call turns out to cost more than its quote, you pay the actual price, capped at twice the quote. No monthly minimum. Top-ups start at $5.00.

Data source

Public blockchains and CoinGecko

Blockchain data from public chains. Prices powered by CoinGecko.

Use it

Your AI assistant does the work: it finds this tool, shows you the price first, runs it, and you are charged when the run finishes. There is nothing to set up for this tool in particular.

Connect once and your AI can find and run this tool, and any other it needs.

For developers: the calls your assistant makes
agent
// 1. search: find the tool
omnial_search({ query: "what you need" })

// 2. inspect: price and input schema
omnial_inspect({ tool: "omnial/onchain-sql" })

// 3. learn: read the usage guide at runtime
omnial_learn({ tool: "omnial/onchain-sql" })

// 4. run: price the exact call first, then run it
omnial_execute({ tool: "omnial/onchain-sql", input: { /* see input_schema */ }, dry_run: true })
omnial_execute({ tool: "omnial/onchain-sql", input: { /* ... */ } })

// 5. settle: the call is charged when it finishes, nothing to do

Not connected yet? Point your MCP client at https://mcp.eden-engine.com/mcp, then copy a config for your client.

Pricing

Every charge this tool can incur.

ChargePrice
Per call
$0.0328
Updated
Oct 27, 2026

Input and output schemas

Input schema
input_schema.json
{
  "type": "object",
  "required": [
    "sql"
  ],
  "properties": {
    "sql": {
      "type": "string",
      "minLength": 1,
      "description": "Read-only ClickHouse SELECT/WITH query. Discover tables with /onchain/schema. Rules (server-enforced or query-killing): SELECT/WITH only (read-only); table references must be database-qualified as agent.<table>; ALWAYS filter on block_date or block_number (partition key — without it the query times out); compare address columns directly against lowercase literals (wrapping the column in lower() is rejected); never filter on symbol columns (unindexed full scan, and symbol matches surface scam clones — resolve a ticker to a contract address with /search/token first); on transfer tables use separate UNION ALL branches instead of OR across from/to; use single quotes for strings, e.g. toDate('2026-04-07'). Example: SELECT block_date, sum(amount_usd) FROM agent.ethereum_dex_trades WHERE block_date >= today() - 7 GROUP BY block_date."
    },
    "max_rows": {
      "type": "integer",
      "default": 1000,
      "maximum": 10000,
      "minimum": 1,
      "description": "Maximum rows to return. Example: 100. Defaults to 1000 (server-side), capped at 10000."
    }
  },
  "additionalProperties": false
}
Output schema
output_schema.json
{
  "type": "object",
  "properties": {
    "code": {
      "type": "string",
      "description": "Present only when the query is rejected instead of executed (e.g. a non-SELECT query caught by the read-only guard). Observed as 'HTTP_400' on the one real rejected query."
    },
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "trades": {
            "type": "number",
            "description": "Row count for the day, when the query aliases its count() column as `trades`. Only present when the SELECT list computes it."
          },
          "block_date": {
            "type": "number",
            "description": "Unix seconds for the day bucket, observed when the query groups by a block_date column. Only present when the SELECT list includes it."
          },
          "volume_usd": {
            "type": [
              "number",
              "null"
            ],
            "description": "Summed USD volume for the day, when the query aliases its sum() column as `volume_usd`. Only present when the SELECT list computes it. Null for the current, still-incomplete day when no priced trades have settled yet."
          }
        },
        "additionalProperties": true
      },
      "description": "Result rows. Only observed with one real query (a daily Ethereum DEX trade-count and volume aggregation) -- a different SELECT list returns different column names entirely; the fields below describe that one observed shape, not a fixed schema."
    },
    "meta": {
      "type": "object",
      "properties": {
        "limit": {
          "type": "number",
          "description": "Effective row limit applied, echoing max_rows."
        },
        "total": {
          "type": "number",
          "description": "Total row count for the query."
        },
        "cached": {
          "type": "boolean"
        },
        "offset": {
          "type": "number"
        }
      },
      "additionalProperties": true
    },
    "message": {
      "type": "string",
      "description": "Human-readable rejection reason, present only alongside `code`."
    }
  },
  "description": "The query's result rows, or an error object when the query is rejected instead of executed.",
  "additionalProperties": true
}