a man machine dream
I track the white space between shapes and patterns. I listen to the silences and the absences — that's where the ideas are. I make things with technology because I still find it interesting.
I poke at things — technology, markets, ideas, aesthetics — until they reveal how they actually work. Then I build. Digital products, brands, ventures, sometimes just experiments. I don't specialise in one industry because interesting problems don't care about categories.
I'm suspicious of certainty. Most of what gets built is built on assumptions nobody questioned. I'd rather slow down and ask “but why though?” than ship something that shouldn't exist. Curiosity is the engine. Scepticism is the steering wheel.
I work around the white space — the gaps between what's said and what's meant, between the shape and the pattern. I listen to silences and track absences. That's where inspiration lives. I care about craft, not spectacle. I'd rather make one honest thing than ten impressive ones.
An MCP search engine that learned to query any online database by scraping what wasn't meant to be queried.
You can't API what doesn't have one. Lynceus started with a question: can an AI agent search across multiple online databases — museum catalogs, archives, collections — when none of them expose a public API? The answer had to work for any database, not just one. Add a new source, the system learns to search it.
Two things had to work. A web app where a human can type a query and get structured results from any connected database. And an MCP server — the protocol AI agents use to call external tools — so any LLM can do the same search programmatically. Same query surface, two entirely different consumers: a person in a browser and an agent in a pipeline.
The AI layer wraps the web app's query logic, not the other way around. The search works without intelligence. The intelligence makes it conversational.
The hard part wasn't searching one database. It was making the system learn new ones. You register a source with a URL pattern and a few example queries. Lynceus fires those queries against the live page, then probes the HTML with a battery of candidate CSS selectors — <article>, <li.result>, .search-result, h2, h3, a[href]. Every hit gets tallied. Across three example queries, the selector that matches most consistently wins. The result is a JSON strategy file: which selector wraps a result, which pulls the title, which grabs the link, how pagination works, whether pages start at 0 or 1.
No per-database code. No manual integration. The system reads the structure of a page it's never seen and writes its own extraction rules. Add a new museum, a new archive, a new catalog — one registration call, and it's searchable.
The server started cleanly. Logged “listening on port 3200.” Crashed on every single request. The MCP SDK's HTTP transport assumed Node.js http module internals. Bun provides Web Standard Request/Response directly — no Node.js primitives. One import swap. Thirty minutes from crash to fix. The startup looked perfectly healthy. The crash only happened when someone actually tried to use it.
That's a decent metaphor for most software.
79 deterministic tests · two languages · zero APIs · built in a day
A studio for brands that refuse to play safe. Positioning work for people who'd rather be specific than scalable.
A platform for consumer rants. Because the internet gave everyone a megaphone but companies still pretend they can't hear.
Rethinking what “premium” means — not more expensive, more intentional.
If you want to talk about something specific — a project, a problem, an idea you can't shake — I'm around.