Skip to main content
Glama
ayushsri

mcp-tabular

by ayushsri
README.md
# mcp-tabular

**An MCP server that gives any LLM agent SQL over CSV and Excel files.** DuckDB-powered, read-only, zero configuration.

## Why

Embedding spreadsheets into a vector store gives agents mushy answers; tables chunk badly. The pattern that works in production is **SQL-over-file**: load the table into an analytical engine and let the agent query it. `mcp-tabular` packages that pattern as a standard [MCP](https://modelcontextprotocol.io) server, so it works with Claude Desktop, Claude Code, or any MCP client.

```
Agent ──MCP──▶ mcp-tabular ──▶ DuckDB (in-memory, read-only)
                  tools: load_file · list_tables · describe_table · query · sample_rows
```

## Install & run

```bash
pip install -e .
mcp-tabular            # stdio transport
```

Claude Desktop config:

```json
{
  "mcpServers": {
    "tabular": { "command": "mcp-tabular" }
  }
}
```

## Tools

| Tool | Description |
|---|---|
| `load_file(path, table_name?)` | Load a CSV/XLSX file into an in-memory table. Returns schema + row count. |
| `list_tables()` | Tables currently loaded. |
| `describe_table(table)` | Columns, types, null counts, min/max — enough for the agent to write correct SQL. |
| `query(sql)` | Read-only SELECT. Results capped and returned as markdown. |
| `sample_rows(table, n)` | Quick peek at representative rows. |

## Safety

- **Read-only**: statements other than `SELECT`/`WITH` are rejected before execution.
- **Path allow-listing**: set `MCP_TABULAR_ROOT` to restrict which directory files may be loaded from.
- **Bounded output**: result sets are truncated (default 200 rows) so a bad query can't blow up the agent's context window.

## Example session

```
> load_file("sales_q3.csv")
loaded table 'sales_q3' (8,412 rows). Columns: region VARCHAR, sku VARCHAR, units BIGINT, revenue DOUBLE

> query("SELECT region, SUM(revenue) r FROM sales_q3 GROUP BY 1 ORDER BY r DESC LIMIT 3")
| region | r        |
|--------|----------|
| South  | 412,050  |
| West   | 371,200  |
| East   | 298,700  |
```

## Design notes

Built after shipping enterprise agents where tabular Q&A over uploaded files was the highest-volume use case. Schema + sample injection (via `describe_table`/`sample_rows`) is what makes agents write correct SQL on the first try.

## License

MIT

TDQS

B3.4/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a clear, distinct purpose: describing schema, listing tables, loading files, running queries, and sampling rows. No overlap in functionality.

Naming Consistency4/5

Most tool names follow a consistent verb_noun pattern (describe_table, list_tables, load_file, sample_rows). 'query' is a single verb but is a common and clear exception that doesn't cause confusion.

Tool Count5/5

With 5 tools covering loading, listing, describing, querying, and sampling, the count is well-suited for a focused tabular data server. No unnecessary or missing tools.

Completeness4/5

The tool set covers the core workflow for read-only SQL querying on loaded tables. Minor gaps like table removal or export exist but are not essential for the stated purpose.

Maintenance

ActivityStale
ResponsivenessNo issues