Software architecture & agentic development

Simpler software. Ready for AI agents.

We cut the cost of over-engineered web stacks and make your applications usable by AI agents. One process on one server, one SQLite file, HTML over the wire.

8.3× faster on mobile 27× less data $20 a year to host Same app, built twice: read the benchmark →
My stack is too expensiveCloud bills, a platform team, a frontend nobody wants to touch. We simplify it. I want my app to work with AI agentsLet your users work with your product from Claude, ChatGPT or Copilot, safely.
Approach

From cloud complexity to one binary on one server.

Most web apps don't need a distributed system. They need a fast server, a reliable database and HTML. Everything else is cost.

The usual stack 10 parts

Kubernetes browser CDN API gateway auth SaaS SPA bundle functions queues workers Observability managed DB

→ eight bills that grow with usage, a platform team, 592 npm packages to keep patched

Our stack 3 parts

HTML over SSE in-process one server · systemd browser one Go binary pages · auth · jobs · files one SQLite file backed up continuously
  • No frontend build, no cold starts, no vendor lock-in
  • Predictable cost: a server, not a meter
  • Small enough for one person, or one agent, to understand

Measured on our Kanban board: one 13.5 MB binary and 28 MB of memory at rest, where PLANKA runs 18 processes in two containers.

This page, live from its server

This site is built the way we describe: one Go binary on one server. While you watch, it sends you these numbers once a second, as HTML over one compressed stream.

Memory (RSS)
…
Go heap
…
Goroutines
…
Tabs watching
…
CPU at startup
…
CPU while running
…
Requests served
…
Running for
…
One update: HTML → wire
…

Connecting …

LLM-ready

Your app, usable from any AI assistant.

Your customers already ask ChatGPT and Claude to do their work. We build an MCP server in front of your existing API so they can, with you in control of what an agent may read and write.

AI agent Claude, ChatGPT, Copilot
Model Context Protocol
MCP server
read tools · write tools only in write mode · every write previewed before it runs
your existing API
your application

MCP servers we have built

  • 18 read tools over all 376 endpoints of the CashCtrl accounting API, four write tools that only exist in write mode and preview every change before it is made.

    Open source on GitHub →
  • Our SaaS for vehicle costs: 8 tools on Swiss vehicle data without signing in, and 22 tools for your own garage behind OAuth, 14 of them writing. Every call lands in the audit log.

    libretto.ch →
  • 43 tools with which agents run websites: content in every language, files, navigation, link checks. With a read-only key, or a writer role that can't delete.

Claude · cashctrlAccounting
  1. Which customer invoices from September are still unpaid?
  2. cashctrl list_open_invoices { type: "sales", from: "2026-09-01", to: "2026-09-30" } → 4 open orders
  3. Four September invoices are open, CHF 4,180 in total. The oldest is Meier AG, due 12 days ago. Shall I create a reminder?
  4. Yes, for the overdue one.
  5. cashctrl create_record { resource: "order", … } → preview
  6. cashctrl shows a preview

    Reminder to Meier AG for CHF 1,240.00, due in 10 days. Nothing is written until you confirm.

    DeclineConfirm

    Confirmed

  7. The reminder is in CashCtrl.

Illustration using cashctrl-mcp's real tools.

Claude · libretto-garageVehicles
  1. What’s coming up for my cars?
  2. libretto-garage upcoming → 2 dates
  3. Two dates: the Saab 900 S is due for its inspection on 19 October, and the 530d’s emissions service on 3 December.
  4. Serviced the 530d today, 221,150 km, 340 francs: oil and filter.
  5. libretto-garage add_entry → recorded
  6. libretto-garage asks you to confirm

    BMW 530d Touring xDrive: CHF 340.00 on 2026-09-22 (werkstatt): Service: oil and oil filter [resets: oil]. Record this?

    DeclineConfirm

    Confirmed

  7. Recorded. The oil-change interval starts over from today.

Re-enacted from a real session with Libretto's demo garage.

Claude · cmsWebsite
  1. Please publish the Kanban post, in German and English, with the cover image.
  2. cms upload_file { folder: "upload/blog" } → 20261008-kanban-hero.jpg
  3. cms create_record { table: "blog", … } → id 3
  4. cms update_multilingual { lang: "de", … }, { lang: "en", … } → 2 languages
  5. cms link_check → no dead links
  6. The post is live, in both languages and with its cover image. The link check finds no dead links.

