TRMNL is an awesome open-source ePaper display that lets users show almost anything they want. Launched on Kickstarter, it’s now got thousands of plugins and users. I’ve published a few plugins, including a realtime TfL bus stop arrival time board.
A few weeks ago, TRMNL added an MCP server. This lets you use a local coding agent to do most of the grunt work. I wrote about how to set that up in another post.
TRMNL is an awesome open-source ePaper display that lets users show almost anything they want. Launched on Kickstarter, it’s now got thousands of plugins and users. I’ve published a few plugins, including a realtime TfL bus stop arrival time board.
A few weeks ago, TRMNL added an MCP server. This lets you use a local coding agent to do most of the grunt work.
Install the MCP server through .mcp.json
Using Claude Code, i created a simple .mcp.json file which references the API key by environment variable. Place this in the root of your repo. As it contains no secrets, this is safe to commit:
To stop my API keys being sucked up by some random malware, I keep secrets in 1Password and inject them into commands at runtime with op run. That works for almost everything, but when using Claude Code, i started getting a confusing error message.
Injecting MCP API keys to Claude Code
Claude Code reads MCP server config from .mcp.json and expands ${VAR} references from the environment.
gently (low temperature) fry onion in the vegetable oil for 5-6 mins over a medium heat in the small (metal?) roasting tin you’ll use in the smoker
Take off the heat and add the grated garlic
Add the beans and hendersons
Stir and put in the smoker (110-120c) for 60-90 minutes. Check after 60 mins to make sure not dried out. If it starts to get dry, add a splash of water. Stir.
Boil new potatoes until fork-tender (15-20 min) then drain
smash them on a sheet tray to break them slightly. The fluffy bits go crispy.
Coat them in oil/fat (e.g. drizzle in vegetable oil) and seasoning (salt, pepper)
roast in the oven at 220°C for 20-25 minutes until the edges are crispy and golden.
Transfer to the smoker at 110-130°C for 20-30 minutes to pick up smoke flavour. The already-crisped surfaces absorb smoke well. Going longer than 30 minutes risks drying them out or making the smoke flavour acrid.
I previously wrote about how i’d implemented a combination of 1Password’s CLI and direnv to avoid storing passwords on disk. This works great, most of the time. The problem comes when i want to add a secret and i’m in the middle of a complex multi-agent task - because the environment is loaded once before Claude or Codex or whatever starts, adding or rotating credentials during a build (e.g. if the agent needs an API key to a new service, or accidentally exposes a secret to its context) is tricky. So i’ve evolved the system slightly.
Recently at work, someone asked me why my team wasn’t creating detailed logical data models as part of their solution design. It seems quite simple to me – they don’t do it because nobody reads it. Most solution architecture documentation is out of date before it even gets logged in the architecture repository.
Why do we even write documentation?
I think we create documentation for one of two reasons:
Collaborate now: as soon as there is a second person in a team, they need to start talking so that they can work together. The more people, the harder this is (which is why we try to limit teams to half a dozen people or so). Documentation is a great way for people to collaborate. When things are written down, everyone can see it, and by adding comments or questions we get to a resolved version.
Communicate with the future: We make decisions today which are the best available given the information we have at the time. Sometimes we forget what we decided, or why, and documentation gives us that. It’s not about proving whether a decision was right or wrong – that’s largely irrelevant – it’s about understanding what led us to that decision in the first place. Perhaps the reasons are still valid and we just forgot what they were. Or perhaps information we have now changes things.
So really, design documentation is about ensuring that everyone’s on the same page, both now and in the future. Some designs are ephemeral – just to help us get our heads around what we want to do, and some is persistent – giving us a framework on which to hang our future plans.
separation of this vault from my main password vault in BitWarden. My whole world exists in Bitwarden - i dont want to inadvertently expose it. And as Bitwarden has a pretty awful CLI experience, it doesnt work for me.
Safe to commit secret file to source control
Safe to commit my .env files to source control because they no longer contain secrets
If you’re running Claude Code against your own API key or through a proxy instead of Anthropic’s native backend, you’ve probably noticed that the built-in WebSearch tool just doesn’t return results because it relies on a server-side API that only exists at Anthropic. Without web search, the agent cant research, so we built a self-hosted replacement using MCP.
What we built
The brilliant DDGS is an open source metasearch server that aggregates results from DuckDuckGo, Bing, Google, Brave, and Yahoo. It has a built in MCP server which exposes five tools: search_text, search_news, search_images, search_videos, and search_books.
Claude Code can do a lot of things. But can it keep a plant alive?
The Plant: Act I — Fifty-Eight Days
October 22 – December 19, 2025
On October 22, 2025, the moisture sensor read 1829, the first of 5,568 check-ins over fifty-eight days. The scale runs from wet at roughly 1100 to dry at 3400, putting that reading in the middle.
The sensor is in the pot of a Tradescantia zebrina. There’s also a 5l jug of water with a pump, a grow light and a camera. Claude’s job is to keep the plant alive - basically, keep the moisture in range and run the grow light on schedule, writing notes after each cycle so it could pick up where it left off. At the start, there were five unknowns: plant species, target moisture range, soil type, ambient temperature, and pot size. Claude logged all five, ran a 60-minute grow light session, and began monitoring. The full session logs, sensor data, and photos are at plants.cynexia.com if you want to follow along.
I have a personal GitHub account and a corporate one, and I found it annoying to have to select the correct SSH key for work repos, so I configured git and SSH to pick the correct key for me. After initial setup, there are three config files to modify:
After the initial setup, there are three config files involved:
Git URL rewrite (~/.gitconfig) — rewrites work org URLs to an SSH host alias
SSH host alias (~/.ssh/config) — maps that alias to the right key (and port 443 if needed)
Work-only Git identity (~/.gitconfig.work) — sets work email/name/signing key, loaded automatically for work repos