npm package: @nomad-e/reader-pdf
Description: MCP server that exposes tools for PDF processing via a configurable backend. Connects to your API (API_PAGEINDEX); no third-party services. Tools: process_document, get_document_structure, get_page_content.
Author: Nomad-e
Latest version: 0.0.2

# PageIndex MCP

Servidor MCP (Model Context Protocol) que expõe 3 tools para um LLM processar PDFs e consultar a sua estrutura e conteúdo via **backend próprio**. O MCP não contacta serviços de terceiros; comunica apenas com a API configurada em `API_PAGEINDEX`.

---

## Arquitectura

```
LLM (Cursor, Claude Desktop, etc.)
        │
        ▼  stdio
   pageindex-mcp  (este repo)
        │
        ▼  HTTP (API_PAGEINDEX)
   Backend API (ex.: PageIndex/src/api/app.py)
        │
        ▼
   Processamento (árvore, sumários, texto das páginas)
```

- **MCP**: transporte **stdio**. O cliente (Cursor) lança o processo e fala por stdin/stdout.
- **Backend**: transporte **HTTP**. O MCP faz `fetch` para a URL em `API_PAGEINDEX` (ex.: `http://localhost:8000`).
- **Sem VectifyAI**: OAuth e API deles foram removidos; toda a lógica e estado ficam no teu backend.

---

## Tools

| Tool | Descrição |
|------|-----------|
| **process_document** | Processa um PDF (path local ou URL). Devolve `doc_id` para usar nas outras tools. |
| **get_document_structure** | Devolve a estrutura em árvore (JSON) do documento: títulos, node_id, start_index, end_index, summary, nodes. |
| **get_page_content** | Devolve o texto de uma página ou intervalo de páginas (1-based). |

---

## Requisitos

- Node.js ≥18
- Backend que implemente o contrato abaixo (ex.: [PageIndex](https://github.com/VectifyAI/PageIndex) com `src/api/app.py`)

---

## Desenvolvimento local

### 1. Instalar dependências

```bash
pnpm install
# ou: npm install
```

### 2. Build

```bash
pnpm run build
# ou: npm run build
```

Gera `build/index.js` a partir de `src/`.

### 3. Lint e format

```bash
pnpm run lint        # verificar
pnpm run lint:fix    # corrigir e formatar
```

### 4. Scripts disponíveis

| Script | Função |
|--------|--------|
| `build` | Compila com tsup → `build/index.js` |
| `dev` | Build em watch |
| `start` | Executa `node build/index.js` |
| `lint` | Biome check |
| `lint:fix` | Biome check --write |
| `clean` | Remove `build/` |

---

## Configuração do MCP

O cliente (Cursor, Claude Desktop, etc.) precisa de `API_PAGEINDEX` com a URL do backend. Sem ela, as tools falham com mensagem a pedir para configurar.

### Cursor

Em Settings → MCP, ou no ficheiro de config do MCP:

```json
{
  "mcpServers": {
    "pageindex": {
      "command": "node",
      "args": ["/caminho/absoluto/para/pageindex-mcp/build/index.js"],
      "env": {
        "API_PAGEINDEX": "http://localhost:8000"
      }
    }
  }
}
```

### Via npm (npx ou instalação global)

**Opção A – npx** (pode dar 404 ou "token expired" se o registry ainda não tiver o pacote ou em alguns ambientes):

```json
{
  "mcpServers": {
    "pageindex": {
      "command": "npx",
      "args": ["-y", "@nomad-e/reader-pdf"],
      "env": {
        "API_PAGEINDEX": "http://localhost:8000"
      }
    }
  }
}
```

**Opção B – instalação global** (mais estável que npx; evita 404 e problemas de token):

```bash
npm install -g @nomad-e/reader-pdf
```

```json
{
  "mcpServers": {
    "pageindex": {
      "command": "reader-pdf",
      "args": [],
      "env": {
        "API_PAGEINDEX": "http://localhost:8000"
      }
    }
  }
}
```

Se aparecer **404** ou **"Access token expired"** ao usar npx: confirma em [npmjs.com/package/@nomad-e/reader-pdf](https://www.npmjs.com/package/@nomad-e/reader-pdf) se o pacote existe; usa a **Opção B** ou o **caminho local** (exemplo acima com `node` e `build/index.js`).

**Nota:** Usa o caminho absoluto para `build/index.js` ou o comando correto; não adiciones barra final na URL (`http://localhost:8000` e não `http://localhost:8000/`).

---

## Contrato do backend

O backend deve expor:

| Método | Path | Descrição |
|--------|------|-----------|
| POST | `/documents` | Recebe JSON `{ "url": "https://..." }` (backend descarrega o PDF) ou multipart com campo `file` (upload). Processa o documento e devolve `{ "doc_id": "string", "message": "..." }`. |
| GET | `/documents/:doc_id/structure` | Devolve o JSON da árvore do documento. |
| GET | `/documents/:doc_id/pages?start_page=1&end_page=1` | Devolve o texto das páginas (1-based, end inclusive). Resposta: `{ "content": "..." }`. |

O MCP usa `API_PAGEINDEX` como base e concatena estes paths.

---

## Usar o PageIndex como backend

O repo [PageIndex](https://github.com/VectifyAI/PageIndex) inclui uma API em `src/api/app.py`. Na raiz do PageIndex:

```bash
pip install -r requirements.txt
export CHATGPT_API_KEY=your_openai_key
python run.py
```

A API sobe em `http://localhost:8000` (ou `PORT` do `.env`). Ver `API_README.md` no repo PageIndex.

---

## Como testar (resumo)

1. **Terminal 1 – API (PageIndex)**  
   ```bash
   cd /caminho/para/PageIndex
   python run.py
   ```

2. **Config do MCP**  
   `API_PAGEINDEX=http://localhost:8000` e `command`/`args` a apontar para este repo.

3. **Cursor**  
   Reiniciar o MCP; as 3 tools devem aparecer e funcionar com a API local.

---

## Estrutura do código

| Ficheiro | Função |
|----------|--------|
| `src/config.ts` | Lê `API_PAGEINDEX`; falha se não estiver definida ao usar o backend. |
| `src/backend-client.ts` | `postDocumentByUrl`, `postDocumentByFile`, `getDocumentStructure`, `getPageContent` — chamadas HTTP ao backend. |
| `src/tools/process-document.ts` | Tool `process_document`: path local → multipart; URL → JSON `{ url }`. |
| `src/tools/get-document-structure.ts` | Tool `get_document_structure`. |
| `src/tools/get-page-content.ts` | Tool `get_page_content`. |
| `src/tools/index.ts` | Regista as 3 tools e `executeTool`. |
| `src/server.ts` | Servidor MCP stdio: ListTools (só estas 3), CallTool. |

---

## Documentação adicional

- **`docs/OVERVIEW-FOR-DEVS.md`** — visão geral para novos devs (o que fizemos, como encaixa, ficheiros principais)
- **`docs/MCP-API-CONNECTION.md`** — como o MCP se liga à API
- **`mcp-config-example.json`** — exemplo de config do MCP para Cursor

---

## Licença

MIT. Ver [LICENSE](./LICENSE).