How I Let AI Agents Write to Live Business Data Without Losing Sleep

How I Let AI Agents Write to Live Business Data Without Losing Sleep

I'm Venetsian Jakimov. In 2026 I built 13 MCP servers with about 360 tools between them. They let AI assistants like Claude work on real systems: invoices and payments for ICEBOX Mechanical, an HVAC contractor in the US, proposals in our own billing portal, product catalogues in NextAI-SEM stores, multilingual content for Global Kyokushin Budokai, sites and DNS on our MaiaHost hosting platform, and Google Ads campaigns.

Letting an agent read data is easy. Letting it write is where you start losing sleep. A model that is right 98% of the time is wrong twice in every hundred calls, and on a live invoice that is not a rounding error. These are the rules I ended up with, and none of them depend on the model behaving.

What an MCP server is, in one paragraph

The Model Context Protocol is a standard way to give an AI assistant tools. My servers are small JSON-RPC endpoints next to each application. Each one lists its tools (icebox_record_payment, store_update_product and so on) with a strict input schema, and the assistant calls them like functions. Every call carries a personal token, and the server re-checks the user's role on every request instead of trusting a session.

Rule 1: every write is a dry run until you say otherwise

Every write tool takes a dry_run flag, and when the assistant leaves it out, it counts as true. Where it matters, the dry run is the real write inside a database transaction that is rolled back at the end. The preview is therefore exactly what would happen: the same validation, the same triggers, even the IDs the new rows would get. The assistant shows me the preview, I confirm, and only then does it repeat the call with dry_run set to false.

One practical trap: do not put a default value in the tool's input schema. Some clients read it as "this argument is required" and make the model fill it in on every call, which defeats the point of a safe default.

Rule 2: the server owns the numbers

The assistant never tells the server what an invoice total is. Totals are computed on the server from the line items. In our billing portal the assistant can send the total it expects, and if that doesn't match what the server computed, the whole write rolls back.

Payments need a reference that is unique per invoice. If a network hiccup makes the assistant retry, the second call is refused instead of recording the money twice. Retries are normal for agents, so every write path has to survive being called again.

Rule 3: nothing is really deleted

On the HVAC system, proposals are soft-deleted and a restore tool brings them back. Invoices are voided, not deleted. When a payment is removed, the row is first copied to an archive table together with the reason, in the same transaction, and if that copy fails, the removal fails too. Customers and projects cannot be deleted through the assistant at all.

The day an agent misunderstands "remove the old one", you want an undo, not a backup restore.

Rule 4: agents and people edit the same rows

This one surprised me. In our billing portal I sometimes have a proposal open in the editor while an assistant drafts changes to the same proposal. The editor autosaves, so it could quietly overwrite what the agent just wrote. The fix is the same one you would use between two people: the write locks the row and sends a hash of the version it read, and if the row changed in the meantime, the write is refused as stale.

The content system for Global Kyokushin Budokai goes further. Texts are append-only revisions, every save names the revision it was based on, and translations are pinned to the source revision they were made from, so a translation that has fallen behind its source is detected automatically.

Rule 5: some steps stay human

Not every action should be a tool. The billing server can draft proposals and contracts, but it cannot send them, change their status or delete them. Those buttons exist only in the portal, where I press them.

Where an agent may send email, as with outreach for the HVAC contractor, the rules live in the server, not in the prompt. The legal footer, the unsubscribe link, the suppression list and a cap of 50 emails a day cannot be switched off by any argument, and the dry run lists every recipient before anything leaves.

Rule 6: log everything, and treat what you read as data

Tool calls are written to an audit log with the user, the token and the arguments, including refused calls and, on most servers, dry runs. When something odd happens, I can see exactly what the agent asked for.

Text that customers typed, such as a note on a public form, comes back to the assistant clearly labelled as client-supplied, so it is treated as a quote and never as an instruction. Prompt injection is not theoretical once your tools read data that strangers can write.

The short version

Put the rules where the agent can't route around them: transactions, database constraints, row locks and server-side checks, not sentences in a prompt. Treat the agent like a fast, tireless new colleague with database access. You wouldn't give that person a delete button without an undo either.

If you want to see the systems behind these rules, they're in my AI and MCP portfolio, and the platform that ties them together is described in Inside My AI Control Center.

← Back to Blog