Initial commit: Image Watch MCP

🖼️ MCP for monitoring and managing images
- get_latest_image: Get most recent image as inline display
- get_recent_images: Get multiple recent images
- list_pending_images: List without loading
- open_image_from_path: View any image file
- archive_processed_images: Clean up processed images

Built with love for the hardware dragon 🦊
This commit is contained in:
Alex Kazaiev
2025-12-16 20:56:09 -06:00
commit 9198846405
5 changed files with 936 additions and 0 deletions

325
README.md Executable file
View File

@@ -0,0 +1,325 @@
# 📸 Image Watch MCP Server
Local image watcher for Claude Desktop - AirDrop photos from your iPhone and discuss them with Claude instantly!
## Features
- 🔍 **Automatic Detection** - Watches `~/Downloads` for new images in real-time
- 📱 **iPhone Support** - Automatic HEIC → JPEG conversion for iPhone photos
- 🗜️ **Smart Compression** - Adapts quality to fit Claude's 1MB limit while maintaining visual quality
- 📦 **Archive Management** - Move processed images to `~/Downloads/Processed/` to keep Downloads clean
-**Multiple Workflows** - Get latest image, batch of images, or list without loading
## Supported Formats
- JPEG / JPG
- PNG
- HEIC (iPhone photos)
- GIF, BMP, WebP
## Installation
### 1. Install Dependencies
```bash
cd /home/alex/Projects/image-watch-mcp
pip install -r requirements.txt
```
Or using a virtual environment (recommended):
```bash
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txt
```
### 2. Configure Claude Desktop
Add to your Claude Desktop config file:
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
**Linux**: `~/.config/Claude/claude_desktop_config.json`
```json
{
"mcpServers": {
"image-watch": {
"command": "python3",
"args": ["/home/alex/Projects/image-watch-mcp/image_watch_mcp.py"]
}
}
}
```
**Note:** If using a virtual environment, use the full path to the Python interpreter:
```json
{
"mcpServers": {
"image-watch": {
"command": "/home/alex/Projects/image-watch-mcp/venv/bin/python",
"args": ["/home/alex/Projects/image-watch-mcp/image_watch_mcp.py"]
}
}
}
```
### 3. Restart Claude Desktop
Close and reopen Claude Desktop to load the MCP server.
## Usage
### Basic Workflow
1. **AirDrop photos from iPhone** → Mac (they land in `~/Downloads`)
2. **In Claude Desktop:** "Show me the photos I just sent"
3. Claude calls the MCP tools and displays images inline
4. **Discuss the images** with Claude
5. **When done:** "Archive those images" → Moved to `~/Downloads/Processed/`
### Available Tools
#### `get_latest_image()`
Get the most recent image added to Downloads.
**Example:**
> Claude, show me the latest photo
Returns the newest unprocessed image, compressed to fit under 1MB.
---
#### `get_recent_images(count, since_minutes)`
Get multiple images at once.
**Parameters:**
- `count` (default: 5) - Maximum number of images to return
- `since_minutes` (default: 60) - Consider images from the last N minutes
**Examples:**
> Show me the last 3 photos I took
>
> Show me all photos from the last 10 minutes
Returns images in chronological order (oldest first).
---
#### `list_pending_images()`
List available images without loading them.
**Example:**
> What images are pending?
Shows image names, sizes, formats, and timestamps. Useful for previewing what's available before loading large batches.
---
#### `archive_processed_images()`
Move viewed images to the archive folder.
**Example:**
> Archive those images
Moves all processed images to `~/Downloads/Processed/` to keep Downloads clean. If a file with the same name exists, adds a timestamp suffix.
## How It Works
### Background Watcher
The MCP server starts a watchdog observer that monitors `~/Downloads` for new image files. When an image is detected, it:
1. Creates metadata (timestamp, size, format)
2. Adds it to the pending queue
3. Waits for you to request it
### Smart Compression
Images larger than 1MB are automatically compressed using a multi-step strategy:
1. **Convert format** - HEIC → JPEG, RGBA → RGB
2. **Quality reduction** - Try 85% → 75% → 65% → 55%
3. **Resize if needed** - Scale down 90% → 80% → 70%... until it fits
4. **Return best effort** - Even if it exceeds 1MB slightly
This ensures maximum visual quality while meeting Claude's constraints.
### State Tracking
Each image has three states:
- **Pending** - Detected but not viewed
- **Processed** - Viewed by Claude
- **Archived** - Moved to archive folder
You can call `archive_processed_images()` anytime to clean up viewed photos.
## Configuration
### Watch Directory
By default, watches `~/Downloads`. To change:
```python
# In image_watch_mcp.py
WATCH_DIR = Path.home() / "Pictures" / "Incoming"
```
### Archive Directory
By default, archives to `~/Downloads/Processed/`. To change:
```python
# In image_watch_mcp.py
ARCHIVE_DIR = Path.home() / "Pictures" / "Archive"
```
### Recent Time Window
By default, considers images from the last 60 minutes as "recent":
```python
# In image_watch_mcp.py
DEFAULT_RECENT_MINUTES = 60 # Change to your preference
```
## Troubleshooting
### Images not detected
- Check that files are in `~/Downloads` (not in subdirectories)
- Verify file extensions are supported (`.jpg`, `.png`, `.heic`, etc.)
- Check MCP server logs: `/tmp/image_watch_mcp.log`
### HEIC not working
Install HEIC support:
```bash
pip install pillow-heif
```
### Images too large
The MCP tries to compress images to fit under 1MB. If an image still won't load:
- Original file might be corrupted
- Extremely large dimensions (>10000px)
- Check logs for compression errors
### "No new images available"
This happens when:
- No images in Downloads from the last 60 minutes
- All images already processed
Try `list_pending_images()` to see what's available.
## Logs
Server logs are written to `/tmp/image_watch_mcp.log`:
```bash
tail -f /tmp/image_watch_mcp.log
```
Shows:
- Images detected
- Compression results
- Tools called
- Errors and warnings
## Development
### Project Structure
```
image-watch-mcp/
├── image_watch_mcp.py # Main MCP server
├── requirements.txt # Python dependencies
├── README.md # This file
└── .gitignore # Git ignores
```
### Testing Locally
Run the server directly to see debug output:
```bash
python3 image_watch_mcp.py
```
The server will start and wait for MCP requests on stdin/stdout.
### Adding Features
The code is organized for easy extension:
- **New image formats**: Add to `IMAGE_EXTENSIONS`
- **Custom tools**: Add `@mcp.tool()` decorated functions
- **Different compression**: Modify `smart_compress()`
- **Additional metadata**: Extend `PendingImage` dataclass
## Example Conversations
### Workflow 1: Single Photo
**You:** AirDrop photo from iPhone
**You:** "Claude, show me the latest photo"
**Claude:** [calls `get_latest_image()`, displays photo inline]
**You:** "What's in this photo?"
**Claude:** [analyzes the image and describes content]
**You:** "Archive it"
**Claude:** [calls `archive_processed_images()`] "Archived 1 image to ~/Downloads/Processed"
---
### Workflow 2: Batch Photos
**You:** AirDrop 5 photos from iPhone
**You:** "Show me all the photos I just sent"
**Claude:** [calls `get_recent_images(count=10)`] [displays all 5 photos]
**You:** "Which one has the best composition?"
**Claude:** [analyzes all photos and provides feedback]
---
### Workflow 3: Selective Loading
**You:** AirDrop many photos
**You:** "What images are pending?"
**Claude:** [calls `list_pending_images()`]
```
Pending images (12):
1. IMG_1234.heic (3.2MB, HEIC, 2m ago)
2. IMG_1235.heic (2.8MB, HEIC, 2m ago)
...
```
**You:** "Just show me the first 3"
**Claude:** [calls `get_recent_images(count=3)`] [displays 3 photos]
## License
Part of the personal MCP toolkit for Claude Desktop.
---
**Built with FastMCP + Watchdog + Pillow for seamless image workflows** 📸