An agent at the centre
I run my working life across six tools that don't talk to each other. Rather than migrate to one mega-app, we built a small MCP server for each and put an agent in the middle — and the agent turned out to be the integration.
Six good apps that don't talk
My working life runs across six things. OmniFocus holds every task, work and personal. OmniOutliner holds the structured stuff — RAID logs, documentation that belongs to a project. OmniPlan holds the roadmap. A reMarkable tablet holds my handwriting, because I think better with a pen. Google Calendar holds time, and Miro holds the mess before the plan.
Every one is excellent at its job, which is exactly why the usual advice is useless.
- Migrate to one app and you trade six good tools for one mediocre one.
- Wire them point to point and the glue grows with the square of the number of tools.
- Use an automation service and you get what those are good at: moving fields around with no idea what any of it means.
What was missing was not a pipe between the apps. It was judgement in the middle — something that knows my conventions, can read every surface, write carefully to each, and decide what belongs where. That is an agent's job.
What we built
Four small MCP servers in Go on the official SDK, each connecting the Claude desktop app to one Mac application. Google Calendar and Miro use connectors that already existed, and that mix is the point: one protocol covers what we built and what we didn't.
It runs locally, driving the applications through Apple's own automation layer, with macOS prompting for permission on every app. I want to be accurate about the data path, because write-ups usually get this wrong: what the agent reads is processed by Claude's models at Anthropic, exactly like anything you would type into a chat window. What is true is that there is no third-party service in the middle and nothing is syncing to somebody's cloud. MCP is an open protocol, so the same servers work with local-model clients if you would rather make that trade.
The write surfaces are deliberately small. None of the servers can delete anything, and the strongest operation any of them performs is reversible inside the app it touched. The safety story is not "trust us" — it is that each codebase is small enough to read in an evening.
The part that makes it work is not the servers, though. A server gives the agent an ability. A skill file gives it judgement: my folder structure, my conventions, which surface wins when two disagree, what to do when something looks wrong.
Ability without judgement is just another integration. Judgement is the difference between automation and an agent — and it lives in a text file, not in the model.
What we learned building it
The servers were designed, written and debugged in conversation with Claude — the same agent that now uses them. At one point it was live-testing tools against my real data from a cloud session through a bridge to my Mac, finding bugs and shipping fixes in the same sitting. The thing that manages my calendar helped build its own hands.
Then OmniFocus taught us the most useful lesson of the project. Its AppleScript dictionary cheerfully accepted every spelling of "move this project into that folder" we could invent, and did nothing. No error — the move simply didn't happen. The fix was to route structural operations through Omni Automation, the apps' first-party JavaScript API, via a JXA bridge. Drive an application the way its vendor drives it.
OmniPlan produced two surprises in one afternoon. Pinning both ends of a bar doesn't stretch it, it slides it — duration is its own property, which is why there is a durationDays field on the tool. And setting a date to null doesn't unpin it; it pins it to the epoch, which there means 2001. Both became honest warnings in the tool results the same day, because the alternative is an agent confidently doing the wrong thing to a roadmap.
The sync loops don't process events. Every run re-derives the desired state from fresh reads, joins by id and never by name, keeps a small state file only to work out which side moved, and flags conflicts to me instead of guessing. It is boring, and boring is the point. One failure is worth stating plainly: a sync once skipped inbound work because it reused a snapshot from earlier in the run. Nothing errored, a task just wasn't there. The rule is now written into the skills — if the re-read didn't run, the sync didn't run.
What it's like now
In the morning I get a plan built from what is actually due and what is actually in the calendar, rather than from my optimism. After a meeting, actions land in the right projects, named the way I name things. Overnight, handwritten day notes come off the reMarkable and turn into tasks where they are tasks and documentation where they are documentation — a note about a risk ends up in that project's RAID log, joined by id rather than by hoping two names match. On the roadmap, every incomplete project is a bar; drag one and the new dates are written back into OmniFocus.
What it taught us about agentic AI in a business
Two things transfer. The value is not in a smarter model, it is in connecting systems that were never designed to talk — which in most organisations is where the friction lives. And the difference between automation and an agent is entirely the judgement layer: the conventions, the rules about what it may write, the arbitration when sources disagree, the honest flag instead of the confident guess. Get that wrong and you have built a very expensive Zapier.
The four servers are on github.com/levantar-ai, MIT licensed. Each is written as a course — the Go files carry numbered lesson blocks explaining why the code is the way it is, including the parts that were wrong first.