After a real session: how we published a post this week.

Services

Four ways we work with you.

01

Architecture audit

One to two weeks: a code review, a workshop and written findings on where your cost and complexity come from, and what to cut first.

02

Simplify & migrate

Off microservices, serverless or a hyperscaler, step by step, without a big-bang rewrite.

03

Make your app LLM-ready

MCP server, OpenAPI spec, typed SDK and a permission model your security team can sign off.

04

Agentic development

We build with your team using coding agents, and show them how to keep quality under control.

Cases

Measured, not claimed.

Three of our own builds, with the source and the raw data on GitHub.

Open Source

The approach, in public code.

Also on Packagist and npm

  • php-geobuf

    Geobuf, a compact format for geodata, in PHP.

    43,822 downloads · Packagist
  • php-ron

    RON in PHP: JSON's value model with a lighter syntax, for people and LLMs.

    2,108 downloads · Packagist
  • datastar-attribute-on-keys

    Datastar plugin that binds key combinations to actions.

    1,284 downloads · npm
  • datastar-attribute-prop

    Datastar plugin that keeps element properties in sync with signals.

    1,017 downloads · npm
  • cashctrl-ts-sdk

    Typed TypeScript client for all 376 endpoints of the CashCtrl API, with an OpenAPI 3.1 spec.

    689 downloads · npm
Blog

Long reads, with the raw data.

Objections

Fair questions.

What does this bring us as a business?

Lower development costs, because there is less architecture to build and keep in sync. Lower running costs, because one server replaces a cloud of metered services. Faster changes, because logic and state live in one place. And predictable performance, because the server decides how much it sends.

Isn't this old-fashioned?

Server-rendered HTML is how the web started. What's new is streaming updates over a single SSE connection, so the page feels real-time without shipping your application state to the browser.

Won't it feel slow without an SPA?

We measured it twice on a mid-range phone over slow 4G. Our version of the same chat app became interactive 8.3 times sooner than the Next.js original, and on our Kanban board a dragged card is confirmed by the server after 253 ms, where PLANKA, built with React, needs 712 ms.

Does SQLite scale?

With a single writer, performance is almost never the issue. All writes go through one connection, one after the other, so they never wait on each other's locks, and reads run alongside them without waiting. The database is a file next to the application, so a query costs no network round trip. What a single writer rules out is many processes writing at once, and the architecture is built not to need that. The writer of our Kanban board handles about 13,800 moves a second with 200 people moving cards at once.

What if the one server goes down?

systemd restarts a crashed process within seconds. Litestream copies every change to object storage in Switzerland about a second later, and a daily test restore checks that the copy works. If the server itself fails, a new one restores the data as it starts. That is how our SaaS Libretto runs. Until the new server is up, the app is down. For most business apps that is a fair price for not running a cluster; if it isn't for yours, we'll tell you before we start.

What about offline-first?

For most business apps it's the wrong default. Offline-first means optimistic updates: the browser shows a result before the server has accepted it, and has to take it back when the server refuses. That moves conflict handling into every client. We keep the server in charge and show honestly what it has confirmed. Where real offline work is essential, a native app is the better tool.

Aren't we locking ourselves in to you?

Go, SQLite and systemd are boring, open and widely known. The code is yours, and any Go developer can take it over.

Is it safe to let an AI agent write to our system?

Only if you decide it is. Our MCP servers are read-only by default. Write tools only exist in write mode, and every write is shown as a preview until someone confirms it.

Will AI-written code become unmaintainable?

It will in a sprawling architecture. In a small codebase with one binary and one database, a reviewer can still read every change, and that is the point.

Portrait of Michael Bolli
About

Problem solvers, not a dev shop.

Behind zwei und eins gmbh is Michael Bolli. For over 20 years he has built and looked after web applications, with a focus on architecture, performance and systems that stay maintainable.

He works without unnecessary framework layers, joins existing systems and teams quickly, and maintains open-source projects such as nfsen-ng and php-via.

Aarberg, Switzerlandgithub.com/mbolliLinkedIn

Contact

Tell us what's too complicated.

We only use your details to answer you. Privacy policy.

Prefer email?