AI Part 1: Why I Gave Claude Write Access to My Site

A year ago I would have called this irresponsible. Today I have a small Node service on a Linux box on my network that lets Claude write blog posts to my site, edit Astro layouts, and run my deploy script. It’s been live for weeks. I’m writing this post through it.

The framing I had in my head — should I let an LLM near my site — turned out to be the wrong question. The real question is what shape of access is tolerable, and what does that shape cost to build? Once I started thinking about it that way, the answer got a lot less scary.

What “owner-operator” lets you simplify

Most of what makes giving an agent access to a system hard is the multi-tenant story. Per-user permissions, per-tenant data isolation, consent dialogs that scale to thousands of users, audit trails that map back to a human identity for compliance. None of that applies here. There is one user. There is one site. The agent only acts on my behalf, and the only person reviewing the audit log is me.

That collapses a lot of the design surface. I don’t need an RBAC model — I need an allowlist of paths the tool will write to. I don’t need per-user consent prompts — I need a tool description honest enough that I’d remember why I built it six months from now. I don’t need scoped tokens per resource — I need a single bearer token that I rotate when I feel like it. The MCP specification accommodates all of that, but the spec doesn’t tell you which parts you can stop building if you only have one user. Most of this series is about which parts I stopped building.

The trust model isn’t “I trust the model”

People hear “I gave an LLM write access” and assume the trust model is “I trust the model not to do something stupid”. It isn’t. The trust model is closer to: I trust the blast radius. Every tool the agent can call is bounded — by an allowlist, by a file size cap, by what the deploy script will actually publish. If the agent does something I didn’t expect, the worst case is a malformed page on a personal site that nobody reads on a Tuesday afternoon. I can revert it in one command.

That framing shifts what you spend your effort on. You don’t spend it interrogating the model’s intent. You spend it on the tools — making sure each tool, used in the worst possible way, is something you can absorb and undo. Allowlists for paths. Atomic writes. An append-only audit log. Versioned backups of the things the agent isn’t supposed to touch but might. Boring infrastructure.

”A very fast typist with a deploy key”

The mental model that’s served me best is: this isn’t an autonomous agent, it’s a very fast typist who has a deploy key. I tell it what I want, it produces something, I look at the diff, I either accept it or I rewrite the prompt. The human is in the loop on every published change — not because I don’t trust the model, but because being in the loop is the point. If I wanted unattended publishing, I wouldn’t need an LLM; I’d write a cron job.

Once you accept that the human is in the loop, a lot of the lurid scenarios stop being scenarios. The model doesn’t get to publish a hundred spam posts overnight because I have to confirm each deploy. The model doesn’t get to leak the contents of an .env file because the read tool refuses to read it. The model doesn’t get to delete a directory because the delete tool refuses directories. None of that is the model being well-behaved; it’s the tool being well-shaped. The model is doing exactly what it was always going to do — call whatever tool seemed relevant — and the tool is what decides whether the call lands.

What this series is about

Across a handful of posts I want to write down the bits that took me longer to figure out than they should have. The minimum viable shape of a personal MCP server: what’s in it, what’s intentionally not. How to write tool descriptions that the model will actually use correctly, and what happens when you don’t. The safety rails that turned out to matter — allowlists, atomic writes, audit logs — and the ones I overbuilt. What it actually feels like to draft a long technical series by talking to an editor instead of typing it. The connector quirks and cache traps that bit me. And the things I’d cut if I were starting over.

If you’re considering doing something similar — for a personal site, an internal tool, a homelab service — most of this should generalise. The specifics of my server are deliberately not in this series. The patterns are.