ComfyUI-Majoor-ProjectSettings 🚀
Project-aware outputs + workflow organization for ComfyUI — without adding any ComfyUI nodes.
This extension turns ComfyUI into a lightweight “mini pipeline”: you pick a project, it creates/maintains a clean folder structure under output/, auto-patches save/export nodes (paths + filename prefixes), and lets you save workflows inside the project (optionally mirrored to ComfyUI/workflows/).
Zero new nodes. Maximum order. Your future self will stop cursing your past self. (Maybe.)
Status & empty workflows
- The Project Settings status bar watches your canvas and turns red when the current graph is empty while prompting you (via dialog) to create or assign a project instead of flooding toasts.
- Toggle the
MajoorPS: Black status when no projectsetting (in the MajoorPS settings category) if you'd rather keep a neutral indicator while you experiment without an active project.
Key Features
- Project management inside ComfyUI (create / select / list).
- Standardized folder structure per project under
output/PROJECTS/<project>/.... - Auto-patch “save/export” nodes:
- sets a safe relative output folder (always under
output/) - sets a filename prefix (project/asset/model/date driven)
- supports many custom nodes via configurable “path widget” names.
- sets a safe relative output folder (always under
- Template-based output paths using tokens (
{BASE},{MEDIA},{DATE},{NAME},{MODEL}, etc.). - Project-aware workflow save:
- saves workflows into the project folder
- optional mirror into
ComfyUI/workflows/for compatibility.
- Project signature in workflow (
graph.extra.mjr_project) to keep provenance. - Empty-graph guard: the status bar turns red when the current graph has no nodes and the extension will prompt you to create or switch to a project, and there is an optional
MajoorPS: Black status when no projectsetting so you can work in a test mode without the warning color. - Safe path guardrails: blocks absolute paths, drive paths,
.., and other escape attempts. - Workflow Utilities: Fix Missing Models inside the Project Settings panel (no top menu).
- Workflow Utilities: Download Missing Models inside the Project Settings panel (recipes + direct URLs).
- Advanced fingerprint cache (optional) for future hash-based model resolution.
Installation
Option A — Git (recommended)
- Go to your ComfyUI folder:
ComfyUI/custom_nodes/
- Clone:
git clone https://github.com/MajoorWaldi/ComfyUI-Majoor-ProjectSettings.git - Restart ComfyUI.
Option B — ZIP
- Unzip into:
ComfyUI/custom_nodes/ComfyUI-Majoor-ProjectSettings/
- Restart ComfyUI.
✅ The extension exposes a WEB_DIRECTORY (./js) and registers API routes on startup.
UI Location
Depending on your ComfyUI version:
- If sidebar tabs are supported, you’ll see a Project Settings tab.
- Otherwise, the UI falls back to a floating panel.
Debugging logs 🐞
- To enable verbose debug logs in the UI, set
window.MJR_DEBUG = truein the browser dev console before interacting with the extension. When enabled, the UI will emit developer messages viaconsole.debug().
Project Structure (Default)
Everything lives under:
output/
└─ PROJECTS/
├─ _INDEX/
│ └─ projects.json
└─ <PROJECT_FOLDER>/
├─ 00_META/
│ └─ current.json
├─ 01_IN/
│ ├─ REFS/
│ └─ SOURCES/
├─ 02_OUT/
│ ├─ IMAGES/
│ ├─ VIDEOS/
│ └─ OTHER/
├─ 03_WORKFLOWS/
├─ 04_PRESENTATION/
└─ 05_DOCS/
projects.jsonstores your project index (last used, archived, etc.)current.jsonstores the active project on disk (useful for external scripts/tools)
Environment Variables
The extension supports various environment variables for customization:
Security & Access Control
MJR_API_KEY: API key for authentication (if not set, only loopback/localhost access is allowed)MJR_INSECURE_NO_AUTH=1: Disable authentication (NOT recommended in production)MJR_DISABLE_CSRF=1: Disable CSRF protection (NOT recommended)MJR_DISABLE_SAME_ORIGIN=1: Disable same-origin checks (NOT recommended)MJR_TRUST_PROXY=1: Trust X-Forwarded-For headers for client IP detection
Download Settings
MJR_SKIP_EXISTING_FILES=1: Skip download if file already exists (default:0- overwrite mode enabled)MJR_MODEL_DOWNLOAD_TIMEOUT: Download timeout in seconds (default:300)MJR_MODEL_DOWNLOAD_ALLOW_PRIVATE_IPS=1: Allow downloads from private IP addressesMJR_MODEL_DOWNLOAD_ALLOWED_HOSTS: Comma-separated list of allowed download hosts
Rate Limiting & Performance
MJR_RATE_LIMIT_PER_MIN: Rate limit per minute per endpoint (default:120)MJR_JOB_CLEANUP_HOURS: Hours before cleaning up old download jobs (default:1)
Example Configuration (Windows PowerShell)
# Enable overwrite mode for downloads (default behavior)
$env:MJR_SKIP_EXISTING_FILES="0"
# Or enable skip mode if you want to avoid re-downloading
$env:MJR_SKIP_EXISTING_FILES="1"
# Set custom download timeout (5 minutes)
$env:MJR_MODEL_DOWNLOAD_TIMEOUT="300"
Example Configuration (Linux/Mac)
# Enable overwrite mode for downloads (default behavior)
export MJR_SKIP_EXISTING_FILES=0
# Or enable skip mode if you want to avoid re-downloading
export MJR_SKIP_EXISTING_FILES=1
# Set custom download timeout (5 minutes)
export MJR_MODEL_DOWNLOAD_TIMEOUT=300
Note on file overwriting: By default (MJR_SKIP_EXISTING_FILES=0), the extension will overwrite existing model files when downloading. This ensures you always get the latest version and prevents issues with corrupted/incomplete downloads. Set MJR_SKIP_EXISTING_FILES=1 if you want to skip downloads when the file already exists.
Configuration: project_structure.json
You can customize the project directories and role mappings:
{
"dirs": [
"00_META",
"01_IN/REFS",
"01_IN/SOURCES",
"02_OUT/IMAGES",
"02_OUT/VIDEOS",
"02_OUT/OTHER",
"03_WORKFLOWS",
"04_PRESENTATION",
"05_DOCS"
],
"roles": {
"images": "02_OUT/IMAGES",
"videos": "02_OUT/VIDEOS",
"other": "02_OUT/OTHER",
"workflows": "03_WORKFLOWS"
}
}
dirs: physically created directoriesroles: logical aliases used by the extension
Output Templates (Path Resolver)
The extension generates relative output paths (always safe under output/) using templates.
Common Tokens
Typical server/UI token set:
{BASE}:PROJECTS/<project_folder>{MEDIA}: media subdir (e.g.02_OUT/IMAGES){DATE}:YYMMDD(e.g.251222){NAME}: normalized asset/shot name{KIND}: kind label (asset/shot/etc., normalized){MODEL}: normalized model label (optionally uppercased from UI)
Example Template
{BASE}/{MEDIA}/{DATE}/{NAME}/{MODEL}
Example resolved output:
PROJECTS/MY_PROJECT/02_OUT/IMAGES/251222/AdrianCloseUp/FLUX_DEV
Node Patching (Save/Export Nodes)
The extension scans the current graph and patches “save-like” nodes:
- detection: node type contains patterns like
save,export,combine(implementation-specific) - patch targets:
filename_prefix- plus one recognized path widget (configurable list)
Supported Path Widget Names
Runtime-config endpoint:
GET /mjr_project/config→path_widgets
If your custom node uses a different widget name for its output folder/path:
- add it to the server defaults (e.g.
PATH_WIDGETS_DEFAULTinserver/project_routes.py) - restart ComfyUI
Workflow Saving (Project-aware)
Endpoint:
POST /mjr_project/workflow/save
Behavior:
- saves the workflow to:
PROJECTS/<project_folder>/<workflows_role>/<optional_subdir>/<workflow_name>.json
- optionally mirrors to:
ComfyUI/workflows/
Returned fields usually include:
project_rel_pathworkflow_rel_dircomfy_workflow_relmirrored,mirror_error
Workflow Utilities: Fix Missing Models (Panel)
The Project Settings panel includes a "Fix Missing Models" button that scans the current graph for combo widgets whose selected model is no longer present in the available values. It proposes exact and near matches (fuzzy) and applies the selection back to the graph.
Behavior summary:
- Missing detection is local (in-memory widgets, no API required).
- Candidates are suggested via a server scan with exact + fuzzy matching.
- Applied fixes update widget values and refresh the graph.
Workflow Utilities: Download Missing Models (Panel)
The Project Settings panel includes a "Download Missing Models" button that resolves
missing model names to download recipes. You can paste direct URLs for missing items and
optionally remember them for next time in:
output/PROJECTS/_INDEX/model_sources.json
Rules:
- Only direct http/https URLs are accepted.
- Allowed extensions:
.safetensors,.ckpt,.pt,.pth,.bin - Optional SHA256 verification if provided.
- Hugging Face token can be provided via
HUGGINGFACE_HUB_TOKENorHF_TOKEN. - Default download size cap is 10GB per file; tune via
MJR_MODEL_DOWNLOAD_MAX_BYTESorMJR_MODEL_DOWNLOAD_MAX_GB. - All public hosts are allowed by default for maximum compatibility. To restrict hosts, set
MJR_MODEL_DOWNLOAD_ALLOW_ANY_HOST=0/mjr_project.download_allow_any_host=falseand configureMJR_MODEL_DOWNLOAD_ALLOWED_HOSTS(comma-separated list). - Private/local IPs are blocked by default (SSRF guard); override with
MJR_MODEL_DOWNLOAD_BLOCK_PRIVATE_IPS=0/mjr_project.download_block_private_ips=false. - POST endpoints enforce same-origin when the browser sends an
Originheader (basic CSRF mitigation). - Timeout can be tuned via
MJR_MODEL_DOWNLOAD_TIMEOUT(seconds). - Online search endpoint is rate-limited per client IP via
MJR_MODEL_SEARCH_RATE_PER_MIN(default: 30/min).
Endpoints:
POST /mjr_models/resolve_recipesPOST /mjr_models/save_recipesPOST /mjr_models/downloadGET /mjr_models/download_status
Advanced: Fingerprint Cache
An optional cache can be built under:
output/PROJECTS/_INDEX/model_fingerprints.json
The cache stores lightweight fingerprints (sha256 of first 1MB + last 1MB + size bytes). This enables future hash-based resolution when model filenames or paths change.
Endpoints:
GET /mjr_models/fingerprint_cache_statusPOST /mjr_models/build_fingerprint_cachePOST /mjr_models/resolve_by_fingerprint
API Reference (High-Level)
Base URL: your ComfyUI host/port.
Set / Select a project
POST /mjr_project/set
{ "project_name": "My Cool Project" }
List projects
GET /mjr_project/list?include_archived=0|1
List available models (from ComfyUI)
GET /mjr_project/models
Get runtime config (includes path widgets)
GET /mjr_project/config
Resolve project by folder name
GET /mjr_project/resolve?folder=<project_folder>
Preview template resolution
POST /mjr_project/preview_template
{
"template": "{BASE}/{MEDIA}/{DATE}/{NAME}/{MODEL}",
"tokens": {
"BASE": "PROJECTS/MY_PROJECT",
"MEDIA": "02_OUT/IMAGES",
"DATE": "251222",
"NAME": "AdrianCloseUp",
"MODEL": "FLUX_DEV"
}
}
Create/validate a custom output dir + prefix (conceptual)
POST /mjr_project/create_custom_out
{
"project_id": "...",
"kind": "asset",
"name": "AdrianCloseUp",
"media": "images",
"model": "Flux Dev",
"model_upper": true,
"date": "251222",
"template": "{BASE}/{MEDIA}/{DATE}/{NAME}/{MODEL}"
}
Archive / Unarchive / Delete
POST /mjr_project/archivePOST /mjr_project/unarchivePOST /mjr_project/delete
“delete” is designed to be safe-by-default: it typically removes index entries and avoids dangerous disk nukes unless explicitly implemented.
Local UI State
The UI persists state in localStorage:
- key:
mjr_project_settings_state
So your settings survive browser refreshes and ComfyUI restarts (unless the browser decides it’s in a mood).
Repo Layout (Typical)
__init__.py- exposes
WEB_DIRECTORY - imports server routes
- exposes
server/project_routes.py(AIOHTTP endpoints viaPromptServer.instance.routes)project_store.py(folder structure + safe path utils + index/current handling)
js/majoor_project_settings.js(ComfyUI extension entry, UI, hooks)state_manager.js(persistence/state)ui_components.js(UI helpers)mjr/(api, graph scan, patching, dialogs, toasts, utilities)
Troubleshooting
“I don’t see the UI”
- Confirm folder is inside:
ComfyUI/custom_nodes/ComfyUI-Majoor-ProjectSettings/
- Restart ComfyUI (not just browser refresh).
- Check browser console (F12): logs are usually prefixed with something like
[mjr].
“My save nodes are not being patched”
- The node may not expose:
filename_prefix, and/or- a recognized path widget name (
output_path,folder,save_path, etc.)
- Add your widget name to the server’s
PATH_WIDGETS_DEFAULTand restart.
“Path rejected / invalid”
- The server intentionally blocks:
- absolute paths
- drive paths (
C:\...) ..traversal- unsafe characters / escape attempts
- This is by design: the extension is strict so it doesn’t become a foot-gun.
"Ctrl+S conflicts"
- If you hook workflow saving, other extensions might also capture Ctrl+S.
- Prefer capture-phase + stopping propagation (or disable your hotkey if exposed).
"Model download fails with permission error"
If model downloads succeed but fail when moving to the models folder:
Common causes:
- Models folder is on a different drive with restricted permissions
- Antivirus is blocking file creation
- Another program has the models folder open
- Insufficient disk space
Solutions:
- Check folder permissions: Right-click models folder → Properties → Security → Add write permissions
- Add models folder to antivirus exclusions
- Close any programs that might be accessing model files
- Run ComfyUI as administrator
- Check if you have enough disk space
- Change models directory to a location with proper permissions
Recovery: If download succeeded but move failed, the file is kept at:
ComfyUI/models/.mjr_tmp/{job_id}/{filename}
You can manually move this file to your models directory.
See docs/BUGFIX_WINDOWS_DOWNLOAD.md for detailed information.
Roadmap Ideas
- Project dashboard (notes, tags, quick links)
- More robust asset/shot detection from workflow metadata
- Preset templates per media type (images/videos/comps)
- Tight integration with an Asset/File Manager for a real pipeline feel
API Error Responses
All API endpoints return errors in the following standardized format:
{
"ok": false,
"error": "Error message describing what went wrong"
}
Common HTTP Status Codes
400 Bad Request: Invalid input, validation error, or malformed request404 Not Found: Project ID, workflow, or resource not found409 Conflict: Resource already exists (when overwrite=false)415 Unsupported Media Type: Missing or invalid Content-Type header (must be application/json)500 Internal Server Error: Server-side error (file I/O, database issues)
Example Error Responses
// Missing required field
{
"ok": false,
"error": "project_name is required"
}
// Invalid characters in input
{
"ok": false,
"error": "project_name contains invalid characters (/ \\ : .. not allowed)"
}
// Resource not found
{
"ok": false,
"error": "project_id not found"
}
// Validation failure
{
"ok": false,
"error": "invalid date format: '999999' (expected YYMMDD, e.g., 251220 for today)"
}
License
No license file is currently included in this repository/folder. Until a license is added by the author, treat the code as unlicensed (i.e., no permission is granted for redistribution or modification beyond what applicable law allows).
If you are the author/maintainer: add a LICENSE file and update this section accordingly.
Credits
Built for the ComfyUI ecosystem with one goal: less chaos, more structure, and outputs that look like you meant it. 😄