A hand-rolled agent harness for local LLMs.
Add it to your home screen and it opens like any other app - its own icon, full screen, a push notification when a long job finishes. Behind that icon there is no cloud. It is talking to a model running on hardware you own, over your own network, and nothing you type leaves it.
There is a terminal UI too, hand-rolled over raw ANSI, for when you are already in a shell. Same agent underneath, same sessions, different face.
It is not going to top the frontier models, and some days you will feel that. It is also offline, private, yours to read and change, and free per token.
- Runtime
- Bun + TypeScript
- Models
- Any OpenAI-compatible endpoint
- Installs as
- A home-screen PWA, or a Mac app
- Status
- Private beta
What it is
The part that goes around the model.
An agent harness is the loop: it reads what you asked for, decides which tools to pick up, runs them, feeds the results back, and goes around again until the job is done or you stop it. Most harnesses assume a cloud endpoint and a companyβs API key. Sashimi assumes neither.
You point it at whatever is serving an OpenAI-compatible endpoint. Here that is usually oMLX or a llama.cpp server holding DeepSeek on the same desk; it will just as happily talk to a hosted endpoint when you want one. Switching is /provider. Adding a new one is config, not code.
The rest is the ordinary furniture of a working agent, built small. A tolerant tool-call parser, because open models are inconsistent about this and will cheerfully emit a call as a <tool_call> tag or a bare JSON blob instead of the native format. Read, write, edit, ls, glob, grep and shell. Sessions that persist as JSONL, so /resume picks up any conversation you have ever had. And a local retrieval layer that indexes folders and past sessions so the agent can search them.
The app
It installs on your phone.
Sashimi serves a web app on port 8787, and that app is a proper PWA - a manifest, a service worker, maskable icons. Open it on your phone and Add to Home Screen, and from then on it launches standalone: no browser chrome, its own icon in the dock or on the springboard, and web push, so a job you kicked off before breakfast can tap you on the shoulder when it lands.
The part that surprises people is what is behind it. There is no account, no server of ours, nothing in the middle. The app is talking to the machine on your desk. By default that machine only listens on 127.0.0.1; to reach it from a phone you flip Network Access on and use the Tailscale address, which is private, encrypted and device-authenticated rather than open to the internet. If you want a trusted certificate at a real name, make caddy puts one at something like sashimi.somegood.co, reachable only on your tailnet.
Turn on the background service and a macOS LaunchAgent keeps sashimi serve running with every window closed, so scheduled prompts fire whether or not you are at the desk. This siteβs homepage is built that way - a cron at 02:30 every morning, running the full agent loop on a Mac mini.
And a terminal, when you want one
- Same agent, different face
- The TUI is hand-rolled straight onto a cell buffer over raw ANSI - no Ink, no React, no terminal framework - which is how it carries a live activity panel beside the transcript, a divider you drag, and wheel scrolling without a dependency tree. Start a conversation in the terminal, pick it up on your phone: it is one session store, not two products.
Local models, private inference
Nothing leaves the machine.
Part of it is doubting the frontier labs subsidise tokens forever. Part of it is control of access and privacy. Part of it is just fun to tinker and see what you can get out of a fixed set of hardware and model constraints.
Whatever the reason, the practical shape is the same. There is no vendor in the middle, so there is no retention policy to read, no training-data question to ask a lawyer about, and no rate limit that moves without warning. When the wifi drops, the agent keeps working. When you close the laptop, the transcript is still only on the laptop.
The honest tradeoff: an open-weight model on a Mac is not GPT-class, and long-horizon planning is where the gap shows most. For reading a codebase, drafting, summarising, moving files around and the hundred small errands that make up a working day, it is genuinely fine. And it costs nothing per token, which changes how freely you use it more than we expected.
Your endpoint, your weights
oMLX, llama.cpp, a bespoke DeepSeek server, LM Studio - anything speaking the OpenAI-compatible shape. One thin provider adapter, swapped at runtime.
Secrets stay out of config
Keys are named by env var and read from
~/.sashimi/.env, never written intoconfig.json. There is nothing to leak in a repo.Retrieval without upload
Indexes are built with a local embedding model and stored under
~/.sashimi/index/. Your folders are searchable without being sent anywhere.Private by default over the network
Reachable from a phone over Tailscale rather than the open internet, with an optional trusted cert at a name on your own tailnet.
Who itβs for
People with a machine and a reason.
Folks working with material that cannot be pasted into a hosted chat window - client files under NDA, records with real names in them, unreleased work, anything a legal team has an opinion about. Folks somewhere the network is the least reliable part of the setup. Teams who would rather run a house agent they can read the source of and change than rent one.
And tinkerers. Sashimi started as a personal tool and still reads like one. If your idea of a good evening is finding out how much you can get out of 64gb and a quantised 30B, you will be at home here.
It is probably not for you if you want a polished product with a support contract, or if you do not have hardware that can hold a model. Both are perfectly reasonable things to want. This just isnβt that yet.
What you need
- A machine that can serve a model
- An Apple Silicon Mac with enough unified memory to hold the weights you want. A 64gb M4 Pro mini runs a quantised 30B comfortably; smaller models are happy in far less.
- A model backend
- oMLX, llama.cpp or equivalent, serving an OpenAI-compatible endpoint. Or point it at another Mac on your tailnet and let that one do the work.
- Bun
- The CLI and the desktop app both run on it. The
.dmgbundles the app itself, but the runtime needs to be there.
How it works
One core, several faces.
The agent is decoupled from everything you look at. Context budgeting, sessions, tool dispatch - one loop, and the phone app, the Mac app and the terminal are three views onto it rather than three products. Start something in one and finish it in another; the session is the same file on disk either way.
Hand-rolled is not a style note, it is why that works. Everything visual is data - colours, the panel border charset, the progress-bar glyphs - so one palette describes the terminal, the web app and the watch face, and re-skinning any of them is a single edit in a single file. There is no framework in the middle deciding what a front end is allowed to be.
- 01
You ask
From the home-screen app, the terminal, or a cron automation firing while nobody is watching.
- 02
Context is budgeted
The conversation is trimmed to fit the window you configured, so a long session degrades gracefully instead of erroring.
- 03
The model streams
Straight from your endpoint. Tokens land as they arrive; nothing round-trips through us.
- 04
Tool calls are parsed
Native OpenAI calls first, then a fallback parser for the models that emit tags, fenced JSON, or something close enough.
- 05
Tools run, results go back
Read, edit, shell, semantic search. The output is fed back in and the loop goes around again.
- 06
The session is written
Appended to JSONL on disk. Resumable, greppable, and entirely yours to delete.
Get access
Itβs a private beta.
The repo is private and the build goes out by hand. That is mostly because it is still moving quickly and we would rather talk to the first people running it than field issues from strangers. We let folks in a few at a time.
Tell us what you would point it at and what you would run it on. We read every one of these ourselves.
Built by Some Good Co
We built this for ourselves first.
Sashimi came out of our own work and still runs it - including this siteβs homepage, which it composes fresh every morning and files in the archive. Building the thing we use is how we prefer to find out whether an idea holds up.
If you have something in this territory - an agent that has to run somewhere private, a model you would rather own than rent, a workflow nobody sells a product for - that is the kind of work we do for other people too. Holler.