Skip to main content
Glama
HenriquePvAr

RAMPAP Productivity

by HenriquePvAr
README.md
# RAMPAP Productivity

**Versão 2.4.0** · Autor: **Henrique Paiva Araujo**

Assistente local de produtividade para Outlook (email + calendário) no
Claude Desktop/Cowork — **zero configuração**, detecta e usa
automaticamente o Outlook Clássico instalado no computador. Além de ler/
organizar email, o RAMPAP compõe, responde, encaminha, categoriza,
sinaliza e gerencia anexos (v2.3.0), e cria/edita/cancela eventos e
reuniões, além de responder convites (v2.4.0) — sempre com confirmação
humana antes de qualquer envio real. O identificador interno do pacote
(`.mcpb`, `package.json`) continua `rampap-file-manager` por
compatibilidade — o nome público é RAMPAP Productivity.

**Princípio de design**: o Claude já tem um conector Microsoft 365 nativo
para ler/buscar email e consultar calendário/disponibilidade — o RAMPAP
não duplica isso. Ele foca no que esse conector não faz: compor, enviar,
categorizar, sinalizar, anexos (email) e criar/editar/cancelar eventos e
reuniões, responder convites (calendário) — ver
[Módulo Outlook](#16-módulo-outlook).

Um módulo de gerenciamento de arquivos locais também existe no código
(intacto, testado), mas fica **desativado por padrão** nesta versão — o
foco do produto passou a ser Outlook/Email. Nenhuma das duas capacidades dá
acesso a terminal, PowerShell ou CMD arbitrário — veja [Segurança](#2-segurança).

## Índice

1. [O que é](#1-o-que-é)
2. [Segurança](#2-segurança)
3. [Pastas que o Claude pode acessar](#3-pastas-que-o-claude-pode-acessar)
4. [Ferramentas de arquivos](#4-ferramentas-tools-disponíveis)
5. [Instalar dependências](#5-instalar-dependências) · [Compilar](#6-compilar) · [Testes](#7-rodar-os-testes)
6. [Gerar e instalar o `.mcpb`](#9-gerar-o-pacote-mcpb)
7. [Como o Claude explica as ações](#14-como-o-claude-explica-as-ações)
8. [Liberar pastas pelo chat](#15-como-liberar-ou-remover-uma-pasta-pelo-chat)
9. [Módulo Outlook](#16-módulo-outlook) — providers, **Outlook Resource Resolver**, leitura completa de email, busca local, tools
10. [Como funciona (diagramas)](#17-como-funciona)
11. [Limitações conhecidas](#18-limitações-conhecidas) · [Roadmap](#19-roadmap)

Documentação técnica complementar: [ARCHITECTURE.md](docs/ARCHITECTURE.md) ·
[SECURITY.md](docs/SECURITY.md) · [TOOLS.md](docs/TOOLS.md) ·
[OUTLOOK_LOCAL.md](docs/OUTLOOK_LOCAL.md) ·
[TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md) ·
[TESTING.md](docs/TESTING.md) · [CHANGELOG.md](CHANGELOG.md)

## 1. O que é

Um servidor MCP que roda localmente (via stdio) e expõe **40 ferramentas**
por padrão, todas de Outlook (`src/outlook/`) — funciona se o Outlook
Clássico estiver instalado, sem nenhuma configuração. O módulo de arquivos
(13 tools, `src/tools/`) continua implementado e testado, mas fica
desativado por padrão nesta versão (`RAMPAP_FILE_MANAGER_ENABLED=1`
reativa — ver seção 4). Não existe nenhuma ferramenta de "executar comando"; todas
as operações são chamadas de API (sistema de arquivos, Outlook Object Model
local, ou Microsoft Graph), individualmente validadas. Antes de qualquer
ação que altere algo, o Claude explica o que vai fazer em português simples
— veja a seção [14. Como o Claude explica as ações](#14-como-o-claude-explica-as-ações).
Se o Claude precisar de uma pasta de arquivos ainda não liberada, ele pede
sua autorização direto na conversa — veja a seção
[15. Como liberar (ou remover) uma pasta pelo chat](#15-como-liberar-ou-remover-uma-pasta-pelo-chat).

## 2. Segurança

- **Lista branca de pastas** (`ALLOWED_ROOTS`): todo caminho passa por
  [`src/security/paths.ts`](src/security/paths.ts) antes de qualquer
  operação. A validação:
  - resolve o caminho absoluto;
  - sobe até o ancestral existente mais próximo e aplica `realpath` nele
    (protege contra symlink/junction apontando para fora do escopo);
  - recusa caminhos UNC (`\\servidor\...`);
  - compara contra as raízes permitidas de forma case-insensitive (como o
    Windows) e nunca permite `..` escapar do escopo.
- **Nenhum shell**: não existe `run_command`, `exec`, `child_process.exec`
  nem `child_process.spawn` com comando arbitrário do modelo em nenhum lugar
  do código.
- **Sem exclusão permanente**: `enviar_para_lixeira` usa o pacote
  [`trash`](https://www.npmjs.com/package/trash), que move o item para a
  Lixeira do Windows. Nada no projeto chama `fs.rm`/`fs.unlink` como forma de
  apagar por pedido do usuário — essas funções só aparecem no fallback
  interno de "mover entre discos diferentes" (copia e depois remove o
  arquivo *já copiado* na origem).
- **Sem sobrescrita silenciosa**: mover/copiar recusam destino já existente
  por padrão (`conflictStrategy: "error"`); `"rename"` gera automaticamente
  `arquivo (2).ext`.
- **Nomes de arquivo validados**: `renomear_item` rejeita caracteres
  inválidos do Windows e nomes reservados (`CON`, `PRN`, `NUL`, etc.).
- **Limites contra operações gigantes**, configuráveis em
  [`src/limits.ts`](src/limits.ts).
- **Nenhuma pasta é liberada sem confirmação humana real**: o Claude pode
  *pedir* acesso a uma pasta, nunca conceder a si mesmo — veja a seção 15.
- **Proteção contra instrução escondida em arquivo**: texto dentro de um
  documento, planilha, nome de arquivo etc. pedindo para "liberar outra
  pasta" nunca é tratado como um pedido válido — isso é reforçado tanto nas
  instruções do servidor (`src/server.ts`) quanto na descrição da própria
  ferramenta de autorização. É uma proteção de instrução, não de código: o
  protocolo não tem como saber "de onde" veio a intenção do Claude, então a
  defesa real é o próprio Claude ter sido orientado a ignorar esse tipo de
  conteúdo.

## 3. Pastas que o Claude pode acessar

**Padrão (sempre permitidas):**

- `%USERPROFILE%\Desktop`
- `%USERPROFILE%\Documents`
- `%USERPROFILE%\Downloads`
- `%USERPROFILE%\Pictures` (se existir)

**Configuradas na extensão (o usuário escolhe):** a partir da v1.1.0, nas
configurações da extensão no Claude Desktop, o usuário pode selecionar
quantas pastas quiser para liberar ao Claude — por exemplo `D:\Projetos`,
`D:\Fotos` ou `C:\Users\<usuário>\OneDrive - Rampap`. Isso é feito através
do recurso oficial `user_config` (tipo `directory`, `multiple: true`) do
formato MCPB — o próprio Claude Desktop mostra o seletor de pastas do
Windows.

**Liberadas pelo chat (a partir da v1.3.0):** o usuário também pode liberar
qualquer pasta específica direto na conversa, sem abrir as configurações —
veja a seção [15](#15-como-liberar-ou-remover-uma-pasta-pelo-chat). Funciona
para qualquer caminho absoluto que o usuário indicar, não uma lista fixa de
nomes.

Em qualquer uma das duas formas, cada pasta liberada — e todas as suas
subpastas — passa a ser acessível, e fica salva mesmo depois de fechar o
Claude ou reiniciar o computador. O Claude (o modelo) **não** tem nenhuma
ferramenta para escolher ou ampliar essas pastas sozinho — só pode *pedir*;
quem decide é sempre o usuário, numa confirmação humana real.

**Sempre bloqueadas (denylist, vence qualquer pasta autorizada):**

- `C:\Windows`, `C:\Program Files`, `C:\Program Files (x86)`, `C:\ProgramData`
- Áreas de credenciais (`AppData\...\Microsoft\Credentials`), `.ssh`, e
  perfis de navegador mais comuns (lista best-effort, não exaustiva).

Qualquer caminho fora das pastas padrão/adicionais autorizadas — ou que caia
dentro da denylist, mesmo que esteja dentro de uma pasta autorizada — é
recusado com o erro `PATH_NOT_ALLOWED`. Uma raiz adicional excessivamente
ampla (`C:\`, `D:\`, ou o próprio `C:\Users`) é sempre recusada no momento em
que o servidor inicia — nunca vira uma pasta liberada.

## 4. Ferramentas de arquivos (desativadas por padrão na v2.3.0)

> A partir da v2.3.0 o foco do produto é Outlook/Email — estas 13 tools
> continuam implementadas e testadas em `src/tools/`, mas não são
> registradas por padrão. Reative rodando o servidor com a variável de
> ambiente `RAMPAP_FILE_MANAGER_ENABLED=1` (ver `FILE_MANAGER_ENABLED` em
> `src/server.ts`) — nenhum código foi apagado.

| Tool | O que faz |
|---|---|
| `listar_arquivos` | Lista arquivos/pastas (nome, caminho, tipo, extensão, tamanho, data) |
| `buscar_arquivos` | Busca por nome/extensão, com padrão glob simples (`*.pdf`) |
| `criar_pasta` | Cria pasta (recursivamente) |
| `mover_item` | Move arquivo ou pasta |
| `copiar_item` | Copia arquivo ou pasta |
| `renomear_item` | Renomeia arquivo ou pasta |
| `obter_metadados` | Retorna metadados sem ler o conteúdo |
| `enviar_para_lixeira` | **Ação destrutiva** — envia para a Lixeira do Windows, sempre pedindo confirmação ao usuário antes |
| `organizar_arquivos` | Executa várias operações de mover em lote (até 100), com relatório item a item |
| `listar_pastas_permitidas` | Somente leitura — mostra quais pastas (padrão + adicionais) o Claude pode acessar agora |
| `preparar_acao` | Somente leitura — pré-visualiza (sem alterar nada) o que uma ação faria e gera a explicação em português que o Claude mostra ao usuário antes de executar |
| `solicitar_acesso_pasta` | Pede autorização humana real (numa janela separada) para liberar uma pasta ainda não disponível. Chamar esta ferramenta nunca concede acesso sozinha |
| `solicitar_remocao_acesso_pasta` | Remove uma pasta liberada pelo chat, também com confirmação humana |

## 5. Instalar dependências

Requer Node.js 20+ (testado com Node 24) e npm.

```bash
npm install
```

## 6. Compilar

```bash
npm run build
```

## 7. Rodar os testes

Os testes usam uma pasta temporária isolada (nunca tocam nos seus arquivos
reais).

```bash
npm test
```

## 8. Usar o MCP Inspector

```bash
npm run inspector
```

Isso compila o projeto e abre o [MCP Inspector](https://github.com/modelcontextprotocol/inspector)
apontando para `dist/index.js`, permitindo testar cada tool manualmente.

## 9. Gerar o pacote `.mcpb`

```bash
npm run pack
```

Gera `rampap-file-manager-2.4.0.mcpb` na raiz do projeto. Esse comando builda
o projeto e empacota `manifest.json` + `dist/` + `node_modules` (dependências
de produção) no formato MCPB (Claude Desktop Extension).

> Observação: para o pacote final incluir só dependências de produção
> (menor e mais limpo), rode `npm prune --omit=dev` antes de empacotar e
> `npm install` depois para restaurar as ferramentas de desenvolvimento.

## 10. Instalar no Claude Desktop

1. Abra o Claude Desktop.
2. Vá em **Settings → Extensions** (ou **Configurações → Extensões**).
3. Clique em **Install Extension** / **Instalar do arquivo** e selecione o
   arquivo `rampap-file-manager-2.4.0.mcpb`.
4. Confirme a instalação. O Claude reconhecerá automaticamente as 40 tools
   de Outlook, sem nenhuma configuração se o Outlook Clássico estiver
   instalado no computador (veja a seção 16) — a tela de configurações da
   extensão nem aparece com campos para preencher nesta versão.
5. **Opcional — liberar pastas adicionais:** ainda em **Settings →
   Extensions → RAMPAP File Manager**, abra as configurações da extensão e,
   em "Pastas adicionais permitidas", clique em **+ Adicionar pasta** para
   escolher (pelo seletor nativo do Windows) quantas pastas quiser — ex.:
   `D:\Projetos`, `D:\Fotos`, `C:\Users\<usuário>\OneDrive - Rampap`.
6. Para **alterar depois**: volte na mesma tela de configurações, adicione
   ou remova pastas da lista e salve — o Claude Desktop reinicia o servidor
   MCP automaticamente com a nova lista.
7. Para **conferir o que está liberado**, peça ao Claude para usar a tool
   `listar_pastas_permitidas`, ou pergunte algo como "quais pastas você
   consegue acessar?".

## 11. Como remover

Em **Settings → Extensions**, encontre "RAMPAP File Manager" e clique em
**Remove/Uninstall**. Isso apaga a extensão e para o processo do servidor
MCP; nenhum arquivo do usuário é afetado.

## 12. Como alterar `ALLOWED_ROOTS`

Existem duas camadas, ambas em [`src/security/paths.ts`](src/security/paths.ts):

- **Pastas padrão** (sempre permitidas, sem o usuário precisar configurar
  nada): constantes `ALWAYS_ROOT_NAMES` e `OPTIONAL_ROOT_NAMES`. Para
  adicionar outra pasta padrão (ex.: `Videos`), edite:
  ```ts
  const OPTIONAL_ROOT_NAMES = ["Pictures", "Videos"] as const;
  ```
  e rode `npm run build` novamente.
- **Pastas adicionais** (escolhidas pelo usuário): não exigem editar código
  — são configuradas pela própria extensão (`user_config.allowed_directories`
  no `manifest.json`, repassadas ao servidor como argumentos de linha de
  comando). Para mudar a denylist (`GLOBAL_DENIED_PATHS`), edite a função
  `computeDeniedPaths()` no mesmo arquivo.

Não é necessário alterar nenhuma outra parte do código — toda tool usa
`assertAllowedPath`, que lê essas listas.

## 13. Distribuição em ambiente Enterprise

- O `.mcpb` gerado é um arquivo único que pode ser distribuído por rede
  interna, GPO de arquivo, ou portal de auto-atendimento de TI.
- O manifest usa `os.homedir()` / `%USERPROFILE%` internamente — funciona
  automaticamente para qualquer usuário (`C:\Users\joao`, `C:\Users\maria`,
  etc.) sem precisar recompilar por máquina.
- Para assinar o pacote (recomendado em ambiente corporativo, para que o
  Claude Desktop confie na origem), use:
  ```bash
  npx @anthropic-ai/mcpb sign rampap-file-manager-2.4.0.mcpb --cert <certificado> --key <chave>
  ```
  (requer um certificado de assinatura de código válido da RAMPAP; não
  incluído neste projeto).
- Os logs de operação ficam em
  `%LOCALAPPDATA%\RAMPAP\FileManager\logs\` em cada máquina, um arquivo por
  dia, formato JSON lines — úteis para auditoria de TI sem expor conteúdo
  de documentos.

## 14. Como o Claude explica as ações

A partir da v1.2.0, antes de qualquer ação que altere arquivos, o Claude
explica o que vai fazer em português simples — sem jargão técnico (nada de
"filesystem", "syscall", "JSON-RPC") e sem citar o nome interno da
ferramenta (o usuário nunca vê "vou executar mover_item", só "vou mover
este arquivo"). Isso é feito de duas formas combinadas:

1. As **descrições de cada ferramenta** (lidas pelo modelo, não pelo
   usuário) instruem explicitamente o Claude a explicar antes de agir.
2. A ferramenta somente leitura **`preparar_acao`** valida a operação e
   monta a explicação sem alterar nada no disco — o Claude pode chamá-la
   antes de `mover_item`, `copiar_item`, etc., para montar a frase certa.

> Isso é orientação de comportamento para o modelo, não uma garantia
> imposta pelo protocolo MCP — o servidor não consegue obrigar 100% das
> vezes que a interface mostre a frase antes de agir. Descrições fortes +
> `preparar_acao` são a forma recomendada de conseguir esse comportamento
> de forma consistente.

**Mover:**

> Vou mover "relatorio.xlsx" de Downloads para Documents\Relatorios.
> O arquivo continuará existindo, apenas mudará de pasta.
>
> *(depois de executar)* Concluído. O arquivo foi movido com sucesso.

**Copiar:**

> Vou copiar "contrato.pdf" para Documents\Contratos. O arquivo original
> em Downloads será mantido.

**Renomear:**

> Vou renomear "IMG001.jpg" para "Fachada-OCA.jpg". O conteúdo do arquivo
> não será alterado.

**Criar pasta:**

> Vou criar a pasta "Contratos" dentro de Documents.

**Organizar (lote):**

> Vou organizar 34 arquivos:
> • 12 PDFs → Documentos\PDF
> • 8 planilhas → Documentos\Planilhas
> • 10 imagens → Pictures
> • 4 arquivos ZIP → Downloads\Compactados
>
> Nenhum arquivo será excluído.

**Lixeira (sempre pede confirmação):**

> Vou enviar os seguintes arquivos para a Lixeira:
> • arquivo1.pdf
> • arquivo2.pdf
>
> Eles poderão ser recuperados depois pela Lixeira do Windows. Deseja continuar?

**Conflito de nome (nunca sobrescreve silenciosamente):**

> Já existe um arquivo chamado "Relatorio.xlsx" no destino. Posso manter o
> arquivo existente ou criar uma cópia com outro nome. Nenhum arquivo será
> sobrescrito sem sua autorização.

## 15. Como liberar (ou remover) uma pasta pelo chat

A partir da v1.3.0, o usuário não precisa abrir as configurações da extensão
para liberar uma pasta nova — basta pedir na própria conversa.

**Exemplo — liberar:**

> **Você:** `D:\Projetos organize essa pasta`
>
> **Claude:** Essa pasta ainda não está disponível para mim. Como você pediu
> para eu trabalhar nela, vou solicitar sua autorização.
>
> *(abre uma janela de confirmação, separada do chat — veja abaixo)*
>
> **Claude:** Pronto! Agora posso trabalhar em "Projetos". Encontrei 126
> arquivos. Vou organizar assim: imagens → Fotos, vídeos → Vídeos, arquivos
> compactados → Compactados. Nenhum arquivo será apagado.

Repare que o Claude **continua automaticamente** a tarefa original assim que
a pasta é liberada — não é preciso pedir de novo.

**Exemplo — remover:**

> **Você:** `não use mais a pasta D:\Projetos`
>
> **Claude:** Vou remover o acesso à pasta "Projetos". Depois disso não
> poderei mais organizar arquivos nela até que você autorize novamente.
> Deseja continuar?
>
> *(confirmação)* → **Claude:** Pronto! Removi o acesso a "Projetos".

**O que nunca é liberado, mesmo se pedido:** uma unidade inteira (`C:\`,
`D:\`, ...), o "container" de todos os perfis de usuário (equivalente a
`C:\Users`), ou qualquer área protegida do Windows (`C:\Windows`,
`C:\Windows\System32`, `Program Files`, `ProgramData`, credenciais, `.ssh`).
Nesses casos o Claude explica isso e nem chega a abrir uma janela de
confirmação.

**Liberar uma pasta não autoriza excluir nada nela.** Enviar arquivos para
a Lixeira continua sendo uma confirmação separada, sempre pedida na hora —
autorizar o acesso a uma pasta e autorizar apagar arquivos dela são duas
decisões diferentes.

### Como a confirmação funciona por baixo dos panos

O servidor tenta, nesta ordem:

1. **`elicitation`** — mecanismo oficial do protocolo MCP: o servidor pede
   ao *cliente* (o app Claude) para perguntar ao usuário; quem desenha a
   tela é o próprio Claude Desktop. Usado automaticamente quando o cliente
   conectado anuncia suporte a isso.
2. **Janela nativa do Windows** — se o cliente não anunciar suporte a
   `elicitation`, o próprio RAMPAP File Manager abre uma janela simples
   (`MessageBox` do Windows) com o nome da pasta, o caminho completo, e os
   botões Sim/Não. Essa janela pertence exclusivamente à extensão: o texto
   mostrado é fixo, o caminho da pasta chega só por variável de ambiente
   (nunca é interpretado como comando), e não existe nenhuma forma de
   passar comandos arbitrários por ali — não é um terminal.

Em nenhum dos dois casos o simples fato de o Claude *chamar* a ferramenta de
autorização concede acesso — só a resposta humana na janela decide isso.

> **Sobre suporte do Claude Desktop:** `elicitation` é um recurso oficial do
> protocolo MCP (confirmado no SDK atual, `@modelcontextprotocol/sdk@1.30.0`).
> Não foi possível confirmar, neste ambiente de desenvolvimento, se a versão
> atual do aplicativo Claude Desktop já renderiza esse tipo de pergunta — por
> isso a janela nativa do Windows existe como plano B automático. Teste na
> sua instalação real do Claude Desktop para saber qual dos dois caminhos
> está sendo usado (aparece nos logs — veja a seção [13](#13-distribuição-em-ambiente-enterprise)).

### Onde fica salvo

As pastas liberadas pelo chat ficam em
`%LOCALAPPDATA%\RAMPAP\FileManager\allowed-folders.json`, e continuam
liberadas mesmo depois de fechar o Claude, reiniciar o computador, etc. Se
esse arquivo for apagado ou ficar corrompido, o RAMPAP File Manager nunca
"libera tudo" por segurança — ele simplesmente volta a não ter nenhuma pasta
liberada pelo chat (as pastas padrão e as configuradas na extensão continuam
normais), e basta pedir de novo.

## 16. Módulo Outlook

A partir da v2.0.0, o RAMPAP File Manager tem um módulo **opcional e
independente** para o Outlook do usuário (`src/outlook/`, sem misturar
código com o módulo de arquivos, `src/tools/` + `src/security/`).

**O que o Claude pode fazer:** listar e buscar emails (sem baixar o corpo
completo), listar/criar pastas de email, mover e arquivar emails (um a um
ou em lote), enviar emails para Itens Excluídos (sempre com confirmação —
nunca exclusão permanente), criar/listar/ativar/desativar/excluir regras
automáticas da Caixa de Entrada, e listar/selecionar qual conta usar quando
há mais de uma.

**O que ele nunca faz:** enviar, responder ou encaminhar email
(`Mail.Send` não é usado, de propósito — é um módulo futuro separado),
excluir email/regra sem confirmação, ou acessar caixa de email de outra
pessoa (só a conta do próprio usuário).

### Dois modos — arquitetura de providers (v2.1.0)

Desde a v2.1.0, o Outlook funciona de duas formas, escolhidas
automaticamente (`src/outlook/providers/provider-manager.ts`), sem que
nenhuma tool precise saber qual está em uso — as duas implementam o mesmo
contrato (`src/outlook/providers/types.ts`):

1. **Local** (`src/outlook/local/`) — fala diretamente com o Outlook
   Clássico instalado no computador, via a Outlook Object Model (COM). **Não
   precisa de Tenant ID, Client ID, App Registration nem login algum** —
   se o Outlook já está instalado e configurado, funciona na hora.
2. **Microsoft 365 / Graph** (`src/outlook/graph/`, o módulo original da
   v2.0.0, inalterado) — usado quando o Outlook Clássico não está
   disponível (Novo Outlook, Outlook Web, ou o computador não tem Outlook
   instalado), via MSAL + Microsoft Graph.

**Desde a v2.2.1, a tela de configurações da extensão só mostra "Pastas
adicionais permitidas"** — nenhum campo de Outlook aparece mais ali. O
comportamento passou a ser **local-first automático, sem nada para
configurar**: local se disponível, senão o Claude segue a política de
fallback de navegador (próxima seção) — o Microsoft 365/Graph nunca entra
sozinho. Graph continua existindo no código como provider avançado/opcional
(ver `docs/OUTLOOK_ENTRA_SETUP.md`), só que agora só é alcançável por quem
editar manualmente os argumentos do servidor — não é mais algo que o
usuário comum vê ou precisa entender.

### Como o Outlook Clássico é acessado (sem Graph)

`src/outlook/local/bridge/script.ts` é um script PowerShell **fixo**,
embutido no código — o Claude nunca vê nem gera esse script, só chama tools
de alto nível. Ele fala com o Outlook via `New-Object -ComObject
Outlook.Application` (a forma documentada pela Microsoft para automação do
Outlook Clássico) e só entende um conjunto fechado de ações (listar,
buscar, mover, criar pasta, regras...), cada uma com parâmetros
estruturados recebidos em JSON — nunca texto livre, nunca
`Invoke-Expression`. Cada chamada roda em um `powershell.exe` novo (mais
simples do que manter um processo COM de longa duração dentro do Node, que
exigiria lidar com apartment/threading do próprio Outlook).

**Limitações conhecidas do modo local**, documentadas para teste manual
(`docs/OUTLOOK_LOCAL_TEST.md`): a pasta de Arquivo Morto é localizada de
forma heurística (não existe uma constante universal na Object Model); a
primeira chamada pode iniciar o Outlook em segundo plano se ele estiver
fechado. Desde a v2.2.0, busca por texto livre (`texto`) funciona nos dois
modos — veja [Outlook Resource Resolver](#outlook-resource-resolver-v220)
abaixo.

### Outlook Resource Resolver (v2.2.0)

Até a v2.1.5, pastas padrão (Caixa de Entrada, Itens Excluídos...) eram
localizadas pelo **nome visível** na árvore do Outlook — o que falhava
sempre que o nome não batia exatamente (idioma da instalação, acento,
maiúscula/minúscula). Foi assim que surgiu o bug real "`outlook_listar_emails`
com pasta 'Itens Excluídos' → `FOLDER_NOT_FOUND`", mesmo com o Outlook Local
funcionando normalmente para tudo o mais.

A partir da v2.2.0, toda tool que recebe um nome de pasta passa por um
resolvedor único (`Resolve-OutlookFolder` em `script.ts`):

1. **Alias → tipo semântico → `GetDefaultFolder`.** "Itens Excluídos",
   "Lixeira", "Deleted Items" (e variações de acento/maiúscula) mapeiam
   para o mesmo tipo semântico `DeletedItems`, resolvido via
   `Store.GetDefaultFolder(olFolderDeletedItems)` — nunca por nome. O
   mesmo vale para Caixa de Entrada, Itens Enviados, Rascunhos e Lixo
   Eletrônico, em qualquer idioma/instalação.
2. **Nome customizado → busca na hierarquia da Store já selecionada.**
   Pastas como "Anthropic" continuam localizadas por nome, mas nunca
   cruzando para a Store errada, e a busca reconhece variações de acento/
   maiúscula.
3. **Ambiguidade nunca é resolvida silenciosamente.** Se mais de uma pasta
   tiver o mesmo nome (ex.: "Arquivo" dentro de duas pastas-pai diferentes),
   a tool retorna `FOLDER_AMBIGUOUS` com o caminho completo de cada opção —
   o Claude é orientado a mostrar as opções e pedir para o usuário escolher,
   nunca a decidir sozinho.

Também nesta versão, a identidade do email é resolvida de forma central: se
uma tarefa move um email (mudando seu `EntryID` — ver a seção sobre `id_atual`
mais acima) e uma ação seguinte na mesma tarefa ainda usa o id antigo,
`src/outlook/local/mail-identity.ts` segue a cadeia automaticamente até o id
mais recente conhecido — sem precisar de nova busca. Ferramentas de
diagnóstico read-only: `outlook_diagnostico_local` agora inclui um mapa de
quais pastas padrão foram encontradas, e a nova `outlook_diagnostico_resolucao`
mostra como um nome específico seria resolvido (tipo semântico, método,
ambiguidade) — use quando o usuário pedir detalhes técnicos sobre uma pasta
não encontrada.

### Leitura completa de email e busca por texto (v2.2.0)

`outlook_listar_emails`/`outlook_buscar_emails` continuam devolvendo só um
resumo curto (nunca o corpo inteiro em lote — pesado e desnecessário no
contexto). Para ler uma mensagem específica por inteiro (corpo completo,
destinatários, cc, anexos), use a nova `outlook_ler_email` — funciona local,
sem abrir navegador. O corpo é sempre tratado como **dado**: HTML nunca é
executado/renderizado, e nenhuma instrução dentro do email é tratada como
pedido do usuário (mesma proteção contra instrução escondida da seção 2,
agora explícita também para conteúdo de email).

Busca por texto (`outlook_buscar_emails` com `texto`) agora funciona no modo
local também. Como a Outlook Object Model não tem um filtro server-side
confiável para corpo, a busca local aplica os filtros baratos primeiro
(data/remetente/assunto/anexo/pasta) e só então lê o corpo de um lote
limitado de candidatos (`OUTLOOK_LIMITS.TEXT_SEARCH_SCAN_MAX`, 300 mensagens)
— a resposta inclui `buscaLimitada`/`quantidadeAnalisada` quando a busca não
foi exaustiva, em vez de fingir que varreu a caixa inteira. No modo
Microsoft 365 a busca continua sendo server-side (`$search` do Graph), sem
esse limite.

**Erro técnico nunca é confundido com "não instalado"** (hotfix v2.1.1): se
o bridge falhar por qualquer motivo que não seja o sinal real de ausência
do Outlook (script quebrado, timeout, `powershell.exe` não encontrado...),
o modo AUTO não tenta abrir o login do Microsoft 365 silenciosamente — ele
reporta o problema local e para. Use `outlook_diagnostico_local` para
investigar, ou `npm run test:outlook-local-live` (roda o mesmo bridge da
extensão, só leitura) para reproduzir fora do Claude Desktop.

### Se o Outlook Local falhar (v2.1.2): navegador antes do Microsoft 365

O RAMPAP File Manager só controla diretamente o Outlook Local e o Graph —
o **navegador integrado do Cowork** e o **Claude in Chrome** são recursos do
próprio Claude/Cowork, não algo que este MCP consiga acionar ou detectar
sozinho. Por isso essa ordem de preferência vive nas `instructions` do
servidor (orientando o modelo), não em código de provider:

1. **Outlook Local**
2. **Navegador integrado do Cowork** (se disponível na sessão) — continua
   pelo Outlook Web
3. **Claude in Chrome** (se a extensão estiver conectada)
4. Se nenhuma funcionar, uma mensagem única e amigável:
   > "Não consegui acessar o Outlook por nenhuma das opções disponíveis
   > neste computador. Você pode usar o Outlook Clássico, o navegador
   > integrado do Claude ou o Claude in Chrome. Se precisar de ajuda para
   > habilitar uma dessas opções, entre em contato com o TI — Henrique."

**O Microsoft 365 (Graph) deixou de ser fallback automático padrão.** Se o
Outlook Local falhar, o Claude não abre `outlook_conectar` sozinho — isso
pediria um login adicional desnecessário na maioria dos casos. O Graph só
entra automaticamente se o ambiente já tiver Tenant ID/Client ID
preenchidos (sinal de configuração explícita) — do contrário continua
disponível, mas só quando o usuário pedir.

### Autenticação — decisão e por quê

O RAMPAP File Manager usa o fluxo **interativo do MSAL** (`acquireTokenInteractive`):
abre o navegador padrão do Windows para o login da Microsoft, com suporte
completo a MFA e Conditional Access — a mesma tela que o usuário já conhece.
Foi escolhido em vez do Device Code Flow porque este é um app desktop com
navegador disponível (Device Code existe para dispositivos sem tela, como
uma TV ou um CLI headless, e tem pior experiência aqui, embora também
funcione com MFA/CA). **Isso ainda não foi testado dentro do processo real
do Claude Desktop** — se abrir o navegador a partir de lá se mostrar
problemático na prática, Device Code Flow é o fallback natural a
implementar.

O token nunca é salvo em JSON puro: o cache do MSAL é criptografado com a
DPAPI do Windows (`System.Security.Cryptography.ProtectedData`, escopo do
usuário atual — o mesmo mecanismo por trás do Credential Manager do
Windows) antes de ir para o disco, via um script PowerShell fixo (não
gerado a partir de nada que venha do Claude ou do usuário — ver
[`src/outlook/auth/dpapi.ts`](src/outlook/auth/dpapi.ts)). Isso evita
depender de módulos nativos npm (`keytar`, `msal-node-extensions`), que
teriam risco real de não bater com o Node embutido no Claude Desktop em
cada máquina onde a extensão for instalada — uma troca deliberada de
"biblioteca nativa mais padrão" por "zero dependência nativa, mesma
proteção do Windows".

### Configurar

**Se o Outlook Clássico já está instalado no computador, não há nada para
configurar** — instale a extensão e o Outlook já funciona, sem Tenant ID,
sem Client ID, sem escolher "modo". Desde a v2.2.1 esses três campos nem
aparecem mais na tela de configurações; a única configuração de Outlook
visível ao usuário comum não existe — a única tela é "Pastas adicionais
permitidas" (módulo de arquivos).

**Microsoft 365/Graph (Novo Outlook, Outlook Web, ou computador sem Outlook
Clássico instalado)** continua existindo no código como provider avançado,
mas não é mais configurável pela interface normal da extensão — não há
hoje um mecanismo suportado para preencher Tenant ID/Client ID sem editar
manualmente `manifest.json`/os argumentos do servidor. Se sua organização
precisar dessa via, veja `docs/OUTLOOK_ENTRA_SETUP.md` para o App
Registration e trate como configuração avançada de TI, não como algo a
expor ao usuário final nesta versão.

### Testar

- `npm run test:outlook` — todos os testes automatizados de Outlook (local
  + Microsoft 365), 100% mockados (nunca chamam PowerShell/COM real nem o
  Graph real). `npm run test:outlook-local` / `npm run test:outlook-graph`
  rodam só um dos dois.
- [`docs/OUTLOOK_LOCAL_TEST.md`](docs/OUTLOOK_LOCAL_TEST.md) — roteiro para
  validar com um Outlook Clássico real instalado (o caminho mais simples).
- [`docs/OUTLOOK_MANUAL_TEST.md`](docs/OUTLOOK_MANUAL_TEST.md) — roteiro
  para validar numa conta Microsoft 365 de teste real, depois de configurar
  o Entra ID.

### Tools

Ver [docs/TOOLS.md](docs/TOOLS.md) para a lista completa (35 tools) com
leitura/escrita e confirmação — resumo por grupo:

| Tool | O que faz |
|---|---|
| `outlook_status` | Somente leitura — diz se está disponível, e como (local ou Microsoft 365) |
| `outlook_ler_email` | Somente leitura — lê o conteúdo completo (corpo, destinatários, cc, anexos) de UM email já identificado |
| `outlook_buscar_emails` | Busca por remetente, domínio, assunto, texto (assunto+corpo, local ou Microsoft 365), data, lido/anexo, pasta |
| `outlook_mover_email` / `outlook_mover_emails` | Move um email ou vários (lote) — inclui restaurar de Itens Excluídos |
| `outlook_enviar_para_itens_excluidos` | **Destrutiva** — sempre com confirmação; nunca exclusão permanente |
| `outlook_listar_regras` / `outlook_criar_regra` / `outlook_alterar_regra` / `outlook_ativar_regra` / `outlook_desativar_regra` / `outlook_excluir_regra` | Regras automáticas — a última é destrutiva, sempre com confirmação |
| **(novo v2.3.0)** `outlook_criar_rascunho` / `outlook_editar_rascunho` / `outlook_excluir_rascunho` / `outlook_enviar_rascunho` | Rascunho — a última **envia email de verdade**, sempre com preview e confirmação |
| **(novo v2.3.0)** `outlook_responder_email` / `outlook_encaminhar_email` | Responder (ou responder a todos)/encaminhar — **enviam email**, sempre com preview e confirmação |
| **(novo v2.3.0)** `outlook_marcar_lido` / `outlook_sinalizar_email` | Estado da mensagem (lido/não lido, follow-up) — sem confirmação |
| **(novo v2.3.0)** `outlook_listar_categorias` / `outlook_definir_categorias` / `outlook_criar_categoria` | Categorias — sem confirmação |
| **(novo v2.3.0)** `outlook_listar_anexos` / `outlook_salvar_anexo` / `outlook_anexar_arquivo_rascunho` | Anexos — nunca executa um arquivo, só lista/salva/anexa |
| **(novo v2.3.0)** `outlook_sincronizar` | Força Enviar/Receber |
| `outlook_diagnostico_local` / `outlook_diagnostico_ultima_falha` / `outlook_diagnostico_resolucao` | Diagnóstico somente leitura |
| `outlook_conectar` / `outlook_desconectar` / `outlook_listar_contas` / `outlook_selecionar_conta` / `outlook_preparar_acao` | Conexão Microsoft 365, múltiplas contas, preview |

**Desativadas por padrão** (duplicavam o conector Microsoft 365 nativo, código intacto):
`outlook_listar_emails`, `outlook_listar_pastas`, `outlook_criar_pasta`, `outlook_arquivar_email(s)` — ver [docs/TOOLS.md](docs/TOOLS.md#por-que-outlook_buscar_emailsoutlook_ler_emailoutlook_mover_emails-continuam-registradas).

## 17. Como funciona

```mermaid
flowchart TD
    U[Usuário no Claude Desktop / Cowork] --> C[Claude]
    C --> M[RAMPAP Productivity — MCP]
    M --> FM[File Manager]
    M --> OM[Outlook Manager]
    FM --> FS[Sistema de arquivos local<br/>allowlist + denylist]
    OM --> ST[outlook_status]
    ST -->|Outlook Local disponível| RR[Outlook Resource Resolver]
    RR --> COM[Outlook Clássico — COM/MAPI]
    ST -->|Local indisponível| FB[navegador integrado / Claude in Chrome]
    ST -->|configurado explicitamente| GR[Microsoft 365 / Graph]
```

```mermaid
flowchart LR
    P["Pedido: 'itens excluídos', 'lixeira',<br/>'Deleted Items', 'Anthropic'..."] --> RR[Outlook Resource Resolver]
    RR --> D{É pasta padrão<br/>por tipo semântico?}
    D -->|sim| GDF[Store.GetDefaultFolder]
    D -->|não| H[Busca por nome<br/>na Store selecionada]
    H --> A{Mais de uma<br/>pasta com o nome?}
    A -->|sim| AMB[FOLDER_AMBIGUOUS<br/>lista opções, pede confirmação]
    A -->|não, achou 1| OK[Pasta resolvida]
    A -->|não achou| NF[FOLDER_NOT_FOUND]
    GDF --> OK
```

## 18. Limitações conhecidas

- **Envio de email exige sempre confirmação humana** — não existe (e nunca vai existir) um caminho para enviar/responder/encaminhar sem o Claude mostrar o preview e o usuário confirmar explicitamente.
- **Sem exclusão permanente de email** — "excluir"/"apagar" sempre move para Itens Excluídos; não existe "esvaziar a lixeira".
- **Auto-reply/Out of Office não é suportado** — não existe uma API confiável e documentada no Object Model local para isso; possível via Microsoft Graph, não implementado nesta versão.
- **Novo Outlook não usa COM** — o modo local depende do Outlook Clássico; o Novo Outlook cai no modo Microsoft 365.
- **Conteúdo de anexo não é lido** — `outlook_listar_anexos` retorna só metadados (nome, tamanho); `outlook_salvar_anexo` salva o arquivo sem abri-lo/executá-lo.
- **Busca por texto local tem limite de leitura** (300 mensagens por chamada) — não é uma varredura exaustiva da caixa; a resposta avisa quando isso acontece.
- **Pasta de Arquivo Morto é localizada heuristicamente** (não existe uma constante universal na Object Model para ela).
- **Calendário**: editar/excluir só a série inteira de um evento recorrente (não uma ocorrência única); sem sala/recurso, calendário compartilhado ou delegado; sem link automático de reunião Teams/Zoom. Ver [docs/OUTLOOK_CALENDAR_CAPABILITIES.md](docs/OUTLOOK_CALENDAR_CAPABILITIES.md).
- **Teams e contatos** não são gerenciados nesta versão — ver Roadmap abaixo.
- **Módulo de arquivos desativado por padrão** — código intacto, reative com `RAMPAP_FILE_MANAGER_ENABLED=1`.
- **Provider Graph sem paridade nas capacidades novas** — rascunho/responder/encaminhar/categorias/anexos/sync/calendário só funcionam pelo Outlook Local nesta versão (retornam erro amigável pelo Graph, documentado, não fingido).

## 19. Roadmap

- **v2.5.0** — Teams: mensagens, canais, reuniões.

Sem datas prometidas — cada versão só avança depois da anterior estar
sólida e testada ao vivo.

TDQS

A3.9/5.0

Scored across 38 tools

Disambiguation4/5

Most tools are clearly separated by domain (files vs. Outlook) and by action type. The main confusable pairs are the singular/plural email actions (outlook_mover_email/outlook_mover_emails, outlook_arquivar_email/outlook_arquivar_emails) and the read-only file tools (listar_arquivos, buscar_arquivos, obter_metadados), though descriptions do distinguish them.

Naming Consistency4/5

Naming is generally consistent: Portuguese snake_case, verb_noun pattern, and an outlook_ prefix for all Outlook tools. Minor inconsistencies exist, such as filesystem tools lacking a shared prefix and outlook_status/outlook_diagnostico_* deviating from the verb-first style.

Tool Count2/5

With 38 tools, the server is well above the 25+ threshold and feels heavy even for a two-domain productivity tool. Many tools are near-duplicates (singular/plural variants, multiple diagnostic utilities), so the surface could be meaningfully consolidated.

Completeness3/5

File and email organization workflows are well covered with list/create/move/copy/rename/trash/batch operations, plus comprehensive Outlook rule management and diagnostics. However, common productivity actions are missing — no sending/reply emails, no file content reading or writing, and no restore-from-trash — so the surface has notable gaps for a general productivity server.

Maintenance

ActivityMaintained
ResponsivenessNo issues