Skip to main content
Glama
marekrost

mcp-server-spreadsheet

describe_table

Analyze spreadsheet structure to reveal column names, data types, row counts, and sample data for effective SQL query planning.

Instructions

Inspect the structure of a sheet treated as a database table.

Returns column names, inferred data types (text, integer, number, boolean, date), total row count, and sample values from the first 3 data rows. Use this before writing SQL queries to understand the available columns and their types.

When sheet is omitted, returns a list of descriptions for all sheets.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
fileYesPath to the spreadsheet file
sheetNoSheet name to describe. If omitted, describes all sheets in the workbook.
header_rowNo1-based row number containing column headers. Defaults to 1.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The describe_table tool handler function, which inspects the structure of a sheet in a spreadsheet.
    def describe_table(
        file: Annotated[str, Field(description="Path to the spreadsheet file")],
        sheet: Annotated[str | None, Field(description="Sheet name to describe. If omitted, describes all sheets in the workbook.")] = None,
        header_row: Annotated[int, Field(description="1-based row number containing column headers. Defaults to 1.")] = 1,
    ) -> list[dict] | dict:
        """Inspect the structure of a sheet treated as a database table.
    
        Returns column names, inferred data types (text, integer, number,
        boolean, date), total row count, and sample values from the first 3
        data rows. Use this before writing SQL queries to understand the
        available columns and their types.
    
        When sheet is omitted, returns a list of descriptions for all sheets.
        """
        wb = load_workbook(file)
        targets = [_resolve_sheet(wb, sheet)] if sheet else wb.worksheets
    
        results = []
        for ws in targets:
            headers, rows = _sheet_to_records(ws, header_row)
    
            if not headers:
                results.append({"sheet": ws.title, "columns": [], "row_count": 0, "sample": []})
                continue
    
            columns = []
            for col_idx, header in enumerate(headers):
                col_values = [row[col_idx] for row in rows]
                columns.append({"name": header, "type": _infer_describe_type(col_values)})
    
            sample = [dict(zip(headers, row)) for row in rows[:3]]
    
            results.append({
                "sheet": ws.title,
                "columns": columns,
                "row_count": len(rows),
                "sample": sample,
            })
    
        return results[0] if len(results) == 1 else results
Behavior4/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It effectively describes the tool's behavior: it inspects structure, returns specific metadata (column names, data types, row count, sample values), and has conditional behavior based on the sheet parameter. It doesn't mention permissions, rate limits, or side effects, but for a read-only inspection tool, the described behavior is sufficiently transparent.

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?

The description is efficiently structured in three sentences: the first states the core purpose and output, the second provides usage context, and the third explains the conditional behavior. Every sentence adds value without redundancy, and key information is 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?

Given the tool's moderate complexity, 100% schema coverage, and the presence of an output schema (which handles return values), the description is complete. It covers purpose, usage guidelines, behavioral aspects, and parameter implications adequately without needing to duplicate structured data.

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 schema already documents all three parameters thoroughly. The description adds minimal value beyond the schema by mentioning the sheet omission behavior and implying header_row usage, but doesn't provide additional syntax or format details. This meets the baseline for high schema coverage.

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 clearly states the tool's purpose with specific verbs ('inspect the structure', 'returns column names, inferred data types...') and resources ('sheet treated as a database table'). It distinguishes itself from siblings like list_sheets, read_range, and sql_query by focusing on structural metadata rather than data retrieval or manipulation.

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?

The description provides explicit guidance on when to use this tool ('Use this before writing SQL queries to understand the available columns and their types') and distinguishes it from alternatives by specifying the fallback behavior ('When sheet is omitted, returns a list of descriptions for all sheets'), which differentiates it from list_sheets.

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

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/marekrost/mcp-server-spreadsheet'

If you have feedback or need assistance with the MCP directory API, please join our Discord server