Skip to main content
Glama

Secedgar Dataframe Query

secedgar_dataframe_query
Read-onlyIdempotent

Run a single-statement SELECT against the canvas dataframes registered by the data-returning secedgar_* tools — any tool whose response carries a dataset handle. Inspect a dataframe with secedgar_dataframe_describe first; its column schema is what the SQL has to match. Read-only: writes, DDL, DROP, COPY, PRAGMA, ATTACH, and external-file table functions are rejected. System catalogs (information_schema, pg_catalog, sqlite_master, duckdb_*) are denied — list dataframes via secedgar_dataframe_describe. Optional register_as chains the result as a new dataframe with a fresh TTL.

Input Schema

NameRequiredDescriptionDefault
sqlYesSingle-statement SELECT against df_<id> tables on the shared canvas. Standard DuckDB SQL — joins, aggregates, window functions, CTEs all supported. Reference dataframes by the names returned in fetch/search responses or listed by secedgar_dataframe_describe. BIGINT columns (e.g., XBRL `value`, COUNT/SUM results) serialize as JSON strings to preserve precision past 2^53 — CAST(col AS DOUBLE) in projections for inline arithmetic.
previewNoRows to include in the immediate response. Defaults to the row limit. Set lower (e.g., 50) when chaining via register_as and only a sample is needed inline. Capped at 10000: a larger value, up to 100000, returns what 10000 returns.
row_limitNoHard cap on rows materialized in the response. Default 1000. A query matching more rows than this stops at the cap and `row_count_capped` comes back true; the full result lives on-canvas under register_as when provided, so do not raise this to keep large results. One case is not detectable: a SQL LIMIT exactly equal to this cap reads identically to a result that genuinely holds that many rows, and is reported as exact. Capped at 10000: a larger value, up to 100000, returns what 10000 returns.
register_asNoWhen set, persist the result as a new dataframe under this name (must match df_XXXXX_XXXXX shape, or pass a fresh df_<id> generated by the agent). Fresh TTL window — not inherited from the parents in the SELECT. Use to chain analyses without re-running the source SQL.

Output Schema

