Model Shelf
A local-first resolver for Hugging Face models — GGUF, MLX, and safetensors. Your agent checks your curated library before downloading.
> model-shelf resolve "Qwen/Qwen3-14B-GGUF" --quant Q4_K_M
shelf /Volumes/MyDrive/ModelShelf/models/gguf HIT
status found
source local_shelf
format gguf
path /Volumes/MyDrive/ModelShelf/models/gguf/Qwen/Qwen3-14B-GGUF/Qwen3-14B-Q4_K_M.gguf
Why
Local AI workflows download the same model files over and over — across tools, runtimes, and machines. Model Shelf gives you one curated library at a path you own, and one shell command that asks: do I already have this locally?
- Handles GGUF, MLX, and safetensors through one CLI — format auto-detected from the repo id.
- Publisher/repo layout that mirrors Hugging Face Hub (and matches LM Studio's expected structure) —
gguf/Qwen/Qwen3-14B-GGUF/Qwen3-14B-Q4_K_M.gguf instead of models--Qwen--Qwen3-14B-GGUF/snapshots/abc.../....
- Works with any storage you already mount: external SSD, Thunderbolt DAS, NAS, or just an internal folder.
- Downloads land directly in the shelf at the friendly path — no parallel Hugging Face cache to manage or clean up.
- A single shell command (
model-shelf resolve … --json) means any agent that can run shell commands can plug it in — no special protocols, no extra server.
Install
Claude Code (one command)
/plugin install model-shelf@alexziskind1/model-shelf
That's it. The plugin installs a skill that tells the agent to always resolve through Model Shelf, plus a SessionStart hook that auto-installs the CLI via uv on first session. Requires uv — install with curl -LsSf https://astral.sh/uv/install.sh | sh if you don't have it.
Anywhere else
uv tool install git+https://github.com/alexziskind1/model-shelf
# or
pip install git+https://github.com/alexziskind1/model-shelf
Requires Python 3.11+.
Configure
Just run:
model-shelf init
What happens depends on what Model Shelf can see:
- Your external drive already has a
ModelShelf/models/ folder → it uses that one silently. No prompt, no questions. (Most common: you've used this drive before.)
- External drives are connected but none has a shelf yet → interactive picker (arrow keys) showing each drive plus an internal-storage option and a custom-path escape hatch.
- No external drives connected → falls back to internal storage (
~/.cache/model-shelf/models) and tells you.
- Need explicit control →
model-shelf init /path/to/shelf skips detection and uses that path.
Whichever path is picked, Model Shelf creates the three format subfolders under it. Downloads then nest by publisher and repo (mirrors Hugging Face Hub, matches LM Studio's layout):
models/
├── gguf/
│ └── Qwen/
│ └── Qwen3-14B-GGUF/
│ └── Qwen3-14B-Q4_K_M.gguf
├── mlx/
│ └── mlx-community/
│ └── Qwen3-14B-4bit/
└── safetensors/
└── Qwen/
└── Qwen3-14B/
By default init does not pin a path in the config — discovery handles drive swaps and renames automatically. Pass an explicit path (model-shelf init /path/to/shelf) only when you want to pin a specific location in the config.
Switch shelves later by re-running init. Override which config file is used with $MODEL_SHELF_CONFIG or --config <path>. The user-level config (~/.config/model-shelf/config.toml) is the only implicit lookup — Model Shelf does not pick up a ./config.toml from your current directory, so unrelated tools' configs can't accidentally hijack it.
If you pass a path under /Volumes/<name>/ and <name> isn't currently mounted, init fails with a clear error instead of silently writing to the internal SSD.
Multi-shelf lookup
Model Shelf treats every shelf it can see locally as fair game when resolving a model. On every resolve it checks:
- The primary shelf (configured
shelf_root if pinned, or auto-discovered if not).
- Every mounted
/Volumes/*/ModelShelf/models/ directory (any external drive with a shelf).
- The internal default at
~/.cache/model-shelf/models (if it exists).
First hit wins. Downloads on a miss still go to the primary. So you can plug in any drive that has a ModelShelf folder, rename your main drive, or have multiple shelves spread across drives — if the file is local anywhere, it's used.
Pinned vs unpinned config
By default the config doesn't pin a specific path. The user-level config looks like:
allow_downloads = true
That's it — no shelf_root line. At runtime Model Shelf auto-discovers a primary (first external /Volumes/*/ModelShelf/models, else internal). Swap drives, rename them, plug in a different drive entirely — nothing in the config needs to change.