| title | emoji | colorFrom | colorTo | sdk | sdk_version | app_file | pinned | tags | license | short_description | ||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
iOS MCP Server |
📱 |
blue |
purple |
gradio |
6.0.1 |
app.py |
false |
|
mit |
MCP Server to connect to IOS Devices locally |
A Model Context Protocol (MCP) server that allows Large Language Models (LLMs) to access, scan, and search photos on a connected iOS device.
- Device Access: Connects to iPhone via USB using
libimobiledevice. - Smart File Copying: Organize and copy files to your computer with auto-renaming based on metadata.
- Semantic Search: Uses ChromaDB (Vector Database) to enable natural language search (e.g., "Find photos of my trip to Paris").
- Exact Filtering: Supports precise metadata filtering (e.g.,
{"Model": "iPhone 12"}). - Incremental Scanning: "Execute once, query many" architecture. Scans are cached, so subsequent queries are instant.
- Introspection: Tools to discover available metadata fields and fix typos.
Track: building-mcp-track-consumer
- macOS: This tool relies on macOS-specific tools for iOS connectivity.
- System Tools:
brew install libimobiledevice ifuse exiftool
- Python 3.10+
-
Clone the repository:
git clone https://github.com/harshaneigapula/ios_mcp cd ios_mcp -
Install Python dependencies:
pip install -r requirements.txt
Connect your iPhone via USB and ensure you have "Trusted" the computer on the device.
You can run the server directly:
mcp run src/server.pyAdd to your claude_desktop_config.json:
{
"mcpServers": {
"ios-mcp": {
"command": "python",
"args": ["/absolute/path/to/ios_mcp/src/server.py"]
}
}
}If using the Perplexity Desktop app or MCP integration:
- Go to Settings > MCP Servers.
- Add a new server:
- Name:
ios-mcp - Command:
python - Args:
/absolute/path/to/ios_mcp/src/server.py
- Name:
| Tool | Description |
|---|---|
list_connected_devices |
Lists UDIDs of connected iOS devices. |
scan_and_cache_photos |
Mounts the device, scans DCIM, and indexes metadata into the Vector DB. |
search_files |
Semantic search using natural language for photos based on Photo Metadata (e.g., "Photos of Apple 12 taken during 2024"). |
filter_files |
Exact metadata filtering (e.g., {"Flash": true}). |
count_files |
Count files matching semantic or exact criteria. |
group_files |
Group files by a field and return counts (e.g., group by "Model"). |
run_advanced_query |
Complex query with sorting, pagination, and projection. |
run_aggregation_pipeline |
Multi-stage data processing pipeline (MongoDB style). |
get_metadata_keys |
Lists all available metadata fields (columns). |
find_similar_metadata_keys |
Finds valid keys similar to a typo. |
read_image |
Reads and resizes an image, returning base64 data. |
copy_files_to_local |
Copies files to a local directory, with optional renaming. |
mount_device_for_file_access |
Manually mount the device. |
check_db_status |
Check database connection health. |
The server supports powerful data analysis capabilities modeled after MongoDB.
Process data through a multi-stage pipeline. Supported stages: $match, $group, $project, $sort, $limit, $count.
Example: Find camera models with average ISO > 200
[
{"$match": {"Make": "Apple"}},
{"$group": {
"_id": "$Model",
"avg_iso": {"$avg": "$ISO"},
"count": {"$sum": 1}
}},
{"$match": {"avg_iso": {"$gt": 200}}},
{"$sort": {"count": -1}}
]Perform complex queries with sorting and pagination.
Example: Get the 10 most recent photos
{
"where": {"MIMEType": "image/jpeg"},
"sort_by": "CreationDate",
"sort_order": "desc",
"limit": 10
}Quickly see the distribution of your files.
- Input:
field="Model" - Output:
{"iPhone 12": 150, "iPhone 13 Pro": 42}
The copy_files_to_local tool allows you to copy files from the iOS device to your local machine.
Key Feature: Renaming for Organization
You can provide a list of new_filenames matching the source files. This is powerful when combined with metadata. For example, you can rename files based on their creation date or location to organize them automatically.
Example: Copy and Rename
# Conceptual example of what the LLM does
source_files = ["/tmp/iphone/DCIM/IMG_001.JPG", "/tmp/iphone/DCIM/IMG_002.JPG"]
new_names = ["2024-01-01_Paris_001.jpg", "2024-01-01_Paris_002.jpg"]
copy_files_to_local(source_paths=source_files, destination_folder="/Users/me/Photos", new_filenames=new_names)read_image: Reads an image file (JPG, HEIC, etc.) from the device, resizes it (max 1024px), and returns a base64 encoded string. Useful for passing images to Vision-capable LLMs. (Most of the LLMs don't support image input as of now. More testing is needed here.)mount_device_for_file_access: Manually mounts the device if you need to perform operations outside the standard scan flow.
Run the local test script to verify device connectivity and database operations without the MCP layer:
python3 tests/test_local.pyOnce connected to an LLM:
- Scan: "Scan my iPhone for photos."
- Search: "Find photos taken in 2024."
- Introspect: "What metadata fields are available?"