ios-files

Um servidor MCP local que permite que clientes de IA leiam e escrevam arquivos com segurança em dispositivos iOS desbloqueados via SSH/SFTP.

Documentação

ios-files-mcp

Servidor MCP stdio para acesso controlado via SSH/SFTP ao sistema de arquivos de um dispositivo iOS.

AI MCP client -> ios-files-mcp on your computer -> SSH/SFTP -> iOS device

Instalação Rápida

Pré-requisitos:

  • Node.js 20+
  • OpenSSH rodando no seu dispositivo iOS
  • Seu computador consegue acessar o dispositivo via SSH

Encontre o IP do dispositivo iOS em Settings -> Wi-Fi -> your network -> IP Address e teste:

ssh mobile@192.168.1.23

Execute o comando para o seu agente de codificação. Substitua 192.168.1.23 e change-me. Sua senha ssh padrão é alpine se você não a alterou.

Codex

npx -p github:xtofuub/ios-files-mcp iosfiles-mcp --client codex --host 192.168.1.23 --password change-me

Grava em ~/.codex/config.toml.

Claude Desktop

npx -p github:xtofuub/ios-files-mcp iosfiles-mcp --client claude --host 192.168.1.23 --password change-me

Grava na configuração MCP do Claude Desktop.

OpenCode

npx -p github:xtofuub/ios-files-mcp iosfiles-mcp --client opencode --host 192.168.1.23 --password change-me

Grava em ~/.config/opencode/opencode.json.

VS Code

Execute a partir da pasta do workspace onde você deseja habilitar o servidor MCP.

npx -p github:xtofuub/ios-files-mcp iosfiles-mcp --client vscode --host 192.168.1.23 --password change-me

Grava em .vscode/mcp.json.

Todos os Clientes Suportados

npx -p github:xtofuub/ios-files-mcp iosfiles-mcp --client all --host 192.168.1.23 --password change-me

Valores suportados para --client:

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

O instalador grava uma entrada de servidor MCP ios-files e faz backup dos arquivos de configuração existentes em .bak.

Instale com decodificadores opcionais de bytecode Hermes:

npx -p github:xtofuub/ios-files-mcp iosfiles-mcp --client codex --host 192.168.1.23 --password change-me --install-hermes

Os decodificadores Hermes são necessários apenas para decodificação de bundles de bytecode Hermes do React Native. A flag instala hermes-dec com Python/pipx quando disponível.

Para análise estática com radare2, veja a seção radare2 abaixo — o caminho recomendado é instalar radare2 no próprio dispositivo iOS via Sileo.

SSH via USB

Encaminhe o SSH do dispositivo iOS para uma porta local com iproxy e instale usando localhost:

ssh -p 2222 mobile@127.0.0.1
npx -p github:xtofuub/ios-files-mcp iosfiles-mcp --client codex --host 127.0.0.1 --port 2222 --password change-me

SSH via USB ainda usa autenticação SSH normal, então use senha ou chave SSH.

Configuração MCP Manual

O instalador grava este comando:

{
  "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 isso em mcpServers.ios-files para clientes estilo Claude/Cline, ou em servers.ios-files para VS Code.

Para instalação explícita do pacote:

npm install github:xtofuub/ios-files-mcp

Para fazer npm install também gravar a configuração MCP, defina as variáveis de ambiente do instalador primeiro:

$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

Adicione esta variável de ambiente se você também quiser os decodificadores Hermes:

$env:IOS_FILES_MCP_INSTALL_HERMES="true"

Variáveis de ambiente úteis:

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

Arquivo de Configuração JSON Opcional

A maioria dos usuários deve usar MCP env. Arquivos de configuração JSON são necessários apenas para configurações avançadas/locais.

Exemplo mínimo:

{
  "host": "192.168.1.23",
  "port": 22,
  "username": "mobile",
  "password": "change-me",
  "readOnly": true,
  "allowWrites": false
}

Veja ios-files-mcp.config.example.json para todas as opções.

Aponte o MCP para o arquivo de configuração com 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"
      }
    }
  }
}

