Skip to content
The Goodwill Ledger
← All field notes Field note

Why and How I Built This Site

· 4 min read

For most of my career as a software engineer, the guiding principle was to write generic code. Functions should be reusable. Software should serve many cases, not one. That made sense when writing code was expensive, both in money and in cognitive load.

That premise is collapsing. Code is now cheap to produce, and getting cheaper. We are heading towards a world where software is written for a single purpose, used once, and discarded. Claude artifacts are an early instance of this. The economics have inverted. The expensive thing is no longer the code, it is the context that shapes what the code should do.

This is the shift that prompted me to start this site.

I have always kept my ideas largely to myself, in my head or in private notes. Working with AI tools every day has changed how I think about that habit. The quality of the output you get from a model depends almost entirely on the context you give it. Generic prompts produce generic answers. Specific, personal, well-documented thinking produces output that is genuinely useful.

If context is the new scarce input, then documenting yourself in the open is a form of leverage. It is also a form of accountability. The Goodwill Ledger is where I do that work. The essays are written for human readers, and they are written for machines. Both audiences matter, and I will return to the second one at the end.

How the site is built

The site runs on Astro, a modern framework that compiles Markdown files into plain static HTML. I write essays in Markdown, alongside the rest of the source code, inside a Git repository. There is no CMS, no database, no admin panel. The structure of the content lives in the file system. The structure of the design lives in a single stylesheet.

Hosting is on Cloudflare Pages. Every time I push a change, Cloudflare runs the build and serves the resulting static files from its edge network, so the site loads quickly from anywhere in the world. The build also produces an RSS feed, a sitemap, and a machine-readable JSON archive of every published essay.

Two small dynamic pieces run on Cloudflare Pages Functions. The first, at /api/respond, lets readers send me a private response to an essay. It uses Cloudflare’s native email binding to deliver the message straight to my inbox, with no third-party service in between. The second, at /mcp, is the part I will come back to.

The entire codebase was written with Claude Code. A few years ago, a project like this would have required a CMS such as WordPress, a database, a hosting plan, and probably a developer or two. Today it is a folder of Markdown files and a few hundred lines of TypeScript, built in the evenings over a few weeks. I considered open-sourcing the engine, but there is no real need. Anyone with an idea and a few hours of focused attention with an AI assistant can now build something like this for themselves.

How I publish

The publishing workflow is deliberately simple. I write in Obsidian on my desktop. When an essay is ready, I commit the file to Git and push it to the main branch. Cloudflare picks up the push, runs the build, and deploys the new version in about a minute. There is no separate publish button. The commit is the publish action.

The machine layer

The last piece is the one I find most interesting. The site exposes a Model Context Protocol server at /mcp. MCP is an open standard for letting AI tools read external content in a structured way. Any compatible client, including Claude Desktop, Claude.ai and ChatGPT, can connect to this site and treat the full body of my writing as context. You can ask the model to search across my essays, to surface the positions I have taken on a given theme, or to summarise how my thinking on a topic has changed over time.

This was the primary reason I built the site in the form it now takes. The essays serve the human reader in the usual way. The MCP layer serves something else. It lets me, and anyone curious enough to connect, ask a model what I actually think, and watch the answer become more accurate as I write more. Over time, the ledger becomes a working representation of how my views are evolving, legible to me, to other people, and to the systems we are all increasingly working alongside.

That feels like the right use of these tools. Not to replace thinking with output, but to make thinking legible to machines that can help us build on it.