NameRequiredDescriptionDefault
capNoThe row cap that actually bound — `preview` when it is lower than `row_limit`, otherwise `row_limit`.
rowsNoMaterialized rows, bounded by `preview` / `row_limit`.
errorNoPresent when the call failed. Absent on success.
shownNoNumber of rows returned inline.
noticeNoGuidance when the query returned no rows, or when the row cap withheld some.
columnsNoColumn names in projection order.
row_countNoRows the query produced, up to `row_limit`; exceeds `rows.length` when `preview` returned fewer. When `row_count_capped` is true this is the cap, not the full size.
truncatedNoTrue when the result set held more rows than the row cap allowed through.
expires_atNoISO 8601 expiry timestamp for the newly registered dataframe, when applicable.
registered_asNoSet when `register_as` was supplied and the new dataframe was materialized.
row_count_cappedNoTrue when more rows matched than `row_limit`, so `row_count` is the cap; false means `row_count` is exact.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed5 schema fields changed
    • changedInput schema / properties / preview / description
      Previous value: -"Rows to include in the immediate response. Defaults to the row limit. Set lower (e.g., 50) when chaining via register_as and only a sample is needed inline."New value: +"Rows to include in the immediate response. Defaults to the row limit. Set lower (e.g., 50) when chaining via register_as and only a sample is needed inline. Capped at 10000: a larger value, up to 100000, returns what 10000 returns."
    • changedInput schema / properties / preview / maximum
      Previous value: -10000New value: +100000
    • changedInput schema / properties / row_limit / description
      Previous value: -"Hard cap on rows materialized in the response. Default 1000, max 10000. A query matching more rows than this stops at the cap and `row_count_capped` comes back true; the full result lives on-canvas under register_as when provided, so do not raise this to keep large results. One case is not detectable: a SQL LIMIT exactly equal to this cap reads identically to a result that genuinely holds that many rows, and is reported as exact."New value: +"Hard cap on rows materialized in the response. Default 1000. A query matching more rows than this stops at the cap and `row_count_capped` comes back true; the full result lives on-canvas under register_as when provided, so do not raise this to keep large results. One case is not detectable: a SQL LIMIT exactly equal to this cap reads identically to a result that genuinely holds that many rows, and is reported as exact. Capped at 10000: a larger value, up to 100000, returns what 10000 returns."
    • changedInput schema / properties / row_limit / maximum
      Previous value: -10000New value: +100000
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `canvas_unavailable`: The DataCanvas service is not configured for this deployment. `system_catalog_access`: The SQL query references a denied DuckDB system catalog (information_schema, pg_catalog, sqlite_master, duckdb_*). `missing_table`: The SQL query references a df_<id> table that does not exist or has expired. `invalid_sql`: The SELECT fails to prepare — an unknown column or an invalid expression — or hits an engine error no more specific reason covers. `sql_execution_error`: The SELECT prepared but failed on the data it read — a cast or conversion that does not fit, an out-of-range value, or invalid input to a function. `register_as_clash`: The register_as target name already exists on the canvas. `non_select_statement`: The SQL is not a SELECT (DROP, INSERT, UPDATE, DDL, PRAGMA, EXPLAIN, etc.) or does not parse — only read-only SELECTs run against dataframes. `multi_statement`: The SQL holds more than one statement. `denied_function`: The SQL calls a file-reading or external-data table function (read_csv, read_parquet, glob), a function that reads an engine setting (current_setting, current_schema), or one that runs SQL or names a table from a string (query_table, or query() over anything but a single string literal). `sql_read_only`: The SQL names a file as a table (FROM 'data.csv') — the dataframe engine reads no files. `plan_operator_not_allowed`: The query plan uses an operator outside the read-only allowlist, such as the range() or generate_series() table functions. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `canvas_unavailable`: The DataCanvas service is not configured for this deployment. `system_catalog_access`: The SQL query references a denied DuckDB system catalog (information_schema, pg_catalog, sqlite_master, duckdb_*). `missing_table`: The SQL query references a df_<id> table that does not exist or has expired. `invalid_sql`: The SELECT fails to prepare — an unknown column or an invalid expression — or hits an engine error no more specific reason covers. `sql_execution_error`: The SELECT prepared but failed on the data it read — a cast or conversion that does not fit, an out-of-range value, or invalid input to a function. `register_as_clash`: The register_as target name already exists on the canvas. `non_select_statement`: The SQL is not a SELECT (DROP, INSERT, UPDATE, DDL, PRAGMA, EXPLAIN, etc.) or does not parse — only read-only SELECTs run against dataframes. `multi_statement`: The SQL holds more than one statement. `denied_function`: The SQL calls a file-reading or external-data table function (read_csv, read_parquet, glob), a function that reads an engine setting (current_setting, current_schema — an unqualified current_schema is refused even where it names a column, which reads qualified as <table>.current_schema), or one that runs SQL or names a table from a string (query_table, or query() over anything but a single string literal). `sql_read_only`: The SQL names a file as a table (FROM 'data.csv') — the dataframe engine reads no files. `plan_operator_not_allowed`: The query plan uses an operator outside the read-only allowlist, such as the range() or generate_series() table functions. Other values are possible when a failure originates below the handler."
  2. Changed2 schema fields changed
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `canvas_unavailable`: The DataCanvas service is not configured for this deployment. `system_catalog_access`: The SQL query references a denied DuckDB system catalog (information_schema, pg_catalog, sqlite_master, duckdb_*). `missing_table`: The SQL query references a df_<id> table that does not exist or has expired. `invalid_sql`: The SELECT fails to prepare — an unknown column or an invalid expression — or hits an engine error no more specific reason covers. `sql_execution_error`: The SELECT prepared but failed on the data it read — a cast or conversion that does not fit, an out-of-range value, or invalid input to a function. `register_as_clash`: The register_as target name already exists on the canvas. `non_select_statement`: The SQL is not a SELECT (DROP, INSERT, UPDATE, DDL, PRAGMA, EXPLAIN, etc.) or does not parse — only read-only SELECTs run against dataframes. `multi_statement`: The SQL holds more than one statement. `denied_function`: The SQL calls a file-reading or external-data table function such as read_csv, read_parquet, or glob. `plan_operator_not_allowed`: The query plan uses an operator outside the read-only allowlist, such as the range() or generate_series() table functions. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `canvas_unavailable`: The DataCanvas service is not configured for this deployment. `system_catalog_access`: The SQL query references a denied DuckDB system catalog (information_schema, pg_catalog, sqlite_master, duckdb_*). `missing_table`: The SQL query references a df_<id> table that does not exist or has expired. `invalid_sql`: The SELECT fails to prepare — an unknown column or an invalid expression — or hits an engine error no more specific reason covers. `sql_execution_error`: The SELECT prepared but failed on the data it read — a cast or conversion that does not fit, an out-of-range value, or invalid input to a function. `register_as_clash`: The register_as target name already exists on the canvas. `non_select_statement`: The SQL is not a SELECT (DROP, INSERT, UPDATE, DDL, PRAGMA, EXPLAIN, etc.) or does not parse — only read-only SELECTs run against dataframes. `multi_statement`: The SQL holds more than one statement. `denied_function`: The SQL calls a file-reading or external-data table function (read_csv, read_parquet, glob), a function that reads an engine setting (current_setting, current_schema), or one that runs SQL or names a table from a string (query_table, or query() over anything but a single string literal). `sql_read_only`: The SQL names a file as a table (FROM 'data.csv') — the dataframe engine reads no files. `plan_operator_not_allowed`: The query plan uses an operator outside the read-only allowlist, such as the range() or generate_series() table functions. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "canvas_unavailable",
      -  "system_catalog_access",
      -  "missing_table",
      -  "invalid_sql",
      -  "sql_execution_error",
      -  "register_as_clash",
      -  "non_select_statement",
      -  "multi_statement",
      -  "denied_function",
      -  "plan_operator_not_allowed"
      -]New value: +[
      +  "canvas_unavailable",
      +  "system_catalog_access",
      +  "missing_table",
      +  "invalid_sql",
      +  "sql_execution_error",
      +  "register_as_clash",
      +  "non_select_statement",
      +  "multi_statement",
      +  "denied_function",
      +  "sql_read_only",
      +  "plan_operator_not_allowed"
      +]
  3. Changed2 schema fields changed
    • changedOutput schema / properties / row_count / description
      Previous value: -"Rows the query produced, up to `row_limit` (exceeds `rows.length` when `preview` returned fewer). Read it with `row_count_capped`: when that is true this number is the `row_limit` cap itself, and the size of the full result is not in this response."New value: +"Rows the query produced, up to `row_limit`; exceeds `rows.length` when `preview` returned fewer. When `row_count_capped` is true this is the cap, not the full size."
    • changedOutput schema / properties / row_count_capped / description
      Previous value: -"True when the query matched more rows than `row_limit`, so `row_count` is that cap rather than a total. False means `row_count` is exact — including when it happens to equal `row_limit`."New value: +"True when more rows matched than `row_limit`, so `row_count` is the cap; false means `row_count` is exact."
  4. Changed2 schema fields changed
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `canvas_unavailable`: The DataCanvas service is not configured for this deployment `system_catalog_access`: The SQL query references a denied DuckDB system catalog (information_schema, pg_catalog, sqlite_master, duckdb_*) `missing_table`: The SQL query references a df_<id> table that does not exist or has expired `invalid_sql`: The SQL statement contains a syntax or execution error not covered by a more specific reason `register_as_clash`: The register_as target name already exists on the canvas `non_select_statement`: The SQL is a non-SELECT statement (DROP, INSERT, UPDATE, DDL, etc.) — only read-only SELECTs run against dataframes Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `canvas_unavailable`: The DataCanvas service is not configured for this deployment. `system_catalog_access`: The SQL query references a denied DuckDB system catalog (information_schema, pg_catalog, sqlite_master, duckdb_*). `missing_table`: The SQL query references a df_<id> table that does not exist or has expired. `invalid_sql`: The SELECT fails to prepare — an unknown column or an invalid expression — or hits an engine error no more specific reason covers. `sql_execution_error`: The SELECT prepared but failed on the data it read — a cast or conversion that does not fit, an out-of-range value, or invalid input to a function. `register_as_clash`: The register_as target name already exists on the canvas. `non_select_statement`: The SQL is not a SELECT (DROP, INSERT, UPDATE, DDL, PRAGMA, EXPLAIN, etc.) or does not parse — only read-only SELECTs run against dataframes. `multi_statement`: The SQL holds more than one statement. `denied_function`: The SQL calls a file-reading or external-data table function such as read_csv, read_parquet, or glob. `plan_operator_not_allowed`: The query plan uses an operator outside the read-only allowlist, such as the range() or generate_series() table functions. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "canvas_unavailable",
      -  "system_catalog_access",
      -  "missing_table",
      -  "invalid_sql",
      -  "register_as_clash",
      -  "non_select_statement"
      -]New value: +[
      +  "canvas_unavailable",
      +  "system_catalog_access",
      +  "missing_table",
      +  "invalid_sql",
      +  "sql_execution_error",
      +  "register_as_clash",
      +  "non_select_statement",
      +  "multi_statement",
      +  "denied_function",
      +  "plan_operator_not_allowed"
      +]
  5. Changed4 schema fields changed
    • changedInput schema / properties / row_limit / description
      Previous value: -"Hard cap on rows materialized in the response. Default 1000, max 10000. The full result lives on-canvas under register_as when provided — do not raise this to keep large results."New value: +"Hard cap on rows materialized in the response. Default 1000, max 10000. A query matching more rows than this stops at the cap and `row_count_capped` comes back true; the full result lives on-canvas under register_as when provided, so do not raise this to keep large results. One case is not detectable: a SQL LIMIT exactly equal to this cap reads identically to a result that genuinely holds that many rows, and is reported as exact."
    • changedOutput schema / anyOf
      Previous value: -[
      -  {
      -    "not": {
      -      "required": [
      -        "error"
      -      ]
      -    },
      -    "required": [
      -      "columns",
      -      "row_count",
      -      "rows"
      -    ]
      -  },
      -  {
      -    "required": [
      -      "error"
      -    ]
      -  }
      -]New value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "columns",
      +      "row_count",
      +      "row_count_capped",
      +      "rows"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • changedOutput schema / properties / row_count / description
      Previous value: -"Total rows the query produced (may exceed `rows.length` when capped)."New value: +"Rows the query produced, up to `row_limit` (exceeds `rows.length` when `preview` returned fewer). Read it with `row_count_capped`: when that is true this number is the `row_limit` cap itself, and the size of the full result is not in this response."
    • addedOutput schema / properties / row_count_capped
      Added value: +{
      +  "description": "True when the query matched more rows than `row_limit`, so `row_count` is that cap rather than a total. False means `row_count` is exact — including when it happens to equal `row_limit`.",
      +  "type": "boolean"
      +}
  6. Changed10 schema fields changed
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedInput schema / additionalProperties
      Added value: +false
    • changedOutput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedOutput schema / anyOf
      Added value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "columns",
      +      "row_count",
      +      "rows"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • addedOutput schema / properties / cap
      Added value: +{
      +  "description": "The row cap that actually bound — `preview` when it is lower than `row_limit`, otherwise `row_limit`.",
      +  "type": "number"
      +}
    • addedOutput schema / properties / error
      Added value: +{
      +  "additionalProperties": {},
      +  "description": "Present when the call failed. Absent on success.",
      +  "properties": {
      +    "code": {
      +      "description": "JSON-RPC error code for this failure.",
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    },
      +    "data": {
      +      "additionalProperties": {},
      +      "properties": {
      +        "reason": {
      +          "description": "Machine-readable failure mode. Declared by this tool: `canvas_unavailable`: The DataCanvas service is not configured for this deployment `system_catalog_access`: The SQL query references a denied DuckDB system catalog (information_schema, pg_catalog, sqlite_master, duckdb_*) `missing_table`: The SQL query references a df_<id> table that does not exist or has expired `invalid_sql`: The SQL statement contains a syntax or execution error not covered by a more specific reason `register_as_clash`: The register_as target name already exists on the canvas `non_select_statement`: The SQL is a non-SELECT statement (DROP, INSERT, UPDATE, DDL, etc.) — only read-only SELECTs run against dataframes Other values are possible when a failure originates below the handler.",
      +          "examples": [
      +            "canvas_unavailable",
      +            "system_catalog_access",
      +            "missing_table",
      +            "invalid_sql",
      +            "register_as_clash",
      +            "non_select_statement"
      +          ],
      +          "type": "string"
      +        },
      +        "recovery": {
      +          "additionalProperties": {},
      +          "description": "Actionable next step for the caller.",
      +          "properties": {
      +            "hint": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "hint"
      +          ],
      +          "type": "object"
      +        },
      +        "retryable": {
      +          "description": "Whether retrying may succeed.",
      +          "type": "boolean"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "message": {
      +      "description": "Human-readable description of what went wrong.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "code",
      +    "message"
      +  ],
      +  "type": "object"
      +}
    • changedOutput schema / properties / notice / description
      Previous value: -"Guidance when the query returned no rows, or when results were capped."New value: +"Guidance when the query returned no rows, or when the row cap withheld some."
    • addedOutput schema / properties / shown
      Added value: +{
      +  "description": "Number of rows returned inline.",
      +  "type": "number"
      +}
    • addedOutput schema / properties / truncated
      Added value: +{
      +  "description": "True when the result set held more rows than the row cap allowed through.",
      +  "type": "boolean"
      +}
    • removedOutput schema / required
      Removed value: -[
      -  "columns",
      -  "row_count",
      -  "rows"
      -]
  7. Changed1 schema field changed
    • addedInput schema / properties / register_as / pattern
      Added value: +"^df_[A-Z0-9]{5}_[A-Z0-9]{5}$"
  8. Changed1 schema field changed
    • addedOutput schema / properties / notice
      Added value: +{
      +  "description": "Guidance when the query returned no rows, or when results were capped.",
      +  "type": "string"
      +}
  9. Added

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint and idempotentHint annotations, the description discloses concrete SQL restrictions: writes, DDL, DROP, COPY, PRAGMA, ATTACH, and external-file table functions are rejected, and system catalogs are denied. It also explains that register_as creates a new dataframe with a fresh TTL, which is important side-effect context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, each carrying actionable information: purpose, prerequisite, rejected operations, catalog restriction, and chaining option. The critical constraint and prerequisite are front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has an output schema, rich annotations, and full input schema coverage; the description still adds the necessary guardrails around SQL restrictions, schema inspection, and result registration. Nothing material for correct invocation appears missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the detailed parameter behavior is already supplied by the input schema. The description reinforces register_as chaining and the fresh TTL, but does not add substantial semantics for preview or row_limit beyond what the schema already documents.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: running a single-statement SELECT against canvas dataframes registered by secedgar_* tools with a `dataset` handle. It also distinguishes the tool from secedgar_dataframe_describe by assigning describe the schema-inspection role.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says to inspect a dataframe with secedgar_dataframe_describe first so the SQL matches the column schema. It also states what is rejected, that system catalogs must be avoided, and when to use register_as for chaining results.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.