Skip to main content
Glama
naubergois

FileAgent

by naubergois
README.md
# 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

B3/5.0

Scored across 31 tools

Disambiguation2/5

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.

Naming Consistency4/5

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.

Tool Count3/5

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.

Completeness3/5

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.

Maintenance

ActivityMaintained
ResponsivenessNo issues