An assistant can say the data is clean. It cannot make the export return.
Hand a model a supplier spreadsheet and it will hand you back a tidier one, along with its own assurance that everything is in order. Both halves come from the same model in the same reply, so the assurance is worth exactly what the guess is worth. Typesheet is somewhere for an assistant to put that data instead: a typed sheet that checks every cell itself, on our server, and will not give the rows back until they pass.
The check moves somewhere the model cannot reach
Connected over MCP, an assistant maps your columns, coerces what it can defend from the source, and fixes what it is sure about. Then it calls export_records, and that call runs Typesheet’s validator: the same deterministic code the human review grid runs, which never sees the model’s reasoning or its confidence. While one cell is invalid the call comes back as a refusal naming what is unresolved. The assistant can report success, or it can produce the data. It cannot do both while the sheet is dirty.
Side by side on the same messy file
| An assistant alone | An assistant with a typesheet | |
|---|---|---|
| Who certifies the data | The model, in prose, in the same reply that did the work. It is grading its own homework and it is a generous marker. | A validator on our server. It runs the same code the human review grid runs, it never reads the model's reasoning, and there is no wording that talks it round. |
| A value the model is unsure about | Becomes a best guess, indistinguishable in the output from the values it was sure about. | Stays an open issue on its own cell, with the row and the original text, until somebody resolves it. |
| What the finish line is | The assistant saying it is done, which is a claim about a claim. | export_records returning. While one cell is invalid it refuses, and the refusal names what is left. |
| What you can check afterwards | A transcript, if the session still exists, and the file itself. | Every cell records who wrote it: you, the sender, this sheet's memory, or an assistant. The ones a model touched are marked as a model's and can be put back. |
| The second delivery | Handled from scratch, with whatever the model remembers of the first, which is nothing. | Merged on the fields you called unique and reported as new, updated, or unchanged, with the corrections from last time already applied. |
| What the assistant can see | Whatever you gave it, which is usually the whole file. | Your field definitions and the rows of the delivery it is working on. The tools do not hand it the rows the sheet already holds. |
What a model touched stays marked as a model’s
A refusal is only half of it. Every cell in an import records who wrote the value: you, the person who sent the file, the sheet’s own remembered corrections, or an assistant. Forty cells fixed by a model and forty fixed by a person are identical in the data and are not identical in consequence, so the review grid shows which were which, with the value each one replaced, and any of them can be put back. An assistant that cannot defend a change from the source is expected to leave it and send you the review URL instead.
When you don’t need any of this
- The data is already clean and typed, and you want it summarised, charted, or explained. Nothing here helps; that is what the model is for.
- It is a one-off. Twelve rows pasted into a chat, used once, and never referred to again does not need a schema, and defining one costs more than checking twelve rows by eye.
- The rules you care about are about meaning rather than shape. Whether a price is plausible for this supplier is a judgment; whether it is a number is a type. We only enforce the second, and an assistant is genuinely better at the first.
- You already own the pipeline. If the rows land in a database with real constraints and a migration you control, the constraint is the gate and it is a better one than ours.
What is left is the case this was built for: tabular data that arrives repeatedly, from outside, and gets acted on. There, a wrong value is not a bad answer in a chat window, it is a price in a catalogue or a start date in a payroll run, and it is worth having a check that the thing which produced the data does not control.
Questions
Because an assistant cannot check its own output in a way anyone else can rely on. When Claude cleans a spreadsheet it produces both the data and the assurance that the data is good, from the same model, in the same reply. Typesheet moves the assurance somewhere the model does not control: rows are validated by a deterministic engine on Typesheet's server, and the tool that returns clean records refuses while any cell is still invalid, whatever the assistant believes about it.
Nothing stops it from claiming that, and this is the point. It cannot make the claim true. The export_records tool runs Typesheet's validator before returning anything, and while one cell fails the call comes back as a refusal listing what is unresolved. The assistant can report success without the data, or produce the data, but it cannot do both while the sheet is dirty.
Every cell in a Typesheet import records who wrote it: you, the person who sent the file, the sheet's own remembered corrections, or an assistant. The review grid shows a model's edits as a model's edits, with the value it replaced, and any of them can be put back. An assistant fixing forty cells and a person fixing forty cells look identical in the data, so Typesheet does not store them identically.
It can read the shape of a sheet, meaning your field names, their types, and their rules, and it can read the delivery it is currently working on. The tools do not return the rows a sheet already holds. An import link is narrower still: it only ever writes, and it never reveals what is already in the sheet to whoever is sending.
Any client that speaks the Model Context Protocol, which covers Claude, ChatGPT, Cursor, Zed, and Continue among others. Typesheet is a remote MCP server at https://typesheet.com/mcp with no API keys to manage: the first connection opens a browser, you sign in once, and the tools then run as you. If you are writing the agent yourself, an import link takes plain HTTP instead.
No. An import is one delivery however it arrives, so a file you drop in yourself, a file a supplier sends through your link, and a set of rows an assistant puts in over MCP all count as one against the same monthly allowance. Only PDFs and screenshots additionally consume document pages, because only those are read by a model.
Connect it in about a minute
One URL, no API keys, and six tools. Sign in once in the browser and your assistant can start putting data in.