Ou passe como argumento:

{
  "mcpServers": {
    "ios-files": {
      "command": "npx",
      "args": [
        "--yes",
        "--quiet",
        "github:xtofuub/ios-files-mcp",
        "--config",
        "/path/to/ios-files-mcp/ios-files-mcp.config.json"
      ]
    }
  }
}

Teste Local

Isso deve imprimir a ajuda e sair:

npx --yes --quiet github:xtofuub/ios-files-mcp --help

Isso inicia o servidor MCP e aguarda um cliente MCP:

$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

Pressione Ctrl+C para interromper.

Desenvolvimento

A partir de um clone:

npm install
npm run build
npm run typecheck
node dist/index.js --help

Para teste MCP local sem NPX, aponte seu cliente MCP para node dist/index.js com um caminho absoluto.

Primeiras Chamadas MCP

Se os diretórios de aplicativos parecerem vazios, comece aqui:

ios_connection_doctor()
ios_doctor()
ios_diagnose_roots()

Verifique a configuração local do cliente MCP:

ios_mcp_config_status()
ios_config()

Para encontrar o 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")

Para inspecionar um plist de aplicativo:

ios_read_plist("/private/var/containers/Bundle/Application/<UUID>/YouTube.app/Info.plist")

Caminhos de Aplicativos

Contêineres de dados de aplicativos:

/var/mobile/Containers/Data/Application/<UUID>
/private/var/mobile/Containers/Data/Application/<UUID>

Bundles .app da App Store:

/var/containers/Bundle/Application/<UUID>/<AppName>.app
/private/var/containers/Bundle/Application/<UUID>/<AppName>.app

Info.plist geralmente está no bundle .app, não no contêiner de dados.

Segurança

O servidor é somente leitura por padrão. Gravações exigem ambos:

{
  "readOnly": false,
  "allowWrites": true
}

Quando gravações estão habilitadas, a aprovação de gravação ainda é exigida por padrão:

{
  "requireWriteApproval": true,
  "writeApprovalTtlMs": 300000
}

Ferramentas com capacidade de gravação não gravam na primeira chamada. Elas retornam uma solicitação de aprovação com um approvalId. Se você aprovar a operação exata, chame a mesma ferramenta novamente com os mesmos argumentos mais esse approvalId.

IDs de aprovação são:

one-use
time-limited
bound to the exact tool name and arguments

Exemplo:

ios_write_file("/var/mobile/test.txt", "hello")

Retorna uma solicitação de aprovação. Então, somente se aprovado:

ios_write_file("/var/mobile/test.txt", "hello", approvalId="the-id-from-the-request")

Bloqueado por padrão:

/var/Keychains
/var/mobile/Library/Accounts
/var/mobile/Library/SMS
/var/mobile/Library/Mail
/private/var/db
/System
/usr
/bin
/sbin

Toda operação é registrada em ios-files-mcp.log. Conteúdos de arquivos e segredos não são registrados.

Ferramentas

Sistema de Arquivos Básico

FerramentaO que faz
ios_list_dir(path)Lista arquivos e pastas em um diretório.
ios_stat(path)Retorna metadados de arquivo como tipo, tamanho, proprietário, modo e hora de modificação.
ios_exists(path)Verifica se um caminho existe sem falhar se estiver ausente.
ios_hash_file(path)Calcula um hash SHA-256 para um arquivo.
ios_search_files(root, pattern, maxResults, maxDepth, includeMetadata, useCache)Executa uma busca recursiva limitada por nome de arquivo/caminho. Use as ferramentas de aplicativos primeiro para aplicativos instalados.

Leitura de Arquivos

