Back to Browse

Photo S MCP Server

Developer ToolsUse Caution4.2MCP RegistryLocal
Free

Server data from the Official MCP Registry

Batch photo processing: compress, convert, EXIF, rename, dedup, cull, galleries

About

Batch photo processing: compress, convert, EXIF, rename, dedup, cull, galleries

Security Report

4.2
Use Caution4.2High Risk

PhotoS is a well-structured image processing tool with appropriate permissions for its purpose and solid code quality. The MCP server implementation is clean with no authentication requirements (expected for local stdio-based MCP), and credentials are handled via environment variables. Minor code quality observations around broad exception handling and logging do not significantly impact security. Supply chain analysis found 7 known vulnerabilities in dependencies (0 critical, 3 high severity). Package verification found 1 issue.

4 files analyzed Β· 13 issues found

Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.

Permissions Required

This plugin requests these system permissions. Most are normal for its category.

File System Read

Reads files on your machine. Normal for tools that analyze or process local data.

File System Write

Writes or modifies files on your machine. Check that this is expected for the tool.

HTTP Network Access

Connects to external APIs or services over the internet.

env_vars

Check that this permission is expected for this type of plugin.

process_spawn

Check that this permission is expected for this type of plugin.

system_info

Check that this permission is expected for this type of plugin.

How to Install

Add this to your MCP configuration file:

{
  "mcpServers": {
    "io-github-dongwu259-photo-s": {
      "args": [
        "photo-s-tools"
      ],
      "command": "uvx"
    }
  }
}

Documentation

View on GitHub

From the project's GitHub README.

πŸ“· PhotoS β€” Batch Image Compression & Format Conversion

Python Platform License Tests PyPI

PhotoS is a cross-platform batch image processing tool with both GUI and CLI. Built for photographers who need to deliver images at specific sizes, and for AI agents that need reliable image processing pipelines.

πŸ–₯ GUI for humans β€” ⌨️ CLI for AI agents β€” pip install photo-s-tools

✍️ Core developers: deepseek-v4-flash · GLM-5.2 · Kimi K3

English Β· δΈ­ζ–‡


✨ Features

FeatureGUICLIDescription
Batch compressβœ…βœ…JPEG/WebP/HEIC/AVIF quality tuning
Target size modeβœ…βœ…Auto-tune quality to fit under a target file size
Format convertβœ…βœ…JPEG / PNG / WebP / TIFF / BMP / HEIC / AVIF
RAW decodeβœ…βœ…22+ camera RAW formats, built-in (rawpy/libraw)
Resize / Scaleβœ…βœ…Max dimensions, percentage, or longest-side cap
Visual previewβœ…β€”Live original↔processed preview rendered through the real pipeline
Tone & colorβœ…βœ…Brightness/contrast/saturation/gamma/sharpen, B&W, sepia
White balanceβœ…βœ…--wb 5600 Kelvin, or --wb-from ref.jpg sample a gray card
Exposureβœ…βœ…--ev +1 stops, or --auto-exposure 0.45 normalize to target
Auto levelsβœ…βœ…--auto-levels 2% clip histogram stretch
LOG recoveryβœ…βœ…--log-curve SLOG3/CLOG3/LOGC3/DLOG/VLOG/HLG (1D LUT, no deps)
LUT gradingβœ…βœ…--lut film.cube or preset names (built-in trilinear; photo-s-plugin-lut adds tetrahedral + 5 film presets)
Denoiseβœ…βœ…ΒΉ--denoise 10 NLM ([enhance] extra)
Auto-straightenβœ…βœ…ΒΉ--auto-straighten level the horizon, confidence-gated ([enhance] extra)
Crop / Rotate / Flip / Padβœ…βœ…--crop 800x600+0+0, --rotate 90, --flip h, --pad 16:9
Print sizeβœ…βœ…--print-size 8x10@300dpi center-crop + exact print pixels
Smart renameβœ…βœ…{date}_{camera}_{seq} templates
Auto folder organizeβœ…βœ…--organize date-camera subfolder creation
Watermarkβœ…βœ…Text + image overlay, 7 positions
Multi-size outputβœ…βœ…--sizes thumb:480x,screen:1920x
Metadata taggingβœ…βœ…exif --rating / --keywords / --caption batch tag (UserComment)
Metadata filterβœ…βœ…exif --show --rating-min 3 --keywords beach find tagged photos
Metadata importβ€”βœ…exif --from-csv meta.csv batch write from spreadsheet
Cullingβœ…βœ…photo-s cull exposure/sharpness filter (GUI keeps only matches, undoable)
Burst keep-sharpestβœ…βœ…dedup --action keep-sharpest pick the sharpest of a burst
Checksum manifestβœ…βœ…photo-s hash SHA-256 archive integrity + --verify
HTML galleryβœ…βœ…photo-s gallery self-contained index.html + thumbs
Presetsβœ…βœ…Save/load named configs
Multi-profile batchβ€”βœ…--profiles web,thumb one input set, N outputs
Parallel processingβœ…βœ…-j 8 multi-threaded
JSON outputβ€”βœ…--json for AI agent consumption
Config fileβ€”βœ…photo-s.toml defaults (config init/show)
EXIF editβ€”βœ…photo-s exif *.jpg --artist "Me"
EXIF date shiftβ€”βœ…--date-shift "-5h30m" timezone/camera clock fixes
Privacy scrubβ€”βœ…--scrub strips EXIF+ICC+GPS
Sync dateβ€”βœ…--sync-date output mtime ← EXIF datetime
Folder watchβœ…βœ…photo-s watch ~/incoming/ auto-process ([watch] extra)
Auto-rotateβœ…βœ…EXIF Orientation-based
Image dedupβœ…βœ…Perceptual hash duplicate detection
Quality metricsβœ…βœ…--evaluate SSIM + --blur-score
CSV reportβ€”βœ…--report out.csv per-file stats
Integrity checkβ€”βœ…photo-s check corrupt file scan
Contact sheetβœ…βœ…photo-s contact-sheet *.jpg -o sheet.png
Color managementβ€”βœ…--srgb / --flatten-cmyk
REST APIβ€”βœ…photo-s serve for AI agents
Plugin systemβ€”βœ…Third-party plugin support
Official plugin managerβ€”βœ…photo-s plugin list/install/info/fetch + pip install photo-s-plugin-scunet
MCP serverβ€”βœ…photo-s mcp expose 11 tools to MCP clients (Claude Desktop)
Batch benchmarkβ€”βœ…photo-s bench --dir ~/shoot -j 1,2,4,8 measure worker scaling

ΒΉ Denoise / auto-straighten need an optional dependency: pip install photo-s-tools[enhance] (opencv-python-headless). When missing, these features give a clear install hint and the rest keeps working.


πŸ“¦ Installation

pip install (recommended)

pip install photo-s-tools

# With optional features
pip install photo-s-tools[all]       # everything
pip install photo-s-tools[heic]      # HEIC support
pip install photo-s-tools[avif]      # AVIF support
pip install photo-s-tools[watch]     # folder watching
pip install photo-s-tools[exif]      # EXIF editing
pip install photo-s-tools[enhance]   # NLM denoise + auto-straighten (opencv)
pip install photo-s-tools[mcp]       # MCP server (Python 3.10+)

From source

git clone https://github.com/Dongwu259/photo_s.git
cd photo_s
pip install -e .

⌨️ CLI Usage

photo-s --help                  # Show all commands
photo-s compress *.jpg -q 80    # Batch compress
photo-s convert *.png -f webp   # Convert format
photo-s batch ~/photos/ -r      # Recursive batch
photo-s exif *.jpg --artist "Me" # Edit EXIF
photo-s preset save web -q 70   # Save preset
photo-s preset list             # List presets
photo-s watch ~/incoming/       # Auto-process new files
photo-s dedup ~/photos/         # Find duplicates
photo-s info                    # Supported formats
photo-s --version               # Show version

Photographer workflows

# Cull: find over/under-exposed shots
photo-s cull ~/shoot/ -r --overexposed-max 2% --underexposed-max 2% --list

# Tag + filter by tags (core workflow)
photo-s exif ~/shoot/ -r --rating 4 --keywords "keep,beach"   # batch tag
photo-s exif ~/shoot/ -r --show --rating-min 4 --list         # pick >=4-star paths
photo-s exif ~/shoot/ -r --show --keywords beach --json        # filter by keyword
photo-s exif --from-csv meta.csv                               # batch write from CSV
photo-s batch $(photo-s exif ~/shoot/ -r --show --rating-min 4 --list) -o /deliver/

# Archive: generate + verify a SHA-256 manifest
photo-s hash ~/archive/ -r -o manifest.csv
photo-s hash --verify manifest.csv

# Burst selection: keep the sharpest of each group
photo-s dedup ~/burst/ --action keep-sharpest --dry-run

# Delivery: HTML gallery / print size / white balance
photo-s gallery ~/shoot/ -o gallery/ --title "2026 Sichuan"
photo-s batch ~/shoot/ --print-size 8x10@300dpi
photo-s batch ~/shoot/ --wb 5600 --auto-levels

# Global correction: exposure / LOG recovery / denoise / straighten
photo-s batch ~/shoot/ --ev +0.5 --auto-exposure 0.45
photo-s batch ~/log/    --log-curve SLOG3 --wb 5600        # LOG footage recovery
photo-s batch ~/highiso/ --denoise 12 --ev -0.3            # high-ISO denoise
photo-s batch ~/tilted/ --auto-straighten --max-straighten-angle 8

Common examples

# Compress to ~5MB with auto-tune, 8 threads, JSON output (AI agent)
photo-s compress *.jpg --target-size 5MB -j 8 --json

# Convert to AVIF with parallel workers
photo-s convert *.jpg -f AVIF -q 60 -j 4

# Organize by date+camera, add a watermark
photo-s batch ~/photos/ --organize date-camera --watermark-text "Β© Me" -j 4

# Smart rename with EXIF metadata
photo-s compress *.jpg --rename "{date}_{camera}_{seq}"

# Find duplicate images
photo-s dedup ~/photos/ --action report

JSON output (for AI agents)

--json prints pure JSON to stdout (progress/diagnostics go to stderr). All agent-facing subcommands support it: compress/batch/convert (batch results), check/dedup (reports), rename, contact-sheet, info, and --dry-run (config preview).

{
  "summary": {"total": 5, "success": 5, "failed": 0, "saved_bytes": 27262976, "saved_percent": 52.0},
  "results": [{"input": "photo.jpg", "output": "photo_compressed.jpg", "input_size": 10485760, "output_size": 5242880, "format": "JPEG", "dimensions": [6000, 4000], "quality": 78, "status": "ok"}]
}

Use with any AI agent: photo-s compress *.jpg --json --target-size 5MB | your-agent

Exit-code convention: failures in batch/rename/check β†’ 1; dedup returns 1 when duplicates are found (0 otherwise), so agents can branch on it. Under --json, --remove-original / dedup --action move|delete skip interactive confirmation (an explicit agent request is taken as consent).


πŸ–₯ GUI Usage

photo-s          # Launch GUI (no args = GUI)
photo-s gui      # Explicit GUI mode

GUI features: Chinese/English language switch, drag-and-drop (needs pip install photo-s-tools[gui]), cancellable batch processing, before/after comparison, global shortcuts (⌘/Ctrl+O add, ⌘/Ctrl+R start, Esc cancel, ⌘/Ctrl+E review, ⌘/Ctrl+D dedup, ⌘/Ctrl+G gallery, ⌘/Ctrl+Z undo), a checkbox file list (every row has a real checkbox; all actions β€” process, review, dedup, gallery β€” run on the checked files; adding a folder scans subfolders), a review & rate lightbox (←/β†’ navigation, 0-5 stars, keywords/title, rating & keyword filters β€” writes EXIF), a duplicate viewer (side-by-side groups with sharpness scores, keep-checkboxes, move-to-trash instead of delete), and HTML gallery export. Tagged photos can then be filtered in the CLI (photo-s exif --rating-min 4 --list) or used by AI agents.

GUI changes & interface contract: docs/GUI_CHANGES.md

Screenshots

  • Main window with file list + settings panel
  • Processing progress bar and summary dialog
  • Before/after comparison view

🎯 Target Size Mode

Unique feature: set a target file size and PhotoS auto-tunes JPEG/WebP/AVIF quality via binary search.

photo-s compress *.jpg --target-size 5MB
# Auto-tunes quality ∈ [5, 85] to make each output ≀ 5MB

πŸ”Œ Plugin System

Third-party plugins extend PhotoS via Python entry_points.

pip install photo-s-plugin-s3    # Example: auto-upload to S3
photo-s compress *.jpg           # plugins auto-apply

Official plugins

Official plugins are separate PyPI distributions photo-s-plugin-<name>. Install via either the plugin manager or pip. The first official plugin is SCUNet strong denoise β€” stronger high-ISO denoising than the built-in NLM. Once installed, --denoise N prefers it automatically (and falls back to NLM otherwise):

# Channel 1: plugin manager (agent-friendly, --json)
photo-s plugin list
photo-s plugin install scunet --json
photo-s plugin fetch scunet          # pre-download the ONNX weights (~10-40MB, sha256-verified)
photo-s plugin info scunet

# Channel 2: plain pip
pip install photo-s-plugin-scunet

# Usage (auto uses SCUNet when installed, else NLM)
photo-s batch ~/highiso/ --denoise 12

Model weights are not shipped in the wheel: downloaded on first use to ~/.cache/photo-s/models/ (override with $PHOTOS_CACHE_DIR), sha256-verified. All official plugins follow the "separate distribution + external weights" model.

Writing a plugin

# setup.py / pyproject.toml
[project.entry-points."photo_s.plugins"]
my-plugin = "my_package:MyPlugin"

# my_package.py
from photo_s.hooks import PhotoSPlugin

class MyPlugin(PhotoSPlugin):
    name = "my-plugin"

    def on_post_process(self, result, ctx):
        print(f"Processed: {result.output_path}")

See docs/PLUGINS.md for the full API, including operation providers (e.g. a denoise slot provider) and model-weight handling.


πŸ“‹ Supported Formats

FormatReadWriteNotes
JPEGβœ…βœ…quality, progressive, EXIF
PNGβœ…βœ…optimize
WebPβœ…βœ…quality
AVIFβœ…βœ…quality (requires pillow-avif-plugin)
HEICβœ…βœ…requires pillow-heif
TIFFβœ…βœ…LZW compression
BMPβœ…βœ…
ICOβœ…βœ…
RAW (22+ formats)βœ…β€”built-in via rawpy (libraw)

✏️ Naming Convention

ContextFormNotes
Python package / importphoto_ssyntax-enforced: import photo-s is invalid
CLI commandphoto-sshell convention: photo-s compress *.jpg
PyPI distributionphoto-s-toolspip install photo-s-tools (the obvious photo-s is blocked by PyPI β€” too similar to the existing photos package)
UI title / brand / doc headingsPhotoShuman-readable brand name

Don't mix forms within the same context (e.g. photo_s compress in code examples, or photo-s in UI copy, are both wrong). This is the standard Python-ecosystem pattern (scikit-learn→sklearn, Pillow→PIL); please don't "unify" them.


πŸ€– Agent / Application Integration

The complete integration contract (CLI JSON shapes, exit codes, serve endpoints, async tasks, config precedence) lives in docs/AGENT_API.md β€” agents only need that one doc.

PhotoS offers three integration paths, by recommendation:

1. Python library (recommended when the host is Python)

from photo_s.engine import ProcessOptions, batch_process

options = ProcessOptions(
    output_dir="compressed/",
    quality=70,
    max_pixels=8000,
    strip_gps=True,          # privacy
    evaluate=True,           # SSIM
)
result = batch_process(["/path/a.jpg", "/path/b.jpg"], options, jobs=4)
for r in result.results:
    print(r.output_path, r.ssim)

No IPC overhead; just vendor the photo_s package into your app.

2. REST API (photo-s serve β€” non-Python host / cross-process)

photo-s serve --port 0 --token auto --ready-file ./photo-s.ready.json
  • --port 0 = random free port; --token auto = random token; --ready-file atomically writes {"port", "token", "pid"} after listening starts β€” the host agent polls that file (more reliable than parsing stdout, also on Windows), then: GET /health readiness probe β†’ POST /process {"paths": [...], "options": {...}} β†’ get BatchResult JSON (with ssim / blur_score).

Long batches / progress / cancel (POST /process with "async": true):

# 1. Submit an async task
curl -X POST .../process -H "Authorization: Bearer $TOKEN" \
     -d '{"paths": ["/photos/*.jpg"], "async": true}'
# β†’ 202 {"task_id": "...", "poll": "/tasks/<id>", ...}

# 2. Poll progress
curl .../tasks/<id>
# β†’ {"status": "running|done|cancelled|error", "current": N, "total": M,
#     "current_path": "...", "result": {BatchResult JSON when done}}

# 3. Cancel (queued files stop after the in-flight one finishes)
curl -X POST .../tasks/<id>/cancel

POST /process also supports "dry_run": true (returns the paths/options that would be processed, no work done) and options.output_sizes (multi-size, [["thumb",480,None], ...]) and options.pad (= pad_ratio).

  • On Windows without a Python env: use PyInstaller to bundle photo-s.exe (see below), spawn it by absolute path β€” no PATH dependency.
  • The host manages the process lifecycle (terminate the child on exit).

3. CLI subprocess (one-off scripts / CI)

photo-s compress a.jpg -q 80 --json β†’ stdout JSON. Each call has a Python interpreter startup cost (~200-300ms); not recommended for high-frequency batch.

4. MCP server (Claude Desktop & MCP clients)

Model Context Protocol server β€” lets Claude Desktop / any MCP client call PhotoS tools directly (needs Python 3.10+ and the optional extra):

pip install "photo-s-tools[mcp]"
photo-s mcp --list-tools        # inspect the 11 tools + schemas (JSON)
photo-s mcp                     # start the stdio MCP server

Tools: process (batch quality/format/resize/tone/denoise), info (environment probe), exif (read/filter/write metadata), dedup (perceptual-hash groups, keep-sharpest), cull (exposure/sharpness filter), hash (SHA-256 manifests), contact_sheet (grid montage), gallery (HTML gallery), watermark (text/image overlay), preset (list/save/load/delete), plugin (official plugin management). Output shapes mirror the CLI --json contracts.

Claude Desktop config (claude_desktop_config.json):

{
  "mcpServers": {
    "photo-s": {
      "command": "photo-s",
      "args": ["mcp"]
    }
  }
}

Zero-install variant (uvx resolves PyPI deps on first run β€” the same invocation published on the official MCP Registry as io.github.Dongwu259/photo-s):

{
  "mcpServers": {
    "photo-s": {
      "command": "uvx",
      "args": ["--from", "photo-s-tools[mcp]", "photo-s", "mcp"]
    }
  }
}

Destructive safety: dedup keep-sharpest defaults to dry_run=True (deletion requires an explicit dry_run=False). process never overwrites inputs.

Windows packaging (no Python/PATH env)

pip install pyinstaller piexif pillow-heif   # optional features too
python packaging/build.py                    # full: dist/photo-s/photo-s.exe (GUI+CLI+MCP)
python packaging/build.py --lite             # lite: dist/photo-s-lite/photo-s-lite.exe (CLI+MCP, no GUI)

Two editions: the full bundle ships the GUI; the lite bundle excludes photo_s.gui + tkinter at build level (smaller, display-free) β€” ideal for agent-spawned serve/mcp processes. In the lite build photo-s-lite with no args prints help, gui exits 1 with a hint, and --version shows (lite).

The host launches by absolute path, no environment variables needed (see the spawn mode above). CI builds both windows-latest artifacts (.github/workflows/ci.yml).


πŸ§ͺ Development

pip install -e ".[dev]"
python -m pytest tests/ -v

πŸ“„ License

MIT

Reviews

No reviews yet

Be the first to review this server!