ShieldFive
Mova arquivos do seu computador para um cofre com criptografia de ponta a ponta: cada cópia é lida de volta e verificada antes que o original vá para a lixeira local, nada é excluído. Também encontra duplicatas e organiza pastas. Descriptografa na sua máquina; acesso limitado e revogável.
Documentação
@shieldfive/mcp
Um servidor Model Context Protocol que permite Claude, ChatGPT, Cursor ou um modelo local trabalhar com duas coisas:
- seu cofre ShieldFive, criptografado de ponta a ponta: mova arquivos do seu computador para ele — cada um criptografado aqui, enviado, lido de volta e comparado byte por byte antes que o original seja movido para uma pasta de lixo local, nunca excluído — e encontre duplicatas, veja o que ocupa espaço, renomeie, mova e mova para a Lixeira. Funciona nas pastas que você concede, descriptografa na sua máquina, e toda alteração pode ser desfeita;
- pastas no seu próprio disco: os mesmos trabalhos de organização, sem nenhum acesso à rede.
Os servidores da ShieldFive nunca veem um nome de arquivo ou um byte de conteúdo em texto claro, e isso vale também com este servidor em execução. A descriptografia acontece dentro deste processo, no seu computador. O que o assistente faz com o que lê é uma questão separada, respondida em Modelo de segurança.
Conecte seu cofre em 60 segundos
Requer Node 20 ou mais recente.
-
Adicione o servidor ao seu assistente. Para Claude Desktop, adicione isto em
claude_desktop_config.json(Cursor usa o mesmo bloco em~/.cursor/mcp.json):{ "mcpServers": { "shieldfive": { "command": "npx", "args": ["-y", "@shieldfive/mcp"] } } }Para Claude Code:
claude mcp add shieldfive -- npx -y @shieldfive/mcp -
Reinicie o assistente e peça para ele organizar meu cofre ShieldFive. Ele chama
vault_connect, que abre a ShieldFive no seu navegador. -
Nessa aba, escolha as pastas, Somente leitura ou Ler e organizar, e um prazo de validade (1 hora a 90 dias), e clique em Autorizar.
Essa é toda a configuração: a conexão é entregue diretamente ao servidor em execução
no seu computador — via 127.0.0.1, nunca pela ShieldFive — e armazenada no
chaveiro do seu sistema. Nada é copiado manualmente.
Para conectar antes de iniciar uma conversa, execute npx -y @shieldfive/mcp login:
mesma página do navegador, mesmo resultado. login --paste aceita uma string de
conexão que você copiou de Configurações → Assistentes de IA, para uma máquina sem
navegador.
npx @shieldfive/mcp status mostra qual conexão está configurada e se a
ShieldFive ainda a aceita. npx @shieldfive/mcp logout a remove do
chaveiro. Revogá-la na ShieldFive é o que corta o acesso em todos os lugares.
Para CI ou uma máquina sem chaveiro, defina SHIELDFIVE_GRANT para a string de
conexão. Qualquer coisa que possa ler o ambiente do servidor pode então ler a
conexão, então prefira o chaveiro onde houver um. Definir
SHIELDFIVE_GRANT=none mantém um cliente somente local em uma máquina cujo chaveiro
contém uma conexão para outra.
Como a transferência pelo navegador é mantida segura
- A página nunca aceita uma URL de retorno, apenas um número de porta, e constrói
http://127.0.0.1:<port>/callbackela mesma. Um link malicioso não pode enviar sua conexão para qualquer lugar além da sua própria máquina. - O ouvinte aceita exatamente uma entrega: um POST para
/callback,Hostexatamente o endereço de loopback (então um nome DNS reatribuído é recusado), semOriginalém do da ShieldFive, e um estado de 256 bits comparado em tempo constante. Então ele fecha. - A string de conexão viaja em um corpo de formulário, nunca em uma URL, então não cai no histórico do navegador.
- O ouvinte existe apenas enquanto uma conexão está sendo autorizada, e por no máximo 10 minutos.
Modelo de segurança
Em termos simples:
- A string de conexão contém duas coisas. Um token que o servidor verifica em cada solicitação, e um segredo que nunca sai da sua máquina. A ShieldFive armazena apenas um hash do token e nunca viu o segredo.
- O segredo abre apenas as pastas que você escolheu. Quando você cria uma conexão, seu navegador envolve as chaves dessas pastas sob uma chave derivada do segredo. Ele não envolve mais nada: nem a chave raiz do seu cofre, nem sua senha, nem sua chave secreta pós-quântica. Subpastas abrem através da cadeia normal de chaves de pasta do cofre. Uma pasta que você não escolheu não pode ser aberta com nada que este servidor possua.
- A ShieldFive aplica escopo, validade e revogação em cada solicitação. As verificações neste processo apenas produzem erros mais claros; o servidor é o limite. Revogar uma conexão faz sua próxima solicitação falhar. Nada é armazenado em cache que sobreviva a uma revogação.
- A descriptografia acontece aqui, em memória. Nenhum texto claro, chave ou texto cifrado é gravado em disco. Os módulos do cofre não importam o sistema de arquivos, e um teste afirma isso.
- Nada é excluído.
vault_trashmove itens para uma pasta na sua Lixeira que pertence à conexão. Não há ferramenta de exclusão permanente, e a API que uma conexão pode alcançar não tem rota de exclusão. Cada renomeação, movimentação e envio para a lixeira aparece em Configurações → Assistentes de IA → Atividade com um botão Desfazer. - Toda alteração é pré-visualizada primeiro. Ferramentas de mutação relatam um plano, e a chamada confirmada deve carregar o token desse plano e é recusada se os itens mudaram no meio tempo.
O que isso não protege:
- Seu provedor de IA vê o que o assistente lê. Nomes de arquivos, e os conteúdos de arquivos que o assistente abre, vão para o assistente, e para um assistente em nuvem isso significa para seu provedor, como o resto da sua conversa. A única maneira de evitar isso é um modelo local.
- Revogar não pode desler. Qualquer coisa que o assistente já leu permanece lida. Nada mais sobrevive a isso: os conteúdos dos arquivos são transmitidos através da ShieldFive em cada solicitação, então não há link de download que sobreviva a uma revogação.
- Uma conexão é construída a partir do que o servidor mostra ao seu navegador quando você a cria. Cada extensão posterior é verificada contra suas próprias chaves, então um servidor comprometido não pode ampliar uma conexão depois. No momento da criação, porém, um servidor comprometido poderia rotular incorretamente qual pasta você escolheu.
- Uma string de conexão copiada é uma chave viva para as pastas que ela cobre até expirar ou você revogá-la. Mantenha-a no chaveiro.
- Arquivos podem conter instruções direcionadas ao assistente. Este servidor marca
cada nome e conteúdo de arquivo como dados, cerca conteúdos de arquivos em um bloco que o arquivo
não pode fechar, limita
vault_trasha 50 itens por chamada, exige uma pré-visualização para toda alteração, e mantém toda alteração desfazível. Um modelo ainda pode ser convencido a cometer um erro reversível dentro das pastas que você concedeu.
O design completo, incluindo o modelo de ameaças e o raciocínio por trás de cada
decisão, está em
docs/mcp-grants-design.md.
Ferramentas do cofre
vault_connect está sempre disponível. As demais são registradas assim que uma conexão
existe — conectar no meio da conversa as anuncia com
notifications/tools/list_changed. Tudo abaixo nomeia coisas por id; caminhos
são para pessoas.
| Ferramenta | Necessita | O que faz |
|---|---|---|
vault_connect | — | abre a ShieldFive no navegador para autorizar uma conexão, e a armazena no chaveiro |
vault_list_files | leitura | arquivos e pastas no escopo, com nomes, caminhos, tamanhos, datas descriptografados |
vault_search_files | leitura | por nome, caminho, extensão, tamanho ou data, executado localmente sobre nomes descriptografados |
vault_storage_stats | leitura | totais, as maiores pastas e arquivos, uma divisão por tipo |
vault_find_duplicates | leitura | arquivos de mesmo tamanho descriptografados em memória e comparados por SHA-256; com orçamento, e informa quando um resultado é um limite inferior |
vault_read_file | leitura | arquivos de texto como conteúdo cercado e não confiável (até 1 M de caracteres); outros tipos retornam apenas detalhes |
vault_rename | organizar | renomear um arquivo ou pasta |
vault_move | organizar | mover para outra pasta no escopo |
vault_create_folder | organizar | criar uma pasta no escopo |
vault_upload | escrita | criptografar um arquivo local aqui e colocá-lo no cofre, depois lê-lo de volta e comparar antes de ser informado que é seguro remover o original |
vault_trash | organizar | até 50 itens para a pasta da conexão na Lixeira |
vault_move_in | escrita | liberar espaço: até 50 arquivos locais enviados e verificados um a um, cada original movido para a lixeira local somente após sua cópia ser lida de volta idêntica — uma aprovação, nada excluído |
Limites que um usuário pode encontrar:
- Arquivos pós-quânticos enviados de um telefone ou da CLI aparecem como
readable: falseaté você abrir a ShieldFive na web novamente, o que adiciona a chave que a conexão precisa. Arquivos enviados no aplicativo web ficam prontos imediatamente. - A primeira listagem de um cofre grande leva um tempo. Cada nome custa cerca de 70 ms de Argon2id, distribuídos pelos núcleos da sua CPU (cerca de 20 segundos para 2.000 nomes em 8 núcleos). Os nomes são armazenados em cache em memória pelo resto da sessão.
- Itens no topo de uma conexão de cofre inteiro podem ser lidos e movidos para uma pasta, mas não renomeados no lugar, e nada pode ser movido para o topo. Seus nomes estão selados sob sua chave raiz do cofre, que uma conexão nunca possui.
- Envios precisam de uma conexão que possa adicionar arquivos ("Ler, organizar e adicionar arquivos" quando você autoriza) e uma cota de envio, que você escolhe então. Cada arquivo tem no máximo 512 MB. Envios e movimentações leem arquivos locais, então o servidor precisa de raízes além de uma conexão.
- Mover arquivos para dentro não libera espaço por si só.
vault_move_incoloca cada original verificado em.shieldfive-mcp-trash, com um manifesto nomeando sua cópia no cofre; o espaço volta quando você esvazia esse diretório.
Arquivos locais
Todo caminho após o nome do pacote é uma raiz. As ferramentas locais podem ler e escrever dentro desses diretórios e em nenhum outro lugar, e não fazem nenhuma solicitação de rede.
npx @shieldfive/mcp ~/Documents ~/Downloads
Em claude_desktop_config.json:
{
"mcpServers": {
"shieldfive": {
"command": "npx",
"args": ["-y", "@shieldfive/mcp", "/Users/you/Documents", "/Volumes/Archive"]
}
}
}
Com uma conexão configurada e sem raízes, apenas as ferramentas do cofre são registradas. Com raízes e sem conexão, apenas as ferramentas locais são, e o servidor se comporta exatamente como 0.2.0 fazia. Com ambos, você tem ambos.
SHIELDFIVE_MCP_ROOTS adiciona raízes também — as duas são combinadas, não
alternativas — como uma lista separada pelo separador de caminho da sua plataforma (: no
macOS e Linux, ; no Windows):
SHIELDFIVE_MCP_ROOTS="/Users/you/Documents:/Volumes/Archive" npx @shieldfive/mcp
Espaços em branco ao redor de uma raiz são ignorados. Em um caminho dado a uma ferramenta, não são: lá, cada caractere faz parte do caminho.
Veja funcionando primeiro
npm run demo
demo/run-demo.mjs cria cinco arquivos em um diretório temporário — dois com
conteúdos idênticos sob nomes diferentes, um chamariz de mesmo tamanho, um arquivo de 12 MB e
um PDF de dois anos — executa as ferramentas de leitura sobre eles, pré-visualiza uma chamada de lixeira, depois
confirma e mostra o manifesto. Não toca em nada fora desse diretório
e o remove no final (--keep o deixa no lugar).
O que as ferramentas locais não podem fazer
Elas não podem dizer se um arquivo local já está no seu cofre. Corresponder um nome e tamanho locais a uma listagem do cofre é como uma ferramenta exclui a única cópia de algo, e este servidor não vai adivinhar.
Elas não podem impedir que os resultados cheguem ao seu provedor de IA. As ferramentas locais não fazem nenhuma solicitação de rede, e isso vale exatamente o que diz e nada mais: tudo o que elas retornam — caminhos, nomes de arquivos, tamanhos, datas, os resumos que relatam — volta para o cliente de IA que o chamou, e se esse cliente é um assistente em nuvem, esses nomes viajam para o provedor do assistente como o resto da sua conversa. Escolha raízes com base nisso.
Nunca inferirá que dois arquivos são iguais a partir de seus nomes e tamanhos. A detecção de duplicatas lê ambos os arquivos e compara um SHA-256 completo de seus conteúdos. A correspondência de nomes é como uma ferramenta de deduplicação exclui a única cópia de algo, e o custo de fazer certo é alguns segundos de I/O de disco.
O hash é orçado, porém, e o orçamento pode tornar a resposta incompleta.
Candidatos são agrupados por tamanho, triados em um hash dos primeiros 64 KiB onde
os arquivos são maiores que isso, depois confirmados com um resumo completo. Cada leitura de
qualquer tipo conta contra max_files_hashed, 20.000 por padrão. Quando o
orçamento acaba, o resto fica sem hash — o grupo em que ele acaba é submetido a hash em
parte, cópias mais antigas primeiro — e o resultado informa quantos arquivos e quanto espaço
nunca foram verificados. Grupos são processados do maior para o menor, então o que sobrevive a um
orçamento apertado é o que valia mais.
O que conta como recuperável é contado por arquivo no disco. Nomes que são hardlinks
para um mesmo arquivo são uma cópia, porque remover um deles não libera nada. Clones
APFS — o que o Duplicar do Finder faz em um volume APFS — também compartilham seu
armazenamento, mas nada que este servidor possa ler distingue um clone de uma cópia
real, então clones são relatados como recuperáveis quando mover um para a lixeira
libera pouco ou nada. A cópia indicada para manter é a modificada mais cedo; em caso
de empate, vence o caminho mais curto e, depois, o caminho em ordem de unidades de
código, para que a mesma árvore sempre indique a mesma cópia.
Ele não exclui nada seu, com uma exceção. trash_local move arquivos
para um diretório .shieldfive-mcp-trash no mesmo volume em que estão e
grava um manifest.json registrando onde cada um estava. Nenhum espaço em disco é liberado
até que você exclua esse diretório você mesmo, no seu próprio gerenciador de arquivos, com
seu próprio desfazer. A ferramenta diz isso em sua própria saída para que o assistente não
possa relatar o espaço como recuperado. A exceção é um move_local entre volumes, que
precisa copiar: sua origem é removida, mas somente após a cópia ter sido verificada — veja
Movendo entre volumes.
Isso vale também para sobrescrita. move_local com overwrite: true move o
item já no destino para a lixeira e então ocupa seu lugar; ele não
o remove. A pré-visualização informa quantos arquivos e quantos bytes seriam
deslocados, não apenas quantos estão sendo movidos. Se a movimentação falhar, o
item deslocado é colocado de volta.
Toda ferramenta que altera algo não faz nada por padrão. Chame-a sem
confirm: true e ela resolve os caminhos, verifica a contenção, relata exatamente
o que faria e para. A pré-visualização executa as mesmas verificações que a ação,
então um plano que relata uma recusa é uma recusa.
E uma chamada confirmada tem que ser o plano que você viu. A pré-visualização retorna um
plan_token; confirm: true sem ele é recusada. A chamada confirmada planeja
novamente a partir do sistema de arquivos como ele está agora, compara esse plano com o que o
token aprovou — os caminhos, o que cada entrada é, seu tamanho e horário de modificação,
e as contagens de arquivos e bytes abaixo dele — e recusa se algo diferir,
nomeando o que mudou. Um token realiza uma alteração e expira após dez minutos.
Então um diretório que cresceu, um destino que apareceu ou um caminho que agora aponta
para um arquivo diferente interrompe a chamada em vez de silenciosamente ampliá-la.
Ferramentas locais
| Ferramenta | Lê | Grava |
|---|---|---|
list_local | arquivos, tamanhos, datas | — |
find_duplicates | conteúdos de arquivos (SHA-256) | — |
find_large_files | tamanhos | — |
find_old_files | horários de modificação | — |
storage_summary | tamanhos, por extensão e diretório | — |
move_local | tamanhos da origem e de qualquer coisa que deslocaria | move um arquivo, pasta ou symlink; move um destino deslocado para a lixeira; entre volumes, copia, verifica e então remove a origem |
rename_local | — | renomeia no lugar, nunca sobre um nome existente |
create_local_folder | — | cria um diretório |
trash_local | tamanhos da subárvore sendo enviada à lixeira | move para o diretório de lixeira no volume do próprio item, grava um manifesto |
Padrões, todos substituíveis por chamada: list_local retorna 200 linhas, as outras
listagens 100. find_large_files começa em min_bytes 100.000.000 (100 MB).
find_old_files em older_than_days 365. find_duplicates pula arquivos vazios
(min_bytes 1), calcula hash de no máximo max_files_hashed 20.000 deles e retorna
100 grupos, cada um listando no máximo 50 de suas cópias. storage_summary relata as
15 principais extensões e os 15 principais diretórios. Cada varredura para em max_files
200.000 arquivos em todas as raízes e percorre a raiz e 64 níveis de
subdiretórios abaixo dela.
Cada substituição tem um teto, imposto pelo esquema MCP e novamente pela própria
ferramenta: limit 10.000 linhas, max_files 1.000.000, max_files_hashed
1.000.000, paths 1.000 por chamada de trash_local, 4.096 caracteres para um caminho e
255 bytes para new_name. Uma recusa cita apenas o início de um valor que era
longo demais.
find_old_files relata o horário de modificação, que é um sinal fraco: algumas operações
de cópia o redefinem para a data da cópia, e um arquivo intocado não é um arquivo
indesejado. A ferramenta diz isso em seu próprio resultado, em vez de deixar o assistente
apresentar uma lista curta como veredito.
A varredura não é exaustiva
Toda ferramenta de leitura percorre da mesma forma e pula coisas por padrão:
- Entradas ocultas, a menos que você passe
include_hidden: true. - Dezenove diretórios de build e cache por nome, onde quer que apareçam:
node_modules,.git,.svn,.hg,.cache,.venv,venv,__pycache__,.next,.turbo,dist,build,target,Pods,.gradle,.tox,.mypy_cache,.pytest_cachee a própria lixeira deste servidor.build,distetargetsão nomes de pastas comuns fora de uma árvore de código, então isso pode excluir dados reais — não há como substituir a lista ainda. - Symlinks, sempre, sem substituição.
Todos os três são contados e relatados nos avisos do resultado, então um total que
parece pequeno demais diz o porquê. Ainda assim, isso significa que storage_summary não é uma
ferramenta de uso de disco: aponte-a para o diretório pessoal de um desenvolvedor e ela
dirá isso, mas não dirá para onde o espaço foi.
Quando o orçamento de max_files acaba antes de todas as raízes terem sido percorridas, o
resultado lista as raízes que percorreu sob scanned e as outras sob
not_scanned, e seu aviso as nomeia.
Esvaziando a lixeira
Este servidor não faz isso e não pode. trash_local move cada item para
.shieldfive-mcp-trash/<batch>/ no diretório mais alto, entre o item e
sua raiz, que esteja no volume do próprio item: a própria raiz, a menos que o item esteja
em uma unidade montada dentro da raiz, e então o diretório superior dessa unidade.
<batch> é um carimbo de data/hora, um id de processo e um contador, então duas chamadas não compartilham um.
O manifest.json ao lado dos itens é gravado antes que qualquer um deles se mova e
lista de onde cada um veio; uma entrada cujo trashed_to não existe foi
planejada, mas não movida. Removê-los de verdade é um rm -rf que você executa você mesmo,
depois de olhar o que está lá. Nada aqui libera espaço em disco por
conta própria.
Um ponto de montagem não pode ser enviado à lixeira, porque nenhum diretório em seu próprio volume dentro
da raiz pode contê-lo. Se .shieldfive-mcp-trash for um symlink ou um arquivo,
trash_local e um move_local de sobrescrita recusam em vez de segui-lo.
Movendo entre volumes
rename(2) não pode cruzar volumes, então uma movimentação entre eles é uma cópia seguida de
remoção da origem — o único lugar onde este servidor remove algo que você criou. Isso
é feito para que uma falha em qualquer ponto não perca nada:
- A cópia é feita sob um nome oculto novo ao lado do destino
(
.shieldfive-mcp-incoming-<pid>-<n>), criado exclusivamente, e colocada no lugar sem substituir nada. Nada que já estava lá é tocado. - Uma pasta contendo um symlink, um FIFO, um socket ou um arquivo de dispositivo é recusada antes que qualquer parte dela seja removida, porque uma cópia não pode carregá-los fielmente.
- Cada arquivo é liberado para o disco e comparado com sua origem — mesmo tamanho, mesmo SHA-256 — e a origem não deve ter mudado desde que foi copiada. Se qualquer verificação falhar, a cópia é descartada e a origem permanece.
- A origem é removida arquivo por arquivo, cada um somente se ainda for o arquivo que foi
copiado, e pastas somente quando estiverem vazias. Qualquer coisa que mudou ou
apareceu durante a movimentação é deixada onde está e listada em
source_left_in_place.
Uma falha no meio pode deixar uma cópia parcial sob esse nome oculto. A origem está intacta até que sua cópia esteja no lugar.
Cancelamento
Uma solicitação cancelada não inicia nenhuma alteração. trash_local para entre itens, nunca
dentro de um, então cada item é movido e registrado ou intocado, e o
erro diz qual. Um move_local cancelado antes de sua origem começar a ser
removida é desfeito, incluindo colocar de volta qualquer coisa que deslocou; depois
desse ponto, ele termina, porque parar deixaria metade de uma árvore de cada lado. O
SDK MCP não envia resposta a uma solicitação cancelada, então o que uma chamada cancelada fez
é gravado no log de stderr do servidor e, para a lixeira, no manifesto.
Como a contenção funciona
Todo caminho que um assistente fornece é usado exatamente como dado, então "report " é
nunca "report", e resolvido com realpath — seguindo cada symlink — antes
que qualquer coisa o leia ou grave através dele. O resultado deve estar dentro de uma raiz
configurada. Uma verificação de limite ciente de separadores significa que /data/roots-evil não corresponde
à raiz /data/root.
Essa ordem é o ponto. Uma verificação de string no caminho fornecido é derrotada por
..; uma verificação após path.resolve ainda é derrotada por um symlink, porque
/allowed/link -> /etc resolve para uma string sob /allowed enquanto lê
/etc. Resolver links primeiro fecha ambos, e é por isso que a varredura de diretórios usa
lstat e nunca segue um link — um link que a varredura atravessasse seria um caminho
que a contenção nunca viu.
Destinos que ainda não existem — um alvo de movimentação, uma nova pasta — são verificados
resolvendo o ancestral existente mais próximo e reanexando o resto, então gravar
através de um pai com symlink é pego antes da gravação, não depois. Um
symlink cujo alvo não existe é recusado onde quer que uma gravação passe
por ele: realpath o relata exatamente como um caminho ausente, e aceitar isso
ao pé da letra deixaria uma cópia pousar onde quer que o link aponte.
A única coisa não seguida é o item sobre o qual uma ferramenta de mutação age. Um symlink dado
a move_local, rename_local ou trash_local é movido, renomeado ou enviado à lixeira
ele mesmo, do jeito que mv o trata, e o que ele aponta não é tocado; apenas a
própria posição do link precisa estar dentro de uma raiz. O mesmo vale para o destino
de uma movimentação: um symlink lá, pendente ou não, é uma entrada existente que
overwrite: true moveria para a lixeira, não uma pasta para mover para dentro. Dê o
caminho real da pasta para isso.
rename_local e move_local não substituem algo que aparece no
destino depois que o verificaram. Um arquivo é hard-linkado ao seu novo nome
e só então desvinculado do antigo, um symlink é recriado e uma pasta é
renomeada sobre um espaço reservado vazio feito um momento antes, então algo aparecendo
no meio faz a operação falhar em vez de ser sobrescrito. Onde não há
tal operação — FIFOs, sockets e arquivos de dispositivo, sistemas de arquivos sem hard
links como FAT e exFAT, e pastas no Windows — a ferramenta verifica e então
renomeia, e um arquivo criado naquele instante seria substituído.
O que os testes afirmam
npm test executa 225 testes. Os que valem a pena conhecer:
- Um symlink apontando para fora de uma raiz é recusado, tanto no lado de leitura quanto no de escrita, e o mesmo ocorre com um symlink quebrado em um caminho de escrita.
- Um
.shieldfive-mcp-trashque é um symlink para fora da raiz é recusado, e nada é gravado através dele. - Dois arquivos com o mesmo nome e o mesmo tamanho, mas com conteúdos diferentes, não são reportados como duplicados, e dois nomes para um mesmo arquivo não são contados como espaço a ser recuperado.
trash_localdeixa os bytes legíveis em seu novo local, no mesmo volume, e reportaspace_freed_bytes: 0.- Em um disco RAM montado dentro de uma raiz, uma movimentação entre volumes mantém uma origem cuja cópia chega corrompida ou que muda enquanto é copiada, deixa um arquivo existente em seu antigo nome de estadiamento intacto, recusa uma pasta contendo um FIFO, e nunca grava através de um symlink quebrado. Esses testes rodam no macOS e são ignorados em outros lugares.
- Um arquivo que aparece com o novo nome entre a verificação e a renomeação não é substituído.
- Uma solicitação cancelada não move nada, e um lote de lixeira cancelado no meio diz exatamente o que moveu.
- Somente
src/vault/api.mjschamafetch, e somente para uma origem https ShieldFive. Nenhum módulo de ferramenta local importa algo da metade do cofre, e as únicas variáveis de ambiente lidas sãoSHIELDFIVE_MCP_ROOTS,SHIELDFIVE_GRANTeSHIELDFIVE_API_URL. - A transferência para o navegador é o único socket de entrada e o único subprocesso no
pacote:
src/vault/connect.mjsvincula uma porta aleatória em127.0.0.1, não abre nenhuma conexão própria e inicia o navegador com um comando fixo e sem shell. Uma entrega de outra origem, com outro estado, para outroHost, por outro método, ou após a primeira, é recusada. - Os módulos do cofre não importam nenhum módulo de sistema de arquivos, então dados descriptografados não podem ser
gravados em disco. Nenhum módulo usa cifra, HMAC ou KDF próprios. Toda a
criptografia vem de
@shieldfive/crypto. - Contra um ShieldFive em memória que serve ciphertext real em todos os três formatos
de cofre, por meio de um cliente MCP real:
- os arquivos são descriptografados somente pelas chaves da concessão, e nada fora do escopo é listado, lido ou mesmo solicitado;
- uma conexão revogada ou expirada falha na chamada seguinte;
- renomeações e movimentações re-selam nomes e chaves para que as próprias chaves do proprietário ainda os abram;
- o segredo e o token da concessão nunca aparecem em nenhum corpo ou caminho de solicitação.
- Um arquivo cujo conteúdo diz ao assistente para jogar tudo fora volta dentro de uma cerca que ele não consegue fechar. Lê-lo emite apenas leituras, e uma chamada de lixeira com 51 itens é recusada.
- Um cliente MCP real sobre um transporte stdio real vê exatamente as nove ferramentas locais quando nenhuma conexão está configurada, inclusive quando o servidor é iniciado por meio de um symlink da forma como o npm o instala.
A afirmação de rede tem um limite que vale a pena declarar: ela prova o que src/ faz,
não o que a árvore de dependências poderia fazer. @modelcontextprotocol/sdk inclui transportes HTTP
para servidores de outras pessoas. O que fecha essa lacuna é que
server.mjs importa o transporte stdio e nenhum HTTP, o que também é
afirmado.
Limites
- A verificação do plano reduz a lacuna entre pré-visualização e ação; ela não a fecha. A comparação acontece dentro da chamada confirmada, então uma mudança que chega entre essa verificação e a própria gravação ainda é possível. Cada ferramenta re-verifica seu próprio destino imediatamente antes de gravar, o que é o que torna essa janela pequena em vez de ausente, e nenhuma ferramenta baseada em caminho pode fazer melhor.
- Um plano vincula o que nomeou. Para um diretório, isso é a entrada em si mais as contagens de arquivos e bytes abaixo dela — suficiente para detectar conteúdo aparecendo, desaparecendo ou mudando de tamanho, mas não um arquivo editado no local para exatamente o mesmo comprimento dentro do mesmo segundo.
- Os tamanhos são tamanhos de conteúdo de arquivo. Eles excluem a sobrecarga de diretório e ignoram
compressão do sistema de arquivos, arquivos esparsos, hardlinks e clones APFS, então os totais não
corresponderão exatamente a um utilitário de disco;
storage_summaryconta cada nome de um arquivo com hardlink. - Clones APFS parecem cópias.
find_duplicatesos reporta como recuperáveis, e jogar um deles na lixeira libera pouco ou nada. - As varreduras são limitadas por padrão a 200.000 arquivos, e na raiz e 64 níveis de subdiretórios abaixo dela. Quando um limite é atingido, o resultado diz isso, tanto na linha de resumo quanto em um campo: uma varredura que parou em um limite, caso contrário, lê exatamente como uma que terminou, e o assistente reporta uma lista parcial como se fosse a totalidade dela.
- O comportamento entre volumes é testado somente no macOS, contra um disco RAM que os testes montam dentro de seu próprio diretório temporário.
- O Windows não é testado. O código não usa nenhuma API exclusiva do POSIX, e o tratamento de caminhos
passa por
node:path, mas ninguém o executou lá.
SECURITY.md carrega o restante: tempo de verificação/tempo de uso, as janelas nas quais uma renomeação ainda pode substituir algo, hardlinks, o que herdar o ambiente significa e não significa, e o que a afirmação de sem rede cobre.
Política de Privacidade
Este servidor não envia nada para lugar nenhum, a menos que uma conexão ShieldFive esteja
configurada, e então somente para a API da ShieldFive (https://shieldfive.com, ou a
origem em SHIELDFIVE_API_URL):
- O que envia: solicitações que as ferramentas do cofre precisam — listagens, leituras e alterações por id, e para uploads o ciphertext e as chaves embrulhadas que produziu nesta máquina. Nomes e conteúdos de arquivos são criptografados antes de sair; um upload de armazenamento vai direto para uma URL de armazenamento pré-assinada e nunca carrega a credencial da conexão.
- O que nunca envia: nomes ou conteúdos em texto puro, caminhos locais, qualquer coisa sobre suas pastas locais, telemetria ou análises. As ferramentas locais não fazem nenhuma solicitação de rede.
- O que a ShieldFive mantém: um registro da conexão e de cada solicitação que ela faz (ids, ação, resultado, hora — sem nomes, conteúdos, endereço IP ou agente de usuário), mantido enquanto sua conta existir e excluído com ela. A Seção 3.9 da Política de Privacidade da ShieldFive cobre esses registros, sua retenção e seus direitos sobre eles.
- O que seu assistente recebe: tudo o que ele lê por meio deste servidor, descriptografado aqui, vai para quem executa o assistente, sob os termos deles — como qualquer outra coisa nessa conversa.
- Credencial: mantida no chaveiro do sistema operacional (ou
SHIELDFIVE_GRANT), nunca registrada, retornada ou gravada em um arquivo.
Contato: support@shieldfive.com, ou security@shieldfive.com para vulnerabilidades.
Segurança
Reporte vulnerabilidades para security@shieldfive.com. Veja
SECURITY.md.
Licença
MIT. Versões até e incluindo 0.6.3 foram publicadas sob Apache-2.0.