FerramentaO que faz
ios_read_file(path)Lê um arquivo de texto UTF-8 no chat, limitado por maxReadSize.
ios_read_file_chunk(path, offset, length, encoding)Lê uma seção limitada de um arquivo. Use para arquivos grandes de texto ou binários.
ios_tail_file(path, maxBytes)Lê os últimos bytes de um arquivo, útil para logs.
ios_read_last_lines(path, lines, maxBytes)Lê as últimas N linhas de um arquivo de texto.
ios_read_plist(path)Analisa arquivos plist XML ou binários e retorna dados compatíveis com JSON.
ios_inspect_js_bundle(path)Detecta se um bundle React Native é JavaScript puro, bytecode Hermes ou binário desconhecido.
ios_decode_js_bundle(path, mode, localPath, maxOutputBytes, beautify)Embeleza arquivos .jsbundle puros ou executa o decodificador Hermes configurado para bundles de bytecode.
ios_list_hermes_decoders()Mostra o decodificador configurado, comandos de decodificador auto-detectados e notas de configuração.

Copiando Arquivos para Seu Computador

FerramentaO que faz
ios_download_file(remotePath, localPath, overwrite)Copia um arquivo do dispositivo iOS para uma pasta local permitida no seu computador. Não é limitado por maxReadSize.
ios_zip_download(paths, localPath, overwrite)Cria um ZIP local contendo um ou mais arquivos/pastas do dispositivo iOS. Use para pastas de aplicativos, logs ou exportações agrupadas.

localPath deve estar dentro de localArtifactRoots.

Auxiliares para Aplicativos da App Store

FerramentaO que faz
ios_find_app(query)Encontra um aplicativo instalado pelo nome visível, nome .app ou bundle id sem fazer uma busca recursiva lenta.
ios_list_apps(query, limit)Lista bundles de aplicativos instalados, opcionalmente filtrados por nome ou bundle id.
ios_resolve_app_container(bundleId)Resolve um bundle id para seu bundle .app, contêiner de dados do aplicativo e contêineres de grupo de aplicativos quando visíveis.
ios_list_preferences(bundleId)Lista arquivos plist na pasta Library/Preferences do contêiner de dados do aplicativo.
ios_read_preferences(bundleId, includeAll, maxFiles)Lê arquivos plist de preferências do aplicativo. Por padrão, lê apenas o plist exato do bundle id.

SQLite

FerramentaO que faz
ios_read_sqlite_schema(path)Lê nomes de tabelas/views, definições SQL e colunas de tabelas de um banco de dados SQLite.
ios_query_sqlite(path, sql, limit)Executa uma instrução SQL somente leitura e retorna linhas limitadas. Permite SELECT, PRAGMA, WITH e EXPLAIN.

Bundles React Native

Arquivos .jsbundle React Native puros são texto JavaScript. ios_decode_js_bundle pode embelezá-los e visualizar o resultado na resposta MCP ou salvá-lo em um arquivo local.

Bundles Hermes são bytecode. O servidor pode detectá-los e usar automaticamente hbc-decompiler, hbc-disassembler, hermesc ou hbctool se um estiver no PATH. A saída geralmente é pseudo-código, HASM ou bytecode/desmontagem, não o código-fonte original.

Execute ios_list_hermes_decoders() quando a decodificação falhar. Ele informa o que o servidor MCP pode ver a partir do seu próprio processo.

Auxiliar opcional de decodificação:

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

Ferramentas de análise estática radare2

Por padrão, essas ferramentas detectam radare2 no dispositivo iOS e o executam lá via SSH — sem necessidade de copiar binários. Se r2 não estiver instalado no dispositivo, o MCP usa r2/rabin2 no seu computador após copiar o binário para uma pasta local temporária. Execute ios_r2_check para ver qual executor está ativo.

Instalação recomendada (no dispositivo iOS, via Sileo):

  1. Abra o Sileo no dispositivo com jailbreak.
  2. Instale o pacote radare2 do repositório Procursus (padrão em jailbreaks modernos como Dopamine e palera1n).
  3. Do seu computador, execute ssh mobile@<device-ip> 'r2 -v' para confirmar.

