Skip to main content

Generation Tracker & Community Settings

Overview

A local SQLite database that tracks every generation’s settings, counts reuse, and optionally shares anonymized public-LoRA settings to a Cloudflare backend. The MCP server queries the local DB to suggest “what worked before” when building new workflows, and can also fetch community-aggregated settings.

Architecture


Local Database: generations.db

Location: <comfyui_path>/comfyui-mcp/generations.db (Lives alongside the user’s ComfyUI data, gitignored.)

Schema

Settings Hash

The settings_hash is a SHA256 of a canonical JSON string containing only the settings identity fields, sorted alphabetically. This is what defines “the same combo” — resolution is intentionally excluded because the same sampler/steps/CFG combo works across resolutions and we want those to count together. Models and LoRAs are identified by their AutoV2 content hash (first 10 chars of SHA256), not filenames. This means renamed files, different quantizations of the same weights, or the same model downloaded from different sources all map to the same identity.
Excluded from hash (tracked per-row but not part of the fingerprint):
  • width, height — resolution is a per-generation choice
  • model_name, lora_name — display names, not identity
  • preset_name — informational only
  • neg_prompt_hash — prompt content is never part of settings identity
When a generation runs with an already-seen settings_hash, we UPDATE reuse_count += 1 and created_at to the latest timestamp instead of inserting a duplicate row. This keeps the DB compact and gives us a natural popularity signal.

File Identification Flow

All models (checkpoints, UNETs) and LoRAs go through the same hashing pipeline. The file_hashes table caches results so we only compute SHA256 once per file version.
Privacy rule: Only generations where lora_civitai_id IS NOT NULL (or no LoRA) are eligible for community sharing. Private LoRAs never leave the machine. Hashing note: SHA256 of large safetensors files (2-12GB) takes 5-20 seconds. We run this in a worker thread and cache aggressively. The cache invalidates only when file size or mtime changes (renamed files keep their hash).

Settings Advisor (MCP Hook)

When building a new workflow, the MCP server queries the local DB:
The advisor returns the top settings to the LLM as context, letting it suggest proven combos to the user. Combined with model-settings.json presets, this creates a feedback loop: defaults → user experiments → local tracking → better suggestions.

NPM Scripts

npm run generations:review

Interactive CLI that shows what would be shared:

npm run generations:stats

Local-only stats view:

Community Backend (Cloudflare)

Stack

  • Cloudflare Workers — API endpoints (free tier: 100k req/day)
  • Cloudflare D1 — SQLite-compatible edge database (free tier: 5M reads/day, 100k writes/day)
  • Rate limiting — Cloudflare’s built-in rate limiting rules

Endpoints

POST /api/v1/settings/submit

Submit anonymized generation settings.
What is sent: content hashes (AutoV2), CivitAI IDs, sampler params, reuse counts. What is NOT sent: prompts, negative prompts, image data, filenames, file paths, resolutions, private LoRA/model hashes (no CivitAI match), usernames, IP-derived location, timestamps.

GET /api/v1/settings/search

Query community-aggregated settings.
Searchable by: model_family, model_hash, model_civitai_id, model_name, lora_hash, lora_civitai_id, lora_name, sampler, scheduler. All filters are AND-combined. Name fields support LIKE / substring matching (e.g. ?model_name=copax matches “CopaxTimelessV11.safetensors”). Rate limit: 60 req/min per IP.

GET /api/v1/settings/popular

Top settings across all users, filterable.

D1 Schema (Cloudflare)

On submit, the worker does an UPSERT keyed on settings_hash:
  • If new: INSERT with total_uses = reuse_count, unique_users = 1
  • If exists: total_uses += reuse_count, unique_users += 1

MCP Tools (New)

generation_log

Called automatically when enqueue_workflow is invoked. Extracts settings from the executed workflow and logs to SQLite. Not exposed to the user — internal hook.

get_history — the suggest job

get_history — the stats job


Implementation Order

Phase 1: Local tracking (no network)

  1. Add better-sqlite3 dependency
  2. Create src/services/generation-tracker.ts — DB init, log, query
  3. Create src/services/lora-identifier.ts — SHA256 hashing + cache
  4. Hook into workflow executor — log after successful run
  5. Add the settings-suggestion MCP surface
  6. Add npm run generations:stats script

Phase 2: CivitAI identification

  1. Add CivitAI hash lookup in lora-identifier
  2. Cache results in lora_hashes table
  3. Filter shareable vs private in generation log

Phase 3: Community sharing

  1. Stand up Cloudflare Worker + D1
  2. Add npm run generations:review script (preview + confirm)
  3. Add submit endpoint client in MCP server
  4. Add search_community_settings MCP tool
  5. Rate limiting + privacy review

Privacy Guarantees

  1. Opt-in only — Nothing is shared without explicit npm run generations:review confirmation
  2. No prompts — Text prompts and negative prompts are never stored in shareable form
  3. No images — No generated images or thumbnails
  4. No private LoRAs — Only LoRAs with a verified CivitAI hash are included
  5. No PII — No usernames, paths, IPs stored server-side (Cloudflare Workers don’t log by default)
  6. Local-first — The local DB works fully offline; community features are additive
  7. Reviewable — Users see exactly what will be sent before confirming
  8. No tracking — No analytics cookies, no device fingerprinting, no session tracking