tidewaterdata
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@tidewaterdataclean this freight record and show the replayable lineage"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
tidewaterdata (Project Tidewater)
Record-level lineage with replayable transformations, delivered as an MCP server, for data-quality work at Tallowfield Technologies.
The problem
Freight and logistics records arrive dirty: whitespace from CSV exports, inconsistent casing on port and carrier codes, dates in half a dozen formats, missing fields. Cleaning them is easy. Proving what was changed, why, and that the cleaned record genuinely follows from the raw one is the hard part — and it is what an auditor or a downstream dispute actually needs.
tidewaterdata makes every change go through a named, parameterised, deterministic transformation and records each application with content hashes on both sides. Given the original record and the recorded lineage you can replay the whole history and prove the stored result follows from the stored steps — or find the exact step where something was altered.
Related MCP server: Latentmachine MCP Server
How the CPU-only constraint shapes the design
The target environment is CPU-only, with no GPU, and in practice keeps a small, often-isolated runtime footprint. That drives concrete choices:
Correctness rests on canonical JSON + stdlib
blake2bhashing and pure-Python transforms. Nothing wants an accelerator. (ADR 0002)The runtime core has no third-party dependencies, including the MCP server itself, which implements the JSON-RPC stdio protocol directly. (ADR 0001)
Any model/LLM behaviour goes through a provider interface. The default
StubProvideris deterministic and offline, so the whole test suite runs with no API key and no network. If the networkedRealProvideris selected but unconfigured — the normal case on an isolated box — the service degrades to the stub with a logged warning instead of failing. (ADR 0004)
tests/test_offline_cpu.py holds this line: it runs the full flow with the
socket layer stubbed out and asserts no GPU/model libraries were imported.
Architecture
MCP client (stdio JSON-RPC) shell
| |
tidewaterdata/server.py tidewaterdata/cli.py
\_____________ _____________/
\/
tidewaterdata/service.py
validate -> run core -> time -> structured log (stderr)
|
validation.py config.py lineage.py (Pipeline / replay / verify_chain)
|
transforms.py (registry) hashing.py (canonical JSON + blake2b)
|
providers/ base | stub (offline) | real (networked)The core (lineage, transforms, hashing, types) knows nothing about
transport. service.py is the one place that validates input, times work, and
logs. server.py and cli.py are thin adapters over it. Transformations are
identified by (name, params) and resolved through a registry, so a lineage
serialises to pure JSON and replays anywhere without shipping code. (ADR 0003)
Decision records for the contested calls are in docs/adr/.
Install
make install # creates .venv and installs the package with dev extrasmake uses PY ?= .venv/bin/python; override with make test PY=/path/to/python.
The core imports only the standard library, so you can also run it straight from
a checkout without installing anything:
python3.12 -m tidewaterdata list-transformsQuickstart
Every command below runs against a checkout with python3.12 -m tidewaterdata;
after make install, the console script tidewater is equivalent.
List the available transforms:
python3.12 -m tidewaterdata list-transformsClean a record and get back the result plus a replayable lineage:
echo '{"record": {"id": "1", "name": " acme freight "},
"pipeline": [{"name": "trim_whitespace", "params": {"field": "name"}},
{"name": "collapse_spaces", "params": {"field": "name"}}]}' \
| python3.12 -m tidewaterdata clean -i -The result.name is "acme freight", and lineage carries the per-step hashes
and diffs. Save the whole {record, lineage} and verify it later:
echo '{"record": {"id": "1", "name": " acme freight "},
"lineage": { ...the lineage printed above... }}' \
| python3.12 -m tidewaterdata replay -i -replay prints {"result": ..., "verified": true} on success, or exits 2
with a replay mismatch at step N message if the record or lineage was altered.
Run the MCP server (reads newline-delimited JSON-RPC on stdin):
python3.12 -m tidewaterdata serveLibrary use:
from tidewaterdata import Pipeline, Transformation, replay
rec = {"id": "shp-1", "name": " acme freight ", "port": "lax"}
pipe = Pipeline([
Transformation("trim_whitespace", {"field": "name"}),
Transformation("collapse_spaces", {"field": "name"}),
Transformation("to_upper", {"field": "port"}),
])
lineage, cleaned = pipe.run(rec)
assert replay(rec, lineage) == cleaned # raises ReplayMismatch if tamperedMCP tools
The server exposes four tools via tools/list / tools/call:
Tool | Arguments | Returns |
| none | available transform names |
|
|
|
|
|
|
|
|
|
Validation failures and replay mismatches come back as a normal tools/call
result with isError: true and a message; malformed JSON or an unknown method
comes back as a JSON-RPC error.
Transforms
trim_whitespace, collapse_spaces, to_upper, to_lower, default_missing,
drop_field, rename_field, coerce_int, standardize_date. Register your own
with @tidewaterdata.register("name") — a transform is a pure dict -> dict
function that must not mutate its input.
Configuration
All optional, read from the environment at startup and validated there (a bad
value fails immediately with a configuration error):
Variable | Default | Meaning |
|
|
|
|
| reject records larger than this |
|
| reject pipelines longer than this |
|
| batch-size cap (reserved; see limitations) |
|
|
|
Config.from_file(path) overlays these defaults with keys from a JSON object.
Logs are one JSON object per line on stderr (stdout is the protocol/result stream). The size and length limits are the defence against resource exhaustion: oversized input is rejected before any work is done.
The real provider additionally reads TIDEWATER_PROVIDER_ENDPOINT and
TIDEWATER_PROVIDER_API_KEY, and needs the real extra
(pip install -e .[real], which pulls in httpx).
Test
make test # or: python3.12 -m pytestCLI exit codes: 0 success, 2 bad input / validation / missing file / replay
mismatch, 1 unexpected.
Known limitations
No batch tool yet.
TIDEWATER_MAX_BATCHis wired into config but there is noclean_batchMCP tool; records are cleaned one at a time. The cap exists so the limit is enforced the moment batching lands.Replay depends on transform behaviour staying stable across versions. Changing what a registered transform does will break replay of older lineages — surfaced as a
ReplayMismatch, not a silent wrong answer, but it is a real compatibility obligation. (ADR 0003)16-byte hashes detect tampering and drift, not a determined forger who recomputes the whole chain. Signing the final lineage is a future option. (ADR 0002)
The
realprovider's response contract is provisional. It assumes a{"suggestions": [...]}shape; see the TODO inproviders/real.pypending a frozen endpoint spec.No deployment wrapper. systemd/container packaging is out of scope for this delivery.
Tallowfield Technologies is an illustrative client; this repository is a self-directed reference implementation built to work end to end.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
No tool schema history has been recorded yet.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Standardize, reshape, and normalize messy data — CSV, Excel, Parquet, S3, databases.
- SnipgetOAuthai.snipget
300+ deterministic data utilities for AI agents: validate, normalize, parse, match, redact.
One command to validate, transform, and deduplicate — chain GoldenCheck + Flow + Match.
Deterministic cleanup tools for decimals, whitespace, filenames, delimiters, and booleans.
Related MCP Servers
- AlicenseAqualityCmaintenanceProvides AI agents with data validation, transformation, and normalization capabilities, including JSON schema validation, CSV processing, data normalization, text cleaning, and dataset merging.571MIT
- AlicenseNot gradedqualityBmaintenanceProvides deterministic tools for understanding, transforming, and verifying structured data via MCP, enabling rule inference from examples and verification of transformed records.MIT
- AlicenseNot gradedqualityFmaintenanceEnables orchestrating data quality checks, transformation, and deduplication pipelines via an MCP interface. Offers tools for listing pipeline stages, validating wiring, running the full check-transform-match pipeline, and explaining configurations.MIT
- AlicenseNot gradedqualityCmaintenanceProvides deterministic, stateless tools for common data work including JSON, CSV, text, encoding, hashing, IDs, date/time, and number statistics.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/J-X0/tallowfield-technologies-data-quality-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server