Caminhos comuns no dispositivo após instalação via Sileo:

/usr/bin/r2          (rootful jailbreaks: unc0ver, checkra1n, classic palera1n)
/var/jb/usr/bin/r2   (rootless jailbreaks: Dopamine, palera1n rootless)

O MCP verifica command -v r2 via SSH, então ele detecta o que estiver no $PATH do dispositivo. Substitua com IOS_FILES_MCP_R2_DEVICE_R2_PATH=/your/path se o binário estiver em um local não padrão.

Modos:

  • IOS_FILES_MCP_R2_MODE=auto (padrão) — tenta o dispositivo primeiro, depois o local.
  • IOS_FILES_MCP_R2_MODE=device — exige r2 no dispositivo; falha rápido se ausente.
  • IOS_FILES_MCP_R2_MODE=local — sempre executa neste computador (copia o binário para uma pasta temporária).

Env opcional:

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

Nota de migração: o instalador anterior no host (ios-files-mcp-install-radare2) e a flag pós-instalação IOS_FILES_MCP_INSTALL_R2 foram removidos. Instale radare2 no dispositivo iOS via Sileo, ou instale localmente com seu próprio gerenciador de pacotes se preferir IOS_FILES_MCP_R2_MODE=local.

Quando usar:

  • Use ios_r2_app_triage(bundleId) para a visão geral mais rápida de um aplicativo instalado.
  • Use ios_r2_binary_info(remotePath) quando você já souber o caminho do binário.
  • Use ios_r2_strings(remotePath, query, limit) para endpoints, segredos, Firebase, URLs, strings de depuração e feature flags.
  • Use ios_r2_imports(remotePath, query, limit) para uso de frameworks/APIs como Keychain, criptografia, rede, SQLite, WebKit, integridade do dispositivo e verificações anti-debug.
  • Use ios_r2_functions(remotePath, limit) para mapear funções disponíveis.
  • Use ios_r2_function_disasm(remotePath, functionNameOrAddress) para inspecionar uma função ou endereço selecionado.

Fluxo de análise recomendado:

  1. ios_find_app("App Name") ou ios_resolve_app_container("com.example.app")
  2. ios_r2_app_triage("com.example.app")
  3. ios_r2_strings(remotePath, query, limit) com consultas como http, api, firebase, token, auth, key, debug
  4. ios_r2_imports(remotePath, query, limit) com consultas como SecItem, CommonCrypto, CryptoKit, NSURLSession, SQLite, WKWebView
  5. ios_r2_functions(remotePath, limit)
  6. ios_r2_function_disasm(remotePath, functionNameOrAddress) em uma função ou endereço específico interessante
FerramentaO que faz
ios_r2_check()Mostra se o suporte r2 está habilitado e se r2/rabin2 locais estão disponíveis.
ios_r2_binary_info(remotePath)Retorna metadados Mach-O e bibliotecas vinculadas para um caminho de binário.
ios_r2_app_triage(bundleId)Resolve um aplicativo instalado, encontra seu executável e retorna informações do binário, imports/strings interessantes, prévia de funções e próximas ações.
ios_r2_strings(remotePath, query, limit)Busca strings binárias por URLs, endpoints, tokens, configuração Firebase, texto de depuração e feature flags.
ios_r2_imports(remotePath, query, limit)Busca símbolos importados/APIs de frameworks como Keychain, criptografia, rede, SQLite, WebKit e chamadas anti-debug.
ios_r2_functions(remotePath, limit)Lista nomes e endereços de funções antes de inspeção mais profunda.
ios_r2_function_disasm(remotePath, functionNameOrAddress)Retorna desmontagem JSON estruturada para uma função ou endereço selecionado.

Gravação de Arquivos

