ios-files
A local MCP server that lets AI clients safely read and write files on jailbroken iOS devices over SSH/SFTP.
ios-files-mcp
MCP stdio server for controlled SSH/SFTP access to an iOS device filesystem.
AI MCP client -> ios-files-mcp on your computer -> SSH/SFTP -> iOS device
Quick Install
Requirements:
- Node.js 20+
- OpenSSH running on your iOS device
- Your computer can SSH to the device
Find the iOS device IP in Settings -> Wi-Fi -> your network -> IP Address, then test:
ssh [email protected]
Run the command for your coding agent. Replace 192.168.1.23 and change-me. Your default ssh password is alpine if you haven't changed it.
Codex
npx -p github:xtofuub/ios-files-mcp iosfiles-mcp --client codex --host 192.168.1.23 --password change-me
Writes to ~/.codex/config.toml.
Claude Desktop
npx -p github:xtofuub/ios-files-mcp iosfiles-mcp --client claude --host 192.168.1.23 --password change-me
Writes to Claude Desktop's MCP config.
OpenCode
npx -p github:xtofuub/ios-files-mcp iosfiles-mcp --client opencode --host 192.168.1.23 --password change-me
Writes to ~/.config/opencode/opencode.json.
VS Code
Run this from the workspace folder where you want the MCP server enabled.
npx -p github:xtofuub/ios-files-mcp iosfiles-mcp --client vscode --host 192.168.1.23 --password change-me
Writes to .vscode/mcp.json.
All Supported Clients
npx -p github:xtofuub/ios-files-mcp iosfiles-mcp --client all --host 192.168.1.23 --password change-me
Supported --client values:
codex -> ~/.codex/config.toml
claude -> Claude Desktop config
opencode -> ~/.config/opencode/opencode.json
vscode -> .vscode/mcp.json in the current folder
all -> all supported clients
The installer writes an ios-files MCP server entry and backs up existing config files to .bak.
Install with optional Hermes bytecode decoders:
npx -p github:xtofuub/ios-files-mcp iosfiles-mcp --client codex --host 192.168.1.23 --password change-me --install-hermes
Hermes decoders are only needed for React Native Hermes bytecode bundle decoding. The flag installs hermes-dec with Python/pipx when available.
For radare2 static analysis, see the radare2 section below — recommended path is to install radare2 on the iOS device itself via Sileo.
USB SSH
Forward iOS device SSH to a local port with iproxy, then install using localhost:
ssh -p 2222 [email protected]
npx -p github:xtofuub/ios-files-mcp iosfiles-mcp --client codex --host 127.0.0.1 --port 2222 --password change-me
USB SSH still uses normal SSH auth, so use a password or SSH key.
Manual MCP Config
The installer writes this command:
{
"command": "npx",
"args": ["--yes", "--quiet", "github:xtofuub/ios-files-mcp"],
"env": {
"IOS_FILES_MCP_HOST": "192.168.1.23",
"IOS_FILES_MCP_USERNAME": "mobile",
"IOS_FILES_MCP_PASSWORD": "change-me"
}
}
Use that under mcpServers.ios-files for Claude/Cline-style clients, or under servers.ios-files for VS Code.
For an explicit package install:
npm install github:xtofuub/ios-files-mcp
To make npm install also write MCP config, set installer env vars first:
$env:IOS_FILES_MCP_INSTALL_CLIENTS="codex"
$env:IOS_FILES_MCP_HOST="192.168.1.23"
$env:IOS_FILES_MCP_USERNAME="mobile"
$env:IOS_FILES_MCP_PASSWORD="change-me"
npm install github:xtofuub/ios-files-mcp
Add this env var if you also want Hermes decoders:
$env:IOS_FILES_MCP_INSTALL_HERMES="true"
Useful env vars:
IOS_FILES_MCP_HOST
IOS_FILES_MCP_PORT
IOS_FILES_MCP_USERNAME
IOS_FILES_MCP_PASSWORD
IOS_FILES_MCP_KEY_PATH
IOS_FILES_MCP_ALLOWED_ROOTS
IOS_FILES_MCP_READ_ONLY
IOS_FILES_MCP_ALLOW_WRITES
IOS_FILES_MCP_REQUIRE_WRITE_APPROVAL
IOS_FILES_MCP_ENABLE_R2
IOS_FILES_MCP_R2_MODE
IOS_FILES_MCP_R2_DEVICE_R2_PATH
IOS_FILES_MCP_R2_DEVICE_RABIN2_PATH
IOS_FILES_MCP_R2_PATH
IOS_FILES_MCP_RABIN2_PATH
IOS_FILES_MCP_R2_TIMEOUT_MS
IOS_FILES_MCP_R2_MAX_OUTPUT_BYTES
IOS_FILES_MCP_R2_MAX_BINARY_SIZE
IOS_FILES_MCP_SFTP_OP_TIMEOUT_MS
IOS_FILES_MCP_CONFIG
Optional JSON Config File
Most users should use MCP env. JSON config files are only needed for advanced/local setups.
Minimal example:
{
"host": "192.168.1.23",
"port": 22,
"username": "mobile",
"password": "change-me",
"readOnly": true,
"allowWrites": false
}
See ios-files-mcp.config.example.json for every option.
Point MCP at the config file with IOS_FILES_MCP_CONFIG:
{
"servers": {
"ios-files": {
"command": "npx",
"args": [
"--yes",
"--quiet",
"github:xtofuub/ios-files-mcp"
],
"env": {
"IOS_FILES_MCP_CONFIG": "/path/to/ios-files-mcp/ios-files-mcp.config.json"
}
}
}
}
Or pass it as an arg:
{
"mcpServers": {
"ios-files": {
"command": "npx",
"args": [
"--yes",
"--quiet",
"github:xtofuub/ios-files-mcp",
"--config",
"/path/to/ios-files-mcp/ios-files-mcp.config.json"
]
}
}
}
Local Test
This should print help and exit:
npx --yes --quiet github:xtofuub/ios-files-mcp --help
This starts the MCP server and waits for an MCP client:
$env:IOS_FILES_MCP_HOST="192.168.1.23"
$env:IOS_FILES_MCP_USERNAME="mobile"
$env:IOS_FILES_MCP_PASSWORD="change-me"
npx --yes --quiet github:xtofuub/ios-files-mcp
Press Ctrl+C to stop it.
Development
From a clone:
npm install
npm run build
npm run typecheck
node dist/index.js --help
For local MCP testing without NPX, point your MCP client at node dist/index.js with an absolute path.
First MCP Calls
If app directories look empty, start here:
ios_connection_doctor()
ios_doctor()
ios_diagnose_roots()
Check local MCP client config:
ios_mcp_config_status()
ios_config()
To find YouTube:
ios_find_app("YouTube")
ios_find_app("com.google.ios.youtube")
ios_snapshot_app("com.google.ios.youtube")
ios_app("com.google.ios.youtube")
To inspect an app plist:
ios_read_plist("/private/var/containers/Bundle/Application/<UUID>/YouTube.app/Info.plist")
App Paths
App data containers:
/var/mobile/Containers/Data/Application/<UUID>
/private/var/mobile/Containers/Data/Application/<UUID>
App Store .app bundles:
/var/containers/Bundle/Application/<UUID>/<AppName>.app
/private/var/containers/Bundle/Application/<UUID>/<AppName>.app
Info.plist is usually in the .app bundle, not the data container.
Safety
The server is read-only by default. Writes require both:
{
"readOnly": false,
"allowWrites": true
}
When writes are enabled, write approval is still required by default:
{
"requireWriteApproval": true,
"writeApprovalTtlMs": 300000
}
Write-capable tools do not write on the first call. They return an approval request with an approvalId. If you approve the exact operation, call the same tool again with the same arguments plus that approvalId.
Approval ids are:
one-use
time-limited
bound to the exact tool name and arguments
Example:
ios_write_file("/var/mobile/test.txt", "hello")
Returns an approval request. Then, only if approved:
ios_write_file("/var/mobile/test.txt", "hello", approvalId="the-id-from-the-request")
Blocked by default:
/var/Keychains
/var/mobile/Library/Accounts
/var/mobile/Library/SMS
/var/mobile/Library/Mail
/private/var/db
/System
/usr
/bin
/sbin
Every operation is logged to ios-files-mcp.log. File contents and secrets are not logged.
Tools
Basic Filesystem
| Tool | What it does |
|---|---|
ios_list_dir(path) | Lists files and folders in one directory. |
ios_stat(path) | Returns file metadata such as type, size, owner, mode, and modified time. |
ios_exists(path) | Checks whether a path exists without failing if it is missing. |
ios_hash_file(path) | Computes a SHA-256 hash for a file. |
ios_search_files(root, pattern, maxResults, maxDepth, includeMetadata, useCache) | Runs a capped recursive filename/path search. Use app tools first for installed apps. |
Reading Files
| Tool | What it does |
|---|---|
ios_read_file(path) | Reads a UTF-8 text file into the chat, capped by maxReadSize. |
ios_read_file_chunk(path, offset, length, encoding) | Reads one bounded section of a file. Use this for large text or binary files. |
ios_tail_file(path, maxBytes) | Reads the last bytes of a file, useful for logs. |
ios_read_last_lines(path, lines, maxBytes) | Reads the last N lines of a text file. |
ios_read_plist(path) | Parses XML or binary plist files and returns JSON-safe data. |
ios_inspect_js_bundle(path) | Detects whether a React Native bundle is plain JavaScript, Hermes bytecode, or unknown binary. |
ios_decode_js_bundle(path, mode, localPath, maxOutputBytes, beautify) | Beautifies plain .jsbundle files or runs the configured Hermes decoder for bytecode bundles. |
ios_list_hermes_decoders() | Shows the configured decoder, auto-detected decoder commands, and setup notes. |
Copying Files To Your Computer
| Tool | What it does |
|---|---|
ios_download_file(remotePath, localPath, overwrite) | Copies one file from the iOS device to an allowed local folder on your computer. This is not limited by maxReadSize. |
ios_zip_download(paths, localPath, overwrite) | Creates a local ZIP containing one or more iOS device files/folders. Use this for app folders, logs, or grouped exports. |
localPath must be inside localArtifactRoots.
App Store App Helpers
| Tool | What it does |
|---|---|
ios_find_app(query) | Finds an installed app by visible name, .app name, or bundle id without doing a slow recursive search. |
ios_list_apps(query, limit) | Lists installed app bundles, optionally filtered by name or bundle id. |
ios_resolve_app_container(bundleId) | Resolves a bundle id to its .app bundle, app data container, and app group containers when visible. |
ios_list_preferences(bundleId) | Lists plist files in the app data container's Library/Preferences folder. |
ios_read_preferences(bundleId, includeAll, maxFiles) | Reads app preference plist files. By default it only reads the exact bundle-id plist. |
SQLite
| Tool | What it does |
|---|---|
ios_read_sqlite_schema(path) | Reads table/view names, SQL definitions, and table columns from a SQLite database. |
ios_query_sqlite(path, sql, limit) | Runs one read-only SQL statement and returns limited rows. Allows SELECT, PRAGMA, WITH, and EXPLAIN. |
React Native Bundles
Plain React Native .jsbundle files are JavaScript text. ios_decode_js_bundle can beautify them and either preview the result in the MCP response or save it to a local file.
Hermes bundles are bytecode. The server can detect them and auto-use hbc-decompiler, hbc-disassembler, hermesc, or hbctool if one is on PATH. The output is usually pseudo-code, HASM, or bytecode/disassembly, not the original source code.
Run ios_list_hermes_decoders() when decoding fails. It tells you what the MCP server can see from its own process.
Optional decoder helper:
npx -p github:xtofuub/ios-files-mcp ios-files-mcp-install-hermes-dec
npx -p github:xtofuub/ios-files-mcp ios-files-mcp-check-hermes-decoders
radare2 static analysis tools
By default these tools detect radare2 on the iOS device and run it there over SSH — no binary copy needed. If r2 is not installed on the device, the MCP falls back to running r2/rabin2 on your computer after copying the binary to a temporary local folder. Run ios_r2_check to see which runner is active.
Recommended install (on the iOS device, via Sileo):
- Open Sileo on the jailbroken device.
- Install the
radare2package from the Procursus repo (default on modern jailbreaks like Dopamine and palera1n). - From your computer, run
ssh mobile@<device-ip> 'r2 -v'to confirm.
Common device paths after Sileo install:
/usr/bin/r2 (rootful jailbreaks: unc0ver, checkra1n, classic palera1n)
/var/jb/usr/bin/r2 (rootless jailbreaks: Dopamine, palera1n rootless)
The MCP probes command -v r2 over SSH, so it picks up whatever is on the device's $PATH. Override with IOS_FILES_MCP_R2_DEVICE_R2_PATH=/your/path if the binary is in a non-standard location.
Modes:
IOS_FILES_MCP_R2_MODE=auto(default) — try device first, fall back to local.IOS_FILES_MCP_R2_MODE=device— require device-side r2; fail fast if missing.IOS_FILES_MCP_R2_MODE=local— always run on this computer (copies binary to a temp folder).
Optional env:
IOS_FILES_MCP_ENABLE_R2=true
IOS_FILES_MCP_R2_MODE=auto
IOS_FILES_MCP_R2_DEVICE_R2_PATH=/var/jb/usr/bin/r2
IOS_FILES_MCP_R2_DEVICE_RABIN2_PATH=/var/jb/usr/bin/rabin2
IOS_FILES_MCP_R2_PATH=r2
IOS_FILES_MCP_RABIN2_PATH=rabin2
IOS_FILES_MCP_R2_TIMEOUT_MS=30000
IOS_FILES_MCP_R2_MAX_OUTPUT_BYTES=16777216
IOS_FILES_MCP_R2_MAX_BINARY_SIZE=134217728
Migration note: the previous host-side installer (ios-files-mcp-install-radare2) and the IOS_FILES_MCP_INSTALL_R2 postinstall flag have been removed. Install radare2 on the iOS device via Sileo, or install locally with your own package manager if you prefer IOS_FILES_MCP_R2_MODE=local.
When to use:
- Use
ios_r2_app_triage(bundleId)for the fastest overview of an installed app. - Use
ios_r2_binary_info(remotePath)when you already know the binary path. - Use
ios_r2_strings(remotePath, query, limit)for endpoints, secrets, Firebase, URLs, debug strings, and feature flags. - Use
ios_r2_imports(remotePath, query, limit)for framework/API usage such as Keychain, crypto, networking, SQLite, WebKit, device integrity, and anti-debug checks. - Use
ios_r2_functions(remotePath, limit)to map available functions. - Use
ios_r2_function_disasm(remotePath, functionNameOrAddress)to inspect one selected function or address.
Recommended analysis flow:
ios_find_app("App Name")orios_resolve_app_container("com.example.app")ios_r2_app_triage("com.example.app")ios_r2_strings(remotePath, query, limit)with queries likehttp,api,firebase,token,auth,key,debugios_r2_imports(remotePath, query, limit)with queries likeSecItem,CommonCrypto,CryptoKit,NSURLSession,SQLite,WKWebViewios_r2_functions(remotePath, limit)ios_r2_function_disasm(remotePath, functionNameOrAddress)on a specific interesting function or address
| Tool | What it does |
|---|---|
ios_r2_check() | Shows whether r2 support is enabled and whether local r2/rabin2 are available. |
ios_r2_binary_info(remotePath) | Returns Mach-O metadata and linked libraries for one binary path. |
ios_r2_app_triage(bundleId) | Resolves an installed app, finds its executable, and returns binary info, interesting imports/strings, functions preview, and next actions. |
ios_r2_strings(remotePath, query, limit) | Searches binary strings for URLs, endpoints, tokens, Firebase config, debug text, and feature flags. |
ios_r2_imports(remotePath, query, limit) | Searches imported symbols/framework APIs such as Keychain, crypto, networking, SQLite, WebKit, and anti-debug calls. |
ios_r2_functions(remotePath, limit) | Lists function names and addresses before deeper inspection. |
ios_r2_function_disasm(remotePath, functionNameOrAddress) | Returns structured JSON disassembly for one selected function or address. |
Writing Files
These tools are disabled unless readOnly=false and allowWrites=true.
| Tool | What it does |
|---|---|
ios_write_file(path, content) | Writes UTF-8 content to a file. Existing files are backed up when backupBeforeWrite=true. |
ios_append_file(path, content) | Appends UTF-8 content to a file, or creates it if missing. |
ios_delete_file(path) | Deletes a file or empty directory. |
ios_move_file(from, to) | Moves or renames a file. Existing destinations are backed up when configured. |
ios_copy_file(from, to) | Copies a file on the iOS device. Existing destinations are backed up when configured. |
ios_mkdir(path) | Creates a directory. |
Write-capable tools also accept optional approvalId. If requireWriteApproval=true, the first call returns an approval request and does not write. Retry the same tool with the returned approvalId only after approving the exact operation.
Diagnostics
| Tool | What it does |
|---|---|
ios_doctor() | Finds setup problems: SSH/SFTP connection, visible app roots, local export folders, MCP config, and Hermes decoder availability. |
ios_connection_doctor() | Checks SSH/SFTP connection, visible roots, local artifact roots, MCP config, and Hermes decoder availability. |
ios_config() | Checks whether Codex, Claude, OpenCode, and VS Code are configured to launch this MCP server correctly. |
ios_mcp_config_status() | Shows whether Codex, Claude, OpenCode, and VS Code config files contain the expected ios-files server entry. |
ios_app(bundleId) | Gives a quick app overview: bundle path, data container, app groups, Info.plist summary, preference files, SQLite files, and JS bundles. |
ios_snapshot_app(bundleId) | Builds a metadata-focused app snapshot: bundle/data/app-group paths, Info.plist summary, preference files, SQLite files, and JS bundles. |
ios_diagnose_roots() | Checks whether common iOS app roots are visible over the current SSH/SFTP login and gives notes for empty directories. |
Notes
- Restart the MCP client after rebuilding.
- If directories are empty as
mobile, try SSH/SFTP asrootif your device exposes those directories only to root. ios_search_filesis recursive and can be slow over SFTP. Useios_find_app,ios_list_apps, orios_resolve_app_containerfor apps.ios_search_filesis capped and cached by default. Repeating the same search should return from memory forsearchCacheTtlMs.- Keep recursive searches small first, for example
maxResults=10andmaxDepth=2. ios_search_filesreturns concise path/type results by default. SetincludeMetadata=trueonly when size and modified time are needed.ios_read_filedefaults to a 4 MiB cap throughmaxReadSize.- Use
ios_read_file_chunk,ios_tail_file, orios_read_last_linesinstead of repeated full-file reads. - Use
ios_download_filefor one large file, orios_zip_downloadfor folders/multiple files you want copied from the iOS device to your computer. - Use
ios_read_sqlite_schemaandios_query_sqlitefor read-only SQLite inspection instead of dumping whole database files into chat. - Use
ios_inspect_js_bundlebeforeios_decode_js_bundlewhen you are not sure whether a React Native bundle is plain JavaScript or Hermes bytecode. - More app lookup guidance is in
SKILLS.md.
Servidores relacionados
KnowledgeBaseMCP
Extract text content from local PDF, DOCX, and PPTX files to build a knowledge base.
Sharepoint
Provides access to organizational SharePoint sites and files.
Lumina Docs
An intelligent structured document management system designed for large language models.
MCP Apple Notes
Perform semantic search and retrieval augmented generation over your Apple Notes.
Remote File Server
An MCP server that gives any MCP client read access to an SMB/CIFS file share servers
MCP PDF Reader
Extract text, images, and perform OCR on PDF documents using Tesseract OCR.
File Explorer MCP
A server for programmatic exploration of local files and folders.
MCP Start App
An MCP server for local file management and system operations.
Excel/CSV MCP Server
Read, analyze, and manipulate data in Excel (XLSX, XLS) and CSV files with advanced filtering and analytics.
Readonly Filesystem MCP Server
Provides read-only access to local files and directories.