FileAgent
# FileAgent
FTP para agentes: um filesystem virtual compartilhado, cada arquivo endereçado e verificado por **SHA-256**, com **metadados extraídos** no upload.
Agentes no mesmo `FILEAGENT_DATA_DIR` (stdio) ou no mesmo servidor HTTP vêem o mesmo acervo. **Nada entra ou sai sem um hash cadastrado** (`ftp_register`). Esse `access_hash` é o canal; o SHA-256 do arquivo é a prova de integridade.
## Modelo
| Conceito | O que é |
|---|---|
| **Access hash** | Credencial cadastrada com `ftp_register`. Sem ela, put/get falham. Cada hash é um canal isolado. |
| **Path** | Caminho FTP (`/inbox/nota.md`) **dentro** do access_hash. |
| **Blob** | Bytes imutáveis. Endereço = `sha256(bytes)`. Toda leitura recalcula o hash. |
| **Metadados** | Extraídos do conteúdo: mime, kind, título, idioma, headings, colunas CSV, chaves JSON, dimensões de imagem, hints de PDF. |
| **Documento** | Ponteiro mutável atrás do path. Serve checkout/commit entre agentes. |
| **CAS** | `expected_hash` no get/put. Disco adulterado → `code=tampered`. |
```
agente A FileAgent agente B
|-- ftp_register() -----------> | |
|<-- access_hash ---------------| |
|---------------- compartilha access_hash --------------------->|
|-- ftp_put(/inbox/a.md, hash) >| sha256 + metadata |
| |<-- ftp_get(/inbox/a.md, hash)-|
```
Dois agentes com o mesmo `secret` em `ftp_register` obtêm o mesmo `access_hash`.
## Ferramentas FTP
| Tool | Uso |
|---|---|
| `ftp_register` | **Cadastra** o hash. Sem isto, put/get são recusados. |
| `ftp_revoke` / `ftp_hashes` | Revoga ou lista hashes deste agente. |
| `ftp_put` | Envia. Exige `access_hash`. Grava SHA-256 + metadados. |
| `ftp_get` | Baixa. Exige o mesmo `access_hash`. Recalcula SHA-256. |
| `ftp_ls` | Lista o canal deste hash (conteúdo + metadados).
| `ftp_stat` / `ftp_meta` | Só metadados (path ou hash). |
| `ftp_verify` | Auditoria de integridade. |
| `ftp_find` | Busca por path, hash, título, kind, colunas… |
| `ftp_mkdir` / `ftp_rm` / `ftp_mv` / `ftp_cp` | Navegação estilo FTP. |
`doc_*` continua para edição colaborativa (lock + `doc_commit`) do documento ligado ao path.
Recursos: `fileagent://fs`, `fileagent://docs`, `fileagent://blob/{hash}`.
## Metadados extraídos
No `ftp_put` / `ftp_stat` / `ftp_ls`:
- **sempre:** `hash`, `size`, `mime`, `kind`, `filename`, `extension`
- **texto / markdown:** título, headings, linhas, palavras, idioma (`pt`/`en`)
- **JSON:** validade, tipo, chaves
- **CSV:** colunas e número de linhas
- **PNG / JPEG / GIF:** largura e altura
- **PDF:** versão, title/author se presentes no header
## Admin e senha
Só o **admin** cadastra `access_hash`. A senha em texto fica **apenas** no `.venv` do projeto (fora do git):
- hash: `.venv/fileagent_admin.hash` (PBKDF2-SHA256)
- senha: `.venv/fileagent_admin.password`
```bash
uv run fileagent --init-admin # gera se ainda não existir
uv run fileagent --rotate-admin # nova senha
```
Painel no navegador: abra `/` e entre com essa senha para ver todos os arquivos de todos os canais. Sem login, a lista não aparece.
```bash
# cadastrar um canal para clientes
curl -sS -X POST http://127.0.0.1:8765/v1/admin/register \
-H "Content-Type: application/json" \
-d '{"admin_password":"<senha>","label":"equipe-a"}'
```
Clientes **não** cadastram hash. Usam o `access_hash` devolvido em `POST /v1/files` ou `ftp_put`.
## Subir no ar
```bash
uv run fileagent --http --host 0.0.0.0 --port 8765
```
- Painel admin (login): `http://<host>:8765/`
- MCP: `http://<host>:8765/mcp`
- REST: `POST/GET /v1/files` com header `X-Access-Hash`
- Saúde: `GET /healthz`
## Skills
- `fileagent-send` — agentes que enviam
- `fileagent-receive` — agentes que listam/baixam
## Instalação
```bash
cd /Users/naubergois/FileAgent
uv sync --extra dev
```
### Cursor (mesmo store entre agentes)
```json
{
"mcpServers": {
"fileagent": {
"command": "uv",
"args": ["--directory", "/Users/naubergois/FileAgent", "run", "fileagent"],
"env": {
"FILEAGENT_DATA_DIR": "/Users/naubergois/.fileagent",
"FILEAGENT_AGENT_ID": "cursor",
"FILEAGENT_OPEN_EDIT": "1"
}
}
}
}
```
Cada agente: **mesmo** `FILEAGENT_DATA_DIR`, `FILEAGENT_AGENT_ID` distinto.
### HTTP
```bash
uv run fileagent --http --port 8765
```
## Variáveis
| Variável | Default | Função |
|---|---|---|
| `FILEAGENT_DATA_DIR` | `~/.fileagent` | SQLite + blobs. Mesmo path = mesmo FTP. |
| `FILEAGENT_AGENT_ID` | `user@host` | Quem enviou / editou. |
| `FILEAGENT_OPEN_EDIT` | `1` | Agentes do store editam paths `shared`. |
| `FILEAGENT_HOST` / `PORT` | `127.0.0.1` / `8765` | Modo `--http`. |
Paths `private` só o dono (e grants) enxergam. `agent_id` é coordenação, não autenticação forte. A segurança do conteúdo é o hash: se os bytes mudarem, a leitura falha.
Produção atual (AWS): `https://fileagent.54-204-243-102.sslip.io/` — painel com senha de admin.
## Testes
```bash
uv run pytest -q
```
TDQS
Scored across 31 tools
Several tools have overlapping functionality, making it unclear which to use. For example, ftp_put and doc_put both store content and return a SHA-256 hash, ftp_get and doc_get both retrieve content by hash, and ftp_stat and ftp_meta both retrieve metadata. This redundancy increases the risk of misselection.
The naming mostly follows a consistent pattern of prefix (ftp_ or doc_) plus a verb (put, get, ls, stat, etc.), with only a few exceptions like ftp_hashes and ftp_register. Overall, the naming is predictable and semantically aligned with the action.
With 31 tools, the server is on the higher end but not excessive. However, the count is inflated by redundant operations (e.g., ftp_stat vs. ftp_meta, ftp_ls vs. doc_list) and a clear split between file management and document management, which could be streamlined without loss of functionality.
The toolset covers CRUD for files and documents, versioning, locking, sharing, and admin functions. However, there is no explicit document deletion tool (doc_delete), and the distinction between immutable blobs and editable documents is not fully addressed (e.g., doc_update exists but no corresponding ftp_update). This leaves minor gaps in lifecycle management.