Skip to main content
Glama
csv-tools-mcp

csv-tools-mcp

by d0031020
README.md
# csv-tools-mcp

## What this is

`csv-tools-mcp` is a small public demo MCP server for safe, deterministic CSV cleaning workflows.

| Tool | Input | Output | Notes |
|---|---|---|---|
| `profile_csv` | `csv_text` | rows, columns, inferred types, null counts, duplicate-row count, sample values | Rejects invalid/ragged CSV and >1 MB input |
| `clean_csv` | `csv_text` | `cleaned_csv`, `exceptions`, `change_log` | Deterministic cleaning only; never guesses missing values |
| `validate_schema` | `csv_text`, `schema` | `valid`, `violation_count`, `violations` | Schema supports required columns, types, allowed values |

Resource:

- `rules://cleaning` — plain-text description of cleaning rules.

## Why

- Show a practical **remote MCP server** over streamable HTTP.
- Keep data handling strict and predictable for demos and local testing.
- Avoid file I/O and network side effects by accepting CSV **text input only**.

## Install

```bash
python -m venv .venv
.venv/bin/pip install -e '.[dev]'
```

Tested with Python 3.15 and mcp 2.3.0.

## Usage

Start server:

```bash
export MCP_BEARER_TOKEN=change-me
.venv/bin/python -m csv_tools_mcp.main --host 127.0.0.1 --port 8000 --path /mcp
```

Connect from Claude Code (replace token placeholder):

```bash
claude mcp add csv-tools-mcp --transport http http://127.0.0.1:8000/mcp --header "Authorization: Bearer <YOUR_TOKEN>"
```

### Cleaning behavior

- Trims leading/trailing whitespace in cells.
- Normalizes header names (lowercase, underscore style, deterministic dedupe suffixes).
- Normalizes unambiguous ISO-like dates (`YYYY-MM-DD`, `YYYY/MM/DD`, `YYYY.MM.DD`).
- Drops exact duplicate rows after normalization.
- Never guesses missing values.
- Never merges conflicting rows.

### Security notes

- Bearer authentication required on MCP endpoint (`Authorization: Bearer <token>`).
- Token comes from `MCP_BEARER_TOKEN` env var at startup; no hardcoded key in source.
- Constant-time token comparison is used to reduce timing leak risk.
- CSV input is size-limited to 1 MB.
- No filesystem access in tools (CSV text only).
- Deploy behind HTTPS in non-local environments.

## Testing

The suite runs **offline** (no external network). All CSV data in tests is **synthetic**.

Coverage includes:

- CSV tool units: `profile_csv` (basic, empty input, oversize rejection), `clean_csv` (normalize and dedupe, ragged rows, Unicode), `validate_schema` (violations, JSON-string schema).
- Server startup: refuses to start without `MCP_BEARER_TOKEN`.
- HTTP integration via the MCP SDK client: missing/wrong bearer returns 401; tools and `rules://cleaning` resource with a valid token.

```bash
.venv/bin/python -m pytest -q
```

## Known limitations

- This is a **demo**, not a hosted service; the server does not terminate TLS itself — deploy behind HTTPS.
- Authentication is a single static bearer token from an env var (no OAuth/SSO, no token rotation or per-user scopes).
- Date normalization only handles unambiguous ISO-like formats (`YYYY-MM-DD`, `YYYY/MM/DD`, `YYYY.MM.DD`); other formats are left unchanged.
- Input is CSV text only, max 1 MB, no file or URL inputs.
- The `claude mcp add` connection example has not been tested end-to-end with a live Claude client — the test suite uses the MCP SDK client.
- Tested locally on Python 3.15 with mcp 2.3.0 only.

## License

MIT — see LICENSE.

This project was built with AI coding agents for implementation, documentation and a separate review step; the results were checked and tested before publishing.