{
  "id": "surf.onchain.query",
  "object": "tool",
  "name": "Blockchain Structured Query",
  "summary": "Query on-chain tables with structured JSON filters — no SQL text.",
  "description": "Query on-chain tables with structured JSON filters — no SQL text. Pick a source table (discover with /onchain/schema), then filter (eq/gt/gte/lt/lte/like/in), sort, and limit (max 10000 rows, 30s timeout). ALWAYS filter on block_date for large tables. Never filter by symbol — resolve tickers to contract addresses with /search/token and filter contract_address instead. On transfer tables amount is decimal-adjusted; amount_raw is base units. Timestamps in results are Unix seconds, even for Date columns. For joins or aggregations write SQL via /onchain/sql. Refresh: ~24h.\n\nRaw surf#onchain/query endpoint: input is { body, queryParams, pathParams } as the provider documents them (https://docs.asksurf.ai/data-api/onchain/query).",
  "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_query",
  "input_schema": {
    "type": "object",
    "properties": {
      "body": {
        "type": "object",
        "properties": {
          "source": {
            "type": "string",
            "pattern": "^agent\\.[a-z0-9_]+$",
            "description": "Fully-qualified table name. Discover tables with /onchain/schema. Example: agent.ethereum_dex_trades."
          },
          "fields": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1
            },
            "description": "Columns to return. Omit to return all columns. Example: [\"block_time\", \"amount_usd\"]."
          },
          "filters": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "field": {
                  "type": "string",
                  "minLength": 1,
                  "description": "Column name to filter on. Example: block_date. Never filter on symbol columns (unindexed; resolve tickers to contract addresses with /search/token first)."
                },
                "op": {
                  "type": "string",
                  "enum": [
                    "eq",
                    "neq",
                    "gt",
                    "gte",
                    "lt",
                    "lte",
                    "like",
                    "in",
                    "not_in"
                  ],
                  "description": "Comparison operator. For in/not_in, value must be a JSON array. Example: gte."
                },
                "value": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "number"
                    },
                    {
                      "type": "boolean"
                    },
                    {
                      "type": "array",
                      "items": {
                        "type": [
                          "string",
                          "number"
                        ]
                      }
                    }
                  ],
                  "description": "Comparison value; a JSON array for in/not_in. Example: 2026-07-01."
                }
              },
              "required": [
                "field",
                "op",
                "value"
              ],
              "additionalProperties": false
            },
            "description": "WHERE conditions, ANDed together. ALWAYS include a block_date bound on large tables — without it the query times out. Example: [{\"field\": \"block_date\", \"op\": \"gte\", \"value\": \"2026-07-01\"}]."
          },
          "sort": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "field": {
                  "type": "string",
                  "minLength": 1,
                  "description": "Column name to sort by. Example: amount_usd."
                },
                "order": {
                  "type": "string",
                  "enum": [
                    "asc",
                    "desc"
                  ],
                  "description": "Sort direction. Example: desc. Defaults to \"asc\"."
                }
              },
              "required": [
                "field"
              ],
              "additionalProperties": false
            },
            "description": "ORDER BY clauses. Example: [{\"field\": \"amount_usd\", \"order\": \"desc\"}]."
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10000,
            "description": "Max rows to return. Example: 20. Defaults to 20 (server-side), capped at 10000."
          },
          "offset": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Rows to skip for pagination. Example: 0. Defaults to 0."
          }
        },
        "required": [
          "source"
        ],
        "additionalProperties": false
      }
    },
    "required": [
      "body"
    ],
    "additionalProperties": false
  },
  "kind": "endpoint"
}