Visual Intelligence Command Center: A Local Computer Vision Engine for Photo Libraries
Project description
photographi-mcp
Give your AI the ability to see, analyze, and manage your local photo library.
photographi-mcp is an MCP server that allows LLMs (like Claude) to work with your photos locally. It analyzes things like focus, lighting, and quality automatically—all while keeping your data 100% private.
Whether you need to find the best shot in a burst, cull a massive shoot, or search your library semantically, photographi-mcp gives your AI agent the "visual brain" it needs to get the job done.
👁️ What It Sees
The engine analyzes every pixel to understand exactly what happened when you pressed the shutter:
- Smart Focus: It finds the main subject of your photo and makes sure it's actually sharp.
- Lighting Check: It looks for photos that are too bright or too dark, and finds "hidden" details in the shadows.
- Gear Awareness: It understands your specific camera and lens to know what a "perfect" shot should look like for your equipment.
- Composition: It evaluates how the photo is organized and if there is enough space around the subject.
- Quality Alerts: It catches common issues, like when your settings are accidentally making your images look soft or fuzzy.
For the math and signal processing details, see the Technical Science Documentation.
⚡ Quick Start: Zero-Install
The fastest way to use photographi is via Claude CLI (Claude Code) or uvx.
[!NOTE] These methods require uv to be installed on your system.
1. Claude CLI (Claude Code)
Run this single command to automatically configure the server:
claude mcp add --scope user photographi uvx photographi-mcp
2. GitHub Copilot CLI
Add the following to your ~/.config/github-copilot/config.json:
{
"mcp_servers": {
"photographi": {
"command": "uvx",
"args": ["photographi-mcp"]
}
}
}
3. Claude Desktop (macOS)
Add this to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"photographi": {
"command": "uvx",
"args": ["photographi-mcp"]
}
}
}
🛠️ Advanced: Local Development
If you want to contribute or edit the source code:
-
Setup:
git clone https://github.com/prasadabhishek/photographi.git cd photographi pip install -e .
-
Configuration: Point your
commandto the localphotographiexecutable or use the absolute path to your venv's python.
📖 Full Documentation: See docs/setup.md
Quick Test:
uvx photographi-mcp --help
🗺️ Roadmap & Community
We are building the future of privacy-first visual AI. See CONTRIBUTING.md to get involved.
License: MIT
🔒 Privacy Config (Optional)
Telemetry is enabled by default to help us improve the tool. To disable all usage tracking, add the --disable-telemetry flag:
{
"mcpServers": { // or "mcp_servers" for Copilot CLI
"photographi": {
"command": "photographi",
"args": ["--disable-telemetry"]
}
}
}
🛠️ Tools (MCP)
photographi-mcp gives your AI agent (like Claude) a set of powerful tools to interact with your photos. Here is how to use them:
1. photographi_analyze_photo
What it does: Performs a deep technical audit of a single image.
- LLM Use Case: "Audit this RAW file and tell me if the focus is sharp enough for a large print."
- Supports: JPEG, PNG, RAW (.ARW, .CR2, .NEF, .DNG, .CR3, etc.), and TIFF.
2. photographi_analyze_folder
What it does: Scans an entire folder and provides a statistical quality report (with pagination).
- Features: High concurrency (4-8x), Pagination (
limit,offset), and Fast Mode (enabled by default). - LLM Use Case: "I just finished a shoot; scan the 'Portraits' folder and tell me the overall success rate of the focus."
3. photographi_rank_photographs
What it does: Identifies the "winners" in a group of photos based on technical perfection.
- Features: Uses Fast Mode to quickly rank bursts of 40MP+ images.
- LLM Use Case: "I took 10 shots of this bird taking flight. Find the single frame that is the sharpest and best exposed."
4. photographi_cull_photographs
What it does: Intelligently filters out low-quality "junk" (blurry, dark, or duplicates) into a separate culled_photos folder.
- Features: Supports moving files or just tagging them via XMP.
- LLM Use Case: "Clean up my 'Downloads' folder by moving all the low-quality or blurry screenshots to a culled folder."
5. photographi_threshold_cull
What it does: A strict "Keep or Toss" tool that sorts photos based on a specific quality score into selects/ or rejects/.
- Features: Highly concurrent. Perfect for strict ingestion workflows.
- LLM Use Case: "Be strict: sort this folder. Anything with a quality score below 0.7 goes into 'rejects', the rest go into 'selects'."
6. photographi_get_color_palette
What it does: Extracts the dominant colors from a photo (as Hex codes).
- LLM Use Case: "Look at my best landscape shots and extract a color palette I can use to design my photography portfolio website."
7. photographi_get_folder_palettes
What it does: Extracts dominant colors for every image in a folder (with pagination).
- LLM Use Case: "Analyze all photos in this folder and give me their color palettes so I can group them by mood."
8. photographi_get_scene_content
What it does: Identifies key objects (people, animals, vehicles, etc.) for quick indexing.
- LLM Use Case: "Which photos in this folder contain a 'dog'?"
🔒 Privacy & Telemetry
photographi is built on a Privacy-First philosophy. We collect high-level, anonymized usage metrics to help improve the tool, but we guarantee your personal data never leaves your machine.
Our Privacy Promise
- Anonymized Aggregates Only: We NEVER collect file names, paths, EXIF metadata, or any identifiers. We only track total counts (e.g., "15 images processed") and quality distributions (e.g., "3 Excellent results").
- Zero Identification: We do not use fingerprints, machine IDs, or cookies. Even we cannot tell which user is sending which metrics.
- Transparency: You can audit exact collection logic in
analytics.py. - Full Control: Telemetry is enabled by default to help us improve, but you can opt-out completely with a single flag.
How to Opt-Out
To disable all telemetry (both local logging and remote transmission), you can either set the environment variable PHOTOGRAPHI_TELEMETRY_DISABLED=1, or add the --disable-telemetry flag to your mcp_config.json:
{
"mcpServers": {
"photographi": {
"command": "python",
"args": [
"/absolute/path/to/photographi/server.py",
"--disable-telemetry"
]
}
}
}
Note: Open Source Security: For the official release, we use a Telemetry Relay (proxy) to securely manage Axiom tokens. If you are forking this project, see
docs/telemetry-relay.jsfor instructions on how to set up your own secure metrics relay.
📚 Documentation
- Full Tool Reference (API): Detailed breakdown of every tool, parameter, and return type.
- System Architecture: Deep dive into the Physics/Neural engines and the Privacy-First Telemetry design.
- Telemetry Relay Setup: Instructions for self-hosting the privacy proxy on Cloudflare.
📊 Performance Benchmark
| Capability | Speed (M1/M2/M3) | Description |
|---|---|---|
| Model Load | ~0.38s | One-time initialization of YOLO26n ONNX model |
| Technical Scan | ~0.19s / img | Fast Mode (Downsampled 40MP -> 1024px) + Concurrency |
| Forensic Scan | ~1.50s / img | Full-Resolution Analysis (Opt-in via fast_mode=False) |
| Throughput | ~18,000 img/hr | Effective batch rate for mixed workloads |
| Scalability | Unlimited | Verified pagination support for 10,000+ folders |
Tested on local Apple Silicon hardware with 1024x1024 synthetic assets. High-resolution RAW files may vary based on disk I/O.
🔒 Privacy & Telemetry
This tool collects anonymous usage data by default to help improve performance.
- Relay: Telemetry is sent to
https://photographi-telemetry.abhishek-a-prasad.workers.dev/. - Disable: Set
PHOTOGRAPHI_TELEMETRY_DISABLED=1to opt-out. - Data: We collect execution time, error rates, and camera model stats. NO image data is ever uploaded.
🤝 Contributing
Contributions are welcome! Please read CONTRIBUTING.md for details.
🏗️ Technology
photographi-mcp is built on top of the photo-quality-analyzer-core engine. This core library provides the signal processing, physics-based metrics, and neural network logic that powers the analysis.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file photographi_mcp-0.2.2.tar.gz.
File metadata
- Download URL: photographi_mcp-0.2.2.tar.gz
- Upload date:
- Size: 20.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a1a0896dd5938bfb850c13aa8eb9aea3b418691227b2a013104cf848f3126a54
|
|
| MD5 |
147476fc2368c2c68e9817b81f00420c
|
|
| BLAKE2b-256 |
ff9563f13de0c13fbff708d8aaddb34b155de6221aa73b3f976f3587b0da883f
|
Provenance
The following attestation bundles were made for photographi_mcp-0.2.2.tar.gz:
Publisher:
publish.yml on prasadabhishek/photographi-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
photographi_mcp-0.2.2.tar.gz -
Subject digest:
a1a0896dd5938bfb850c13aa8eb9aea3b418691227b2a013104cf848f3126a54 - Sigstore transparency entry: 953613268
- Sigstore integration time:
-
Permalink:
prasadabhishek/photographi-mcp@7f676429735fd471dddd4773f2bd5a1bed3d2402 -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/prasadabhishek
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7f676429735fd471dddd4773f2bd5a1bed3d2402 -
Trigger Event:
push
-
Statement type:
File details
Details for the file photographi_mcp-0.2.2-py3-none-any.whl.
File metadata
- Download URL: photographi_mcp-0.2.2-py3-none-any.whl
- Upload date:
- Size: 15.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d928eeb01d4df0c97464ef381204d191bccb5912222d9c908889c5cfb6930014
|
|
| MD5 |
8f1933ab97e2eee9d1027070bf38f1c7
|
|
| BLAKE2b-256 |
813870e0b7bed462880a4cb139cdbe9dc759b711eb44a498654c54e6f695ac66
|
Provenance
The following attestation bundles were made for photographi_mcp-0.2.2-py3-none-any.whl:
Publisher:
publish.yml on prasadabhishek/photographi-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
photographi_mcp-0.2.2-py3-none-any.whl -
Subject digest:
d928eeb01d4df0c97464ef381204d191bccb5912222d9c908889c5cfb6930014 - Sigstore transparency entry: 953613269
- Sigstore integration time:
-
Permalink:
prasadabhishek/photographi-mcp@7f676429735fd471dddd4773f2bd5a1bed3d2402 -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/prasadabhishek
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7f676429735fd471dddd4773f2bd5a1bed3d2402 -
Trigger Event:
push
-
Statement type: