{
  "id": "surf.onchain.sql",
  "object": "tool",
  "name": "Blockchain SQL Query",
  "summary": "Run a read-only ClickHouse SQL query against on-chain data (joins, aggregations, custom windows) with a 30s timeout.",
  "description": "Run a read-only ClickHouse SQL query against on-chain data — joins, aggregations, and custom windows the fixed endpoints cannot express. 111 tables in the agent database (discover with /onchain/schema), max 10000 rows, 30s timeout. 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'). Timestamps in results are Unix seconds, even for Date columns. A timeout answers 408 with recommended_action use_async_job — submit the same SQL to /onchain/sql/jobs instead of retrying here. Estimate cost/validity first with /onchain/sql/preflight. Refresh: ~24h.\n\nRaw surf#onchain/sql endpoint: input is { body, queryParams, pathParams } as the provider documents them (https://docs.asksurf.ai/data-api/onchain/sql).",
  "category": "lookup",
  "hosted_by": "Surf",
  "runtime": "partner",
  "side_effects": false,
  "status": "live",
  "credits": 0,
  "price": null,
  "providers": [
    {
      "id": "surf",
      "name": "Surf",
      "price": null,
      "own_key_only": true
    }
  ],
  "mcp_name": "surf_onchain_sql",
  "input_schema": {
    "type": "object",
    "properties": {
      "body": {
        "type": "object",
        "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": {
            "default": 1000,
            "type": "integer",
            "minimum": 1,
            "maximum": 10000,
            "description": "Maximum rows to return. Example: 100. Defaults to 1000 (server-side), capped at 10000."
          }
        },
        "required": [
          "sql"
        ],
        "additionalProperties": false
      }
    },
    "required": [
      "body"
    ],
    "additionalProperties": false
  },
  "kind": "endpoint"
}