A macOS menu-bar utility that watches memory across every local LLM provider you run — Ollama, oMLX, LM Studio, llama-swap and koboldcpp — and lets you eject a model from any of them in one place.
Each provider manages its own memory and is blind to the others. Ollama doesn't know oMLX is holding 30 GB; oMLX doesn't know LM Studio just loaded a 7B. Individually they all behave; together they push the machine into swap. LLMFuse is the only thing with a whole-system view.
Not a chat app, not a proxy. It sits beside your providers rather than in front of them, so it sees models loaded by anything — a script, an editor plugin, another app — not just traffic routed through it.
- How much memory is in use, as a stacked bar with one segment per resident model, so a model's share of the machine is something you see rather than compute.
- Every model resident across every provider, largest first, with its size, the context window it's actually loaded at, and which provider owns it.
- One-click eject for any of them.
- A log of what changed and what LLMFuse did about it.
macOS 15 or later, Apple Silicon or Intel. No dependencies — LLMFuse talks to providers over their local HTTP APIs and reads the kernel's own process table.
Download the .dmg from Releases and drag to
Applications.
Or build from source:
git clone https://github.com/enclavum/llmfuse.git
cd llmfuse
make runThat builds, ad-hoc signs and launches ./LLMFuse.app — no Apple ID or certificate needed.
There isn't any. LLMFuse detects each provider's port and API key from what's already on the machine: its settings file, its launch arguments, its environment, or — when nothing states a port — the kernel's socket table, confirmed by asking the port whether it answers that provider's API. Detection re-runs every second, so a provider that restarts on a different port is followed without you touching anything.
The one exception is LM Studio's API key. LM Studio stores only a SHA-512 hash of it, so no amount of reading the machine recovers it — if you've enabled authentication there, type it in Settings → LLMFuse → Configure. Nothing else needs entering, ever.
Model sizes are measured, not estimated, and every provider was checked against ground truth by loading a model and watching what the machine actually consumed:
| Provider | Size source | Error vs. measured |
|---|---|---|
| oMLX | its own actual_size |
+0.2% |
| Ollama | its own /api/ps size |
−0.8% |
| koboldcpp | serving process | −3.1% |
| llama-swap | per-model server process | −5.6% |
| LM Studio | model's process | −8.4% |
A model file's size on disk is not used: it's weights without the KV cache, and it understated one koboldcpp model by 27 GB. Where a provider measures its own memory it's trusted; where it doesn't, the process holding the model is measured directly.
Sizes are 1024-based throughout (GiB shown as "GB"), matching how macOS reports RAM — which is why a
model can read ~7% smaller here than in ollama ps, which prints decimal GB.
make run # build + ad-hoc sign + launch
make test # unit tests (needs full Xcode — the Command Line Tools ship without XCTest)
make cleanTests that talk to a live provider skip themselves when it isn't running, so the suite is green on a machine with nothing installed — and actually exercises the HTTP path on one where a provider is up.
The release targets need a one-time setup:
- A Developer ID Application certificate in your keychain.
.signing.mk— copy.signing.mk.exampleand fill in your identity string.- Notary credentials, stored once:
The profile name is just a local keychain label — credentials are per Apple ID and team, not per project, so point
xcrun notarytool store-credentials llmfuse-notary \ --apple-id <apple-id> --team-id <team-id> --password <app-specific-password>NOTARY_PROFILEat one you already have if you'd rather not create another. LLMFuse.provisionprofile— a Developer ID provisioning profile for the app's bundle ID, saved in the repo root. This authorizes the restrictedkeychain-access-groupsentitlement; without it the app doesn't merely lose the Keychain, it fails to launch.
Then:
make release # signed + notarized + stapled LLMFuse.dmg
make verify # inspect signature, entitlements, Gatekeeper verdictBoth .signing.mk and *.provisionprofile are gitignored.
LLMFuse makes no network requests except to localhost and, if you leave update checks on, to
GitHub's releases API to compare version numbers. It sends nothing anywhere, and reads only
same-user processes.
