> ## Documentation Index
> Fetch the complete documentation index at: https://docs.messora.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Servidor MCP

> Conecte agentes LLM ao Messora via Model Context Protocol usando a mesma API key e os mesmos créditos da REST API.

# Servidor MCP da Messora

A Messora expõe um [Model Context Protocol](https://modelcontextprotocol.io) (MCP)
server remoto em **Streamable HTTP**. Ele permite que agentes LLM (Claude, Codex,
Cursor e outros clientes MCP) chamem scrape, crawl, search e consultem jobs e
uso — reutilizando a mesma conta, a mesma API key e a mesma pool de créditos da
REST API.

## Endpoint

| Recurso | URL                              |
| ------- | -------------------------------- |
| MCP     | `https://mcp.messora.dev/mcp`    |
| Health  | `https://mcp.messora.dev/health` |

O endpoint `/health` é independente do backend e retorna `{"status": "ok",
"service": "messora-mcp"}` sem exigir autenticação.

## Autenticação

O MCP usa **exclusivamente** o header `Authorization: Bearer`:

```bash theme={null}
Authorization: Bearer $MESSORA_API_KEY
```

<Warning>
  O header `X-API-Key` usado na REST API **não** é aceito pelo MCP. Use sempre
  `Authorization: Bearer`.
</Warning>

Você precisa de uma API key da Messora. Se ainda não tem, crie uma em
[www.messora.dev/auth/signup](https://www.messora.dev/auth/signup) → **API Keys**.

## Configurando clientes

### Claude Desktop

O Claude Desktop usa um config JSON em `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) ou `%APPDATA%\Claude\claude_desktop_config.json` (Windows):

```json theme={null}
{
  "mcpServers": {
    "messora": {
      "type": "http",
      "url": "https://mcp.messora.dev/mcp",
      "headers": {
        "Authorization": "Bearer sua-api-key-aqui"
      }
    }
  }
}
```

Reinicie o Claude Desktop após salvar. As ferramentas da Messora aparecem no seletor de tools.

<Note>
  O Claude Desktop não suporta interpolação de variável de ambiente no config.
  Use um placeholder e substitua, ou coloque a key diretamente — o arquivo é
  local e não é versionado.
</Note>

### Cursor

O Cursor usa um arquivo `.mcp.json` na raiz do projeto ou `~/.cursor/mcp.json`:

```json theme={null}
{
  "mcpServers": {
    "messora": {
      "type": "http",
      "url": "https://mcp.messora.dev/mcp",
      "headers": {
        "Authorization": "Bearer sua-api-key-aqui"
      }
    }
  }
}
```

Reinicie o Cursor ou rode `Cursor → Settings → MCP → Refresh` para carregar o servidor.

### Codex CLI

O Codex usa um arquivo `config.toml` em `~/.codex/config.toml`:

```toml theme={null}
[mcp_servers.messora]
url = "https://mcp.messora.dev/mcp"
bearer_token_env_var = "MESSORA_API_KEY"
```

Exporte a API key no shell antes de iniciar o Codex:

```bash theme={null}
export MESSORA_API_KEY="sua-api-key-aqui"
```

### MCP Inspector

```bash theme={null}
export MESSORA_API_KEY="sua-api-key-aqui"
npx @modelcontextprotocol/inspector
```

No Inspector, configure:

* **Transport type:** Streamable HTTP
* **URL:** `https://mcp.messora.dev/mcp`
* **Authentication:** Bearer token
* **Token env var:** `MESSORA_API_KEY`

<Note>
  Nunca coloque a API key literalmente em arquivos de configuração versionados.
  Para o Codex, use sempre variável de ambiente (`$MESSORA_API_KEY`). Para
  Claude Desktop e Cursor, o config é local (não versionado) — substitua o
  placeholder pela sua key.
</Note>

## Ferramentas disponíveis

O servidor expõe exatamente cinco tools:

### `scrape_url`

Extrai conteúdo de uma URL. Consome crédito somente quando o backend retorna
`scrape_status = success`.

| Parâmetro           | Tipo           | Default         | Descrição                              |
| ------------------- | -------------- | --------------- | -------------------------------------- |
| `url`               | string (URI)   | **obrigatório** | URL alvo                               |
| `formats`           | `["markdown"]` | `["markdown"]`  | Formatos: `markdown`, `json`, `raw`    |
| `json_schema`       | object         | —               | Obrigatório se `formats` inclui `json` |
| `render_js`         | boolean        | `false`         | Renderizar JavaScript                  |
| `only_main_content` | boolean        | `false`         | Somente conteúdo principal             |
| `timeout`           | int (1–180)    | `60`            | Timeout em segundos                    |
| `max_pages`         | int (1–50)     | `1`             | Máximo de páginas                      |
| `parse_pdf`         | boolean        | `true`          | Processar PDFs                         |
| `tags`              | string\[]      | —               | Até 10 tags (64 chars cada)            |

### `start_crawl`

Inicia um crawl assíncrono e retorna `job_id`. Consulte `get_job` até o estado
virar `SUCCESS`, `FAILURE` ou `REVOKED`.

| Parâmetro           | Tipo              | Default         | Descrição                  |
| ------------------- | ----------------- | --------------- | -------------------------- |
| `url`               | string (URI)      | **obrigatório** | URL semente                |
| `max_pages`         | int (1–50)        | **obrigatório** | Teto de páginas            |
| `max_depth`         | int ≥ 0           | —               | Profundidade máxima do BFS |
| `only_main_content` | boolean           | `true`          | Somente conteúdo principal |
| `timeout_ms`        | int (1000–300000) | `60000`         | Timeout por página         |
| `tags`              | string\[]         | `[]`            | Tags de uso                |

### `start_search`

Inicia uma busca premium assíncrona e retorna `job_id`.

| Parâmetro      | Tipo                          | Default         | Descrição                                                                                                                                                   |
| -------------- | ----------------------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `query`        | string                        | **obrigatório** | Query de busca                                                                                                                                              |
| `num_results`  | int (10–100)                  | `10`            | Número de resultados                                                                                                                                        |
| `country`      | string (ISO alpha-2)          | —               | Ex.: `BR`, `US`                                                                                                                                             |
| `freshness`    | `day\|week\|month\|year\|any` | —               | Recência                                                                                                                                                    |
| `tags`         | string\[]                     | —               | Até 10 tags                                                                                                                                                 |
| `query_fanout` | boolean                       | `true`          | Expande a query em até 5 variantes via LLM. `false` busca só a query crua — mais rápido, com 1 chamada LLM a menos (o score de relevância continua rodando) |
| `use_cache`    | boolean                       | `false`         | Reutiliza um resultado completo dos últimos 10 minutos para a mesma query e filtros                                                                         |

### `get_job`

Consulta o estado de um job de crawl ou search.

| Parâmetro | Tipo   | Descrição                                          |
| --------- | ------ | -------------------------------------------------- |
| `job_id`  | string | UUID retornado por `start_crawl` ou `start_search` |

**Estados:** `PENDING` → `STARTED` → `SUCCESS` | `FAILURE` | `REVOKED`

<Note>
  Recomendamos polling a cada 2 segundos com backoff. O adaptador MCP não faz
  polling interno nem retry automático de operações cobradas.
</Note>

### `get_usage`

Consulta plano, créditos usados e saldo da conta. Sem argumentos de produto.
Mesmo payload do REST [`GET /account/usage`](/pt-BR/api-reference/usage).

## Fluxo assíncrono: `start_*` → `get_job`

Crawl e search são assíncronos no backend. O fluxo recomendado é:

```
start_crawl(url, max_pages=3)
  → {"job_id": "d8cc042a-dcbb-4f8b-a159-91fd47d060f9", "status": "PENDING", "next_action": "Chame get_job..."}

get_job(job_id="d8cc042a-dcbb-4f8b-a159-91fd47d060f9")
  → {"status": "STARTED", "meta": {"pages_done": 1, "max_pages": 3}}

get_job(job_id="d8cc042a-dcbb-4f8b-a159-91fd47d060f9")
  → {"status": "SUCCESS", "credits_used": 3, "results": [...]}
```

## Tamanho de resposta

Toda resposta de tool é limitada a **100.000 caracteres**. Se excedir, campos
textuais (`markdown`, `rawHtml`) são truncados preservando estrutura, status,
metering e JSON válido:

```json theme={null}
{
  "ok": true,
  "data": { "status": "SUCCESS", "credits_used": 3, "results": [...] },
  "output": { "truncated": true, "original_chars": 250000, "returned_chars": 99500 }
}
```

## Erros

| HTTP | Código MCP                   | Retry | Significado                              |
| ---- | ---------------------------- | ----- | ---------------------------------------- |
| 401  | `missing_api_key`            | não   | Credencial ausente                       |
| 402  | `insufficient_credits`       | não   | Créditos insuficientes                   |
| 403  | `invalid_or_revoked_api_key` | não   | Key inválida ou revogada                 |
| 404  | `not_found`                  | não   | Job inexistente ou de outra conta        |
| 422  | `validation_error`           | não   | Input inválido                           |
| 429  | `rate_limit_exceeded`        | sim   | Limite excedido (preserva `Retry-After`) |
| 5xx  | `backend_unavailable`        | sim   | Falha temporária no backend              |
| —    | `backend_timeout`            | sim   | Timeout de rede                          |

<Note>
  O MCP é um adaptador fino: auth, billing, rate limit e jobs pertencem ao backend
  FastAPI. Os mesmos limites e custos da REST API se aplicam.
</Note>