Estas ferramentas estão desabilitadas a menos que readOnly=false e allowWrites=true.

FerramentaO que faz
ios_write_file(path, content)Grava conteúdo UTF-8 em um arquivo. Arquivos existentes são copiados quando backupBeforeWrite=true.
ios_append_file(path, content)Adiciona conteúdo UTF-8 a um arquivo, ou o cria se ausente.
ios_delete_file(path)Exclui um arquivo ou diretório vazio.
ios_move_file(from, to)Move ou renomeia um arquivo. Destinos existentes são copiados quando configurado.
ios_copy_file(from, to)Copia um arquivo no dispositivo iOS. Destinos existentes são copiados quando configurado.
ios_mkdir(path)Cria um diretório.

Ferramentas com capacidade de gravação também aceitam approvalId opcional. Se requireWriteApproval=true, a primeira chamada retorna uma solicitação de aprovação e não grava. Repita a mesma ferramenta com o approvalId retornado somente após aprovar a operação exata.

Diagnóstico

FerramentaO que faz
ios_doctor()Encontra problemas de configuração: conexão SSH/SFTP, raízes de aplicativos visíveis, pastas de exportação locais, configuração do MCP e disponibilidade do decodificador Hermes.
ios_connection_doctor()Verifica conexão SSH/SFTP, raízes visíveis, raízes de artefatos locais, configuração do MCP e disponibilidade do decodificador Hermes.
ios_config()Verifica se Codex, Claude, OpenCode e VS Code estão configurados para iniciar este servidor MCP corretamente.
ios_mcp_config_status()Mostra se os arquivos de configuração do Codex, Claude, OpenCode e VS Code contêm a entrada de servidor ios-files esperada.
ios_app(bundleId)Fornece uma visão geral rápida do aplicativo: caminho do bundle, contêiner de dados, grupos de aplicativos, resumo do Info.plist, arquivos de preferências, arquivos SQLite e bundles JS.
ios_snapshot_app(bundleId)Constrói um snapshot do aplicativo focado em metadados: caminhos de bundle/dados/grupos de aplicativos, resumo do Info.plist, arquivos de preferências, arquivos SQLite e bundles JS.
ios_diagnose_roots()Verifica se as raízes comuns de aplicativos iOS estão visíveis no login SSH/SFTP atual e fornece notas para diretórios vazios.

Notas

  • Reinicie o cliente MCP após recompilar.
  • Se os diretórios estiverem vazios como mobile, tente SSH/SFTP como root se o seu dispositivo expor esses diretórios apenas para root.
  • ios_search_files é recursivo e pode ser lento via SFTP. Use ios_find_app, ios_list_apps ou ios_resolve_app_container para aplicativos.
  • ios_search_files é limitado e armazenado em cache por padrão. Repetir a mesma busca deve retornar da memória por searchCacheTtlMs.
  • Mantenha buscas recursivas pequenas primeiro, por exemplo maxResults=10 e maxDepth=2.
  • ios_search_files retorna resultados concisos de caminho/tipo por padrão. Defina includeMetadata=true apenas quando tamanho e hora de modificação forem necessários.
  • ios_read_file usa um limite padrão de 4 MiB via maxReadSize.
  • Use ios_read_file_chunk, ios_tail_file ou ios_read_last_lines em vez de leituras repetidas de arquivos inteiros.
  • Use ios_download_file para um arquivo grande, ou ios_zip_download para pastas/vários arquivos que você queira copiar do dispositivo iOS para o seu computador.
  • Use ios_read_sqlite_schema e ios_query_sqlite para inspeção somente leitura de SQLite em vez de despejar arquivos de banco de dados inteiros no chat.
  • Use ios_inspect_js_bundle antes de ios_decode_js_bundle quando você não tiver certeza se um bundle React Native é JavaScript puro ou bytecode Hermes.
  • Mais orientações sobre busca de aplicativos estão em SKILLS.md.