Skip to content

About

CLI tool to track, rate, and manage AI models across Ollama, llama.cpp, and ComfyUI backends

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

mr — Model Registry v1.5.0

A CLI + MCP server for tracking, rating, and managing AI models across three local backends: Ollama (via Docker), llama.cpp (.gguf files), and ComfyUI (.safetensors, .ckpt, etc.). State is stored in a local SQLite database.

Three files, one engine:

  • mr_core.py — engine/logic (no UI)
  • mr.py — interactive CLI (click + rich)
  • mr_mcp.py — MCP server so agents can manage the registry over the LAN without shell/filesystem access

Features

  • Scan all three backends in one command and keep a unified registry
  • Rate models 1–5 and assign statuses (active, favorite, on_hold, blacklisted, …)
  • Pull models from HuggingFace or CivitAI with download tracking
  • Enrich registry entries with HF download counts, likes, architecture, and CivitAI trigger words
  • Blacklist models with a reason so you're warned before accidentally re-downloading them
  • Cross-backend duplicate detection (same hf_repo on multiple backends)
  • Audit log: every mutating operation is recorded in an events table
  • Model tagging system for custom categorization
  • Copy models between GGUF backends
  • Restore missing ComfyUI models from their recorded source
  • Automatic directory flattening for HuggingFace downloads

Requirements

  • Python 3.10+
  • Docker (for the Ollama backend)
  • pip packages: click, rich, requests, huggingface_hub, gguf, mcp[streamable-http] (see requirements.txt)

Installation

git clone https://github.com/TorvaldUtne/model-registry.git
cd model-registry
python -m venv venv
# Windows
venv\Scripts\activate
# macOS / Linux
source venv/bin/activate
pip install -r requirements.txt

Optional: add mr to your PATH

On Windows you can copy or symlink mr.py and create a small wrapper so you can type mr anywhere:

@echo off
python "C:\path\to\model-registry\mr.py" %*

Save it as mr.bat somewhere on your PATH.

Quick start

# First-time setup (interactive wizard, writes config.json)
python mr.py init

# Scan all enabled backends
python mr.py scan

# List locally installed models
python mr.py list

# Show full details for a model
python mr.py show llama3

# Rate a model interactively
python mr.py rate llama3

# Pull a model from HuggingFace (llama.cpp backend)
python mr.py pull bartowski/Llama-3.2-3B-Instruct-GGUF

# Pull from CivitAI into ComfyUI
python mr.py pull "urn:air:sdxl:checkpoint:civitai:2218365@2741096"

# Fetch HuggingFace + CivitAI metadata for all registry entries
python mr.py enrich

# Summary report
python mr.py report

Configuration

mr init generates config.json next to mr.py. You can also copy config.example.json as a starting point:

{
  "registry_db": "",
  "backends": {
    "ollama": {
      "enabled": true,
      "mode": "docker",
      "docker_container": "ollama"
    },
    "llamacpp": {
      "enabled": true,
      "model_dir": "/path/to/gguf/models",
      "extensions": [".gguf"]
    },
    "comfyui": {
      "enabled": false,
      "base_dir": "/path/to/ComfyUI/models",
      "extensions": [".safetensors", ".ckpt", ".pt", ".pth", ".bin"]
    }
  },
  "huggingface": {
    "token_env_var": "HF_TOKEN"
  },
  "civitai": {
    "token_env_var": "CIVITAI_API_KEY",
    "web_host": "civitai.red",
    "api_host": "civitai.com"
  },
  "display": {
    "date_format": "%Y-%m-%d",
    "max_name_width": 60
  },
  "mcp": {
    "host": "0.0.0.0",
    "port": 8321,
    "mode": "readonly",
    "stateful": false
  }
}

Set registry_db to an absolute path to store the database somewhere other than the script directory. Leave blank to use registry.db next to mr.py.

CivitAI split its web frontend: civitai.green (SFW only) and civitai.red (includes NSFW; serves all models). civitai.web_host controls the browse links shown by mr show (default civitai.red); civitai.api_host controls API calls (default civitai.com, except that a CivitAI URL ref uses the host from that URL).

The optional mcp section configures the MCP server:

"mcp": {
  "host": "0.0.0.0",
  "port": 8321,
  "mode": "readonly",
  "stateful": false
}

Agent access via MCP

Start the MCP server so agents (e.g. Hermes) can use mr without being given shell or filesystem access:

python mr_mcp.py                 # read-only server on 0.0.0.0:8321
python mr_mcp.py --read-write    # also expose write tools
mr-serve.bat --read-write        # same via launcher
  • Endpoint: http://<host>:8321/mcp
  • Stateless by default: the Streamable HTTP transport mints no session id and ignores any mcp-session-id header, so a client that cached a session id from a previous run (or after the 30-minute idle expiry) can never hit a hard 404. These tools are pure request/response, so nothing depends on session state. Pass --stateful (or set "stateful": true in the mcp config) to opt back into stateful sessions if a client needs resumability or server-initiated requests.
  • Read-only by default: exposes mr_list, mr_show, mr_report, mr_search, mr_backends only.
  • Read-write (--read-write or "mode": "readwrite") additionally exposes mr_scan, mr_enrich, mr_rate, mr_status, mr_note, mr_touch, mr_tag, mr_untag, mr_pull, mr_delete, mr_remove, mr_removeall, mr_rename, mr_copy, mr_blacklist, mr_restore.
  • Destructive tools (pull, delete, remove, removeall, rename, copy, blacklist, restore) require confirm=True in the call, so an agent always states intent explicitly.
  • No authentication — run it only on a trusted local network.

Tools return structured JSON (never raw shell). Each engine_* function in mr_core.py is registered once as an mr_<name> tool.

API tokens

Tokens are read from environment variables (not stored in config):

export HF_TOKEN=hf_...          # HuggingFace (required for gated repos)
export CIVITAI_API_KEY=...      # CivitAI (required for gated models)

Commands

Command Description
init Interactive setup wizard. Writes config.json and initialises the DB.
scan Scan all enabled backends and update the registry.
list List registry entries (local & non-blacklisted by default).
show MODEL Full detail panel for a model.
rate MODEL Set rating (1–5), status, and an optional note interactively.
status MODEL STATUS Change status without touching the rating.
note MODEL [TEXT] Append a timestamped note.
touch MODEL Mark last_used = now (for tracking use outside this tool).
report Summary: totals by backend/status, unrated list, blacklisted list, cross-backend duplicates.
pull REF [VARIANT] Download a model and register it. See below.
rename MODEL NEW_NAME For GGUF backends, renames the directory containing the model (file name unchanged). For ComfyUI, renames the file in place (subdir stays put) and enriches the new name with CivitAI metadata when available.
delete MODEL Remove a model from Ollama or disk; DB record is kept with status=deleted.
remove MODEL Hard delete a model from the registry (completely removes DB entry).
removeall Purge all models with status='deleted' from the registry (hard delete).
tag MODEL TAGS... Add one or more tags to a model.
untag MODEL [TAGS...] Remove specific tags or all tags if none provided.
backends List configured backend names with their status.
copy SRC_BACKEND DST_BACKEND MODEL_NAME Copy a model between GGUF backends (Ollama/ComfyUI are rejected).
restore Re-download all missing ComfyUI models that have a known source. --dry-run to preview.
blacklist MODEL [REASON] Blacklist and auto-delete a model. Future pulls warn before proceeding.
enrich Fetch HuggingFace and CivitAI metadata for all registered models. Unenriched ComfyUI files are also matched on CivitAI by SHA-256 hash.
search TERM Search registry by name, HF repo, notes, or tags.

list options

--backend   ollama | llamacpp | comfyui
--status    active | unrated | blacklisted | deleted | on_hold | testing | keep | favorite
--unrated   Show only models with no rating
--all       Include non-local and blacklisted models
--deleted   Show only deleted models

pull reference formats

Backend is auto-detected from the ref format:

Format Example Backend
Plain Ollama name llama3.2:latest ollama
org/repo (HF) bartowski/Llama-3.2-3B-GGUF llamacpp
.gguf filename model.Q4_K_M.gguf llamacpp
hf.co/org/repo:tag hf.co/bartowski/Llama-3.2-3B-GGUF:Q4_K_M ollama
org/repo VARIANT (new) mradermacher/RolePlayer-V6-LLaMa-70B-GGUF Q5_K_M llamacpp
HF resolve URL https://huggingface.co/org/repo/resolve/main/file.safetensors comfyui
AIR tag urn:air:sdxl:checkpoint:civitai:1234@5678 comfyui
CivitAI version ID civitai:12345 comfyui
CivitAI URL https://civitai.com/models/1234?modelVersionId=5678 comfyui

Use --backend to override auto-detection. For ComfyUI downloads, --subdir is required (e.g. checkpoints, loras, vae); it is auto-detected from AIR tags, the HF file path, and the CivitAI API when possible, and the command fails with a clear error when it cannot be determined. --rename saves CivitAI pulls under a metadata-rich name (name + version + base model + fp + CivitAI id) instead of the upstream filename.

# Force a HF repo into ComfyUI/loras
python mr.py pull stabilityai/stable-diffusion-xl-base-1.0 --backend comfyui --subdir checkpoints

# Specific GGUF variant via glob pattern
python mr.py pull bartowski/Llama-3.2-3B-Instruct-GGUF --file "*Q4_K_M*"

Model statuses

Status Meaning
unrated Default; not yet evaluated
active In regular use
favorite Top-tier model
keep Worth keeping, not actively used
testing Under evaluation
on_hold Paused — may reconsider later
blacklisted Do not use; warns on future pull attempts
deleted Removed from disk; DB record retained (or removed entirely with mr remove)

Database

The SQLite database (registry.db) has two tables:

  • models — one row per model with all metadata (rating, status, size, source URL, HF stats, CivitAI trigger words, tags, etc.)
  • events — append-only audit log of every mutating operation

The schema migrates automatically when new columns are added, so existing databases are never broken by upgrades.

Tags

Models can be tagged with custom categories:

python mr.py tag gembrain RP General Coding Uncensored
python mr.py untag gembrain uncensored

Tags appear in mr list and mr show output, and can be searched:

python mr.py search RP

Testing

pip install -r requirements-dev.txt
python -m pytest tests -q

The suite runs entirely against a temporary SQLite database and temporary model directories, so it never touches your real registry or model files.

Version

The version lives in mr_core.__version__ (re-exported by mr.py). Run mr without arguments to see it:

$ mr
Model Registry v1.5.0
Run mr --help for available commands.

License

MIT — see LICENSE.

Changelog

v1.5.0

  • mr enrich now matches unenriched ComfyUI files on CivitAI by SHA-256 hash, backfilling provenance (source_url/source_type), base model, and trigger words. Adds file_hash/hash_checked columns; unmatched files are cached so they aren't re-looked-up (--all re-checks).
  • CivitAI browse links are configurable: civitai.web_host (default civitai.red; civitai.green is SFW-only) and civitai.api_host (default civitai.com).
  • mr rename for ComfyUI now renames the file in place (subdir stays put) and enriches the new name with CivitAI metadata; GGUF backends still rename the containing directory. Model resolution tolerates a filename passed with its extension (foo.safetensors → foo).
  • mr pull --backend comfyui auto-detects the subdir from the repo file path or CivitAI file type and no longer nests models/loras/loras/foo; meaningful extra folders (e.g. loras/author/foo) are preserved. Bundled multi-version AIR tags (civitai:ID@VER+VER2) are supported.
  • CivitAI pull fixes: correct file id selection, subdir, trigger-word capture, and sanitized filenames; HF pulls show per-file download progress.
  • MCP transport is stateless by default (stateful: false), so a stale or expired mcp-session-id can never cause a hard 404; pass --stateful (or "stateful": true) to opt back in.
  • Scan fixes: ComfyUI duplicate detection, no re-fetching of known GGUF context windows, and no no-op scan_updated events when nothing changed.
  • Fixed a batch of silent-wrong-behavior bugs across the engine, CLI, and MCP server; added a pytest suite under tests/.

v1.4.0

  • New architecture: engine extracted to mr_core.py; mr.py is the CLI; added mr_mcp.py, an MCP (Streamable HTTP) server for agent access over the LAN.
  • Implemented read-only / read-write modes with opt-in gating so testing write paths is safe (see "Agent access via MCP").
  • Existing CLI behavior and output preserved; interactive prompts still live in the CLI, engines never prompt.

v1.3.0

  • Fixed param_count enrichment (HuggingFace safetensors.total key was never read)
  • Fixed mr pull to ComfyUI overwriting an unrelated Ollama row that shared the same hf_repo
  • Rewrote the GGUF context-length reader: the raw header parser (now tried first, ~5ms) conforms to GGUF v1/v2/v3, and the gguf library is the fallback. Previously the binary parser read wrong offsets and never found context_length
  • mr enrich now commits after each model so progress survives interruption; GGUF context extraction no longer needs network calls for local files
  • mr delete / mr blacklist now remove the whole model directory when it is exclusively that model's (including multi-shard GGUF siblings); backend roots and ComfyUI category subdirs are never removed
  • mr removeall now actually purges deleted rows (previously a no-op that re-logged them)
  • Scan no longer re-fetches HuggingFace context windows for models that already have one, and no longer writes no-op scan_updated events when nothing changed
  • mr restore now reports real failures instead of counting every pull as success
  • CivitAI download filenames are sanitized (no path separators or unsafe characters)
  • mr copy rejects Ollama/ComfyUI sources and destinations with clear errors
  • Fixed a crash when a ComfyUI HuggingFace download was flattened before its size was read
  • Fixed broken INSERT for top-level single-file GGUF models (missing currently_local value since v1.2.7)

v1.1.0

  • Added mr tag and mr untag commands for model categorization
  • Added mr copy command to duplicate models between backends
  • Added mr remove and mr removeall for hard deletion
  • Added mr backends to list configured backends
  • Fixed mr rename to only rename directories, not files
  • Fixed HuggingFace downloads to flatten nested subdirectories
  • Added new download syntax: mr pull org/repo variant (instead of org/repo:variant)
  • Added --deleted flag to mr list to show deleted models
  • Added --deleted flag to mr search to include tags in search

v1.0.0

  • Initial release with scan, rate, pull, blacklist, enrich, and other commands

About

CLI tool to track, rate, and manage AI models across Ollama, llama.cpp, and ComfyUI backends

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages