Skip to main content
Glama
VanguardIA-Tech

winthor-mcp

README.md
# winthor-mcp

Servidor MCP para o ERP **TOTVS WinThor**. Ele lê o catálogo de rotinas direto do
Oracle da sua instalação, resolve a permissão da própria pessoa com a mesma regra
que o ERP aplica e executa rotinas nativamente pelo **WinThor Anywhere (WTA)**.
Este é o primeiro MCP de WinThor — não existe hoje nenhum outro, oficial ou de
comunidade.

A ideia é simples: em vez de manter uma lista de rotinas escrita à mão dentro do
projeto, o servidor pergunta ao seu banco. Numa base real isso dá 1.686 rotinas,
e a rotina que a sua casa desenvolveu aparece exatamente como as de fábrica.
A permissão sai do mesmo lugar de sempre — rotina 530 / `PCCONTRO` para as
rotinas desktop e rotina 807 (perfis) para as rotinas web —, então ninguém
enxerga pelo MCP nada que já não enxergasse no WinThor.

## Onde este servidor roda

**Dentro da rede do cliente.** Não é um SaaS e não há serviço hospedado.

O WinThor é on-premise: o Oracle fica na sua infraestrutura e o WTA quase sempre
responde num IP privado. O servidor precisa alcançar os dois ao mesmo tempo, e o
único lugar onde isso é verdade é dentro da sua rede. Ele fala com o cliente MCP
(Claude Desktop, Claude Code, Cursor) por **stdio**, como um processo local —
não abre porta, não escuta conexão de fora.

## O que ele consegue

- Listar o catálogo de rotinas lido de `PCROTINA`, com módulo, submódulo,
  executável, versão e se a tela é web.
- Descrever uma rotina específica e dizer por onde ela pode ser executada.
- Resolver quem é a pessoa conectada e quais rotinas ela pode abrir, com a regra
  do próprio ERP.
- Executar rotinas que têm serviço no WTA, chamando o serviço REST da TOTVS.
- Diagnosticar a instalação: se o Oracle responde, se o WTA está configurado e
  se a identidade informada é válida.

Ferramentas MCP expostas: `whoami`, `listar_rotinas`, `descrever_rotina`,
`executar_rotina`, `diagnostico`.

## O que ele não consegue

Vale ler esta lista antes de instalar.

- **Rotina sem serviço no WTA não executa.** Muita rotina do WinThor só existe
  como executável Delphi. Nesses casos o servidor declara "só no desktop" e para
  por aí — ele não reimplementa a rotina.
- **Sem `WINTHOR_WTA_URL` configurada, o servidor é só leitura.** Ele continua
  útil para catálogo, permissão e diagnóstico, mas diz com todas as letras que
  não executa nada.
- **Ele não emula regra de negócio em SQL.** O servidor nunca monta `INSERT` ou
  `UPDATE` contra as tabelas do ERP para simular o efeito de uma rotina.
  Reproduzir a regra em SQL seria criar uma segunda versão do WinThor, com
  divergências que só aparecem no fechamento.
- **Ele não amplia permissão de ninguém.** Se a pessoa não tem a rotina liberada
  na 530 ou no perfil da 807, o MCP também não tem.

## Requisitos

- Python 3.12 ou superior (só se você for instalar via `uvx`/`pipx`; com Docker,
  não precisa de Python na máquina).
- Uma conta Oracle **de leitura** no schema do WinThor, com acesso a `PCROTINA`,
  `PCCONTRO`, `PCUSUARI`, `PCMODULO` e às demais tabelas de cadastro.
- Opcionalmente, a URL do WinThor Anywhere. Sem ela o servidor sobe em modo
  leitura.

O driver Oracle roda em **modo thin**: não é preciso instalar Instant Client,
`tnsnames.ora` nem wallet.

## Instalação

### uvx (recomendado)

```bash
uvx winthor-mcp
```

Não instala nada permanente: o `uv` baixa, resolve e executa.

### pipx

```bash
pipx install winthor-mcp
winthor-mcp
```

### Docker

A imagem é construída a partir da raiz do repositório:

```bash
docker build -f docker/Dockerfile -t winthor-mcp .
docker run --rm -i --env-file .env winthor-mcp
```

Ou com Compose:

```bash
docker compose -f docker/compose.yaml run --rm winthor-mcp
```

Use `run`, não `up`: é um servidor stdio, ele precisa do stdin ligado ao cliente
MCP.

## Configuração

Todas as variáveis usam o prefixo `WINTHOR_`. Podem vir do ambiente ou de um
arquivo `.env` no diretório de trabalho. Copie o `.env.example` como ponto de
partida.

| Variável | Obrigatória | Padrão | Para que serve |
| --- | --- | --- | --- |
| `WINTHOR_DB_HOST` | sim | — | Host do Oracle do WinThor. |
| `WINTHOR_DB_PORT` | não | `1521` | Porta do listener Oracle. |
| `WINTHOR_DB_SERVICE` | sim | — | Service name do banco. O driver thin usa Easy Connect; não é SID. |
| `WINTHOR_DB_USER` | sim | — | Usuário Oracle de leitura. |
| `WINTHOR_DB_PASSWORD` | sim | — | Senha desse usuário Oracle. |
| `WINTHOR_DB_SCHEMA` | não | igual ao `DB_USER`, em maiúsculas | Dono das tabelas do ERP, quando não for o mesmo usuário que lê. |
| `WINTHOR_WTA_URL` | não | vazio | Base do WinThor Anywhere, `http://host:porta`. Sem ela o servidor fica só em leitura. |
| `WINTHOR_WTA_TIMEOUT_SEGUNDOS` | não | `30.0` | Tempo máximo de espera por uma chamada REST ao WTA. |
| `WINTHOR_USUARIO` | não | vazio | Matrícula do WinThor de quem vai usar o servidor. |
| `WINTHOR_SENHA` | não | vazio | Senha do WinThor dessa mesma pessoa. |
| `WINTHOR_CACHE_SEGUNDOS` | não | `300` | Validade do cache de catálogo e permissão. |
| `WINTHOR_PERMITIR_ESCRITA` | não | `false` | Libera operações de escrita via WTA. Desligado por padrão. |

Exemplo (host e credenciais fictícios):

```bash
WINTHOR_DB_HOST=oracle.exemplo.local
WINTHOR_DB_PORT=1521
WINTHOR_DB_SERVICE=WINT
WINTHOR_DB_USER=consulta_mcp
WINTHOR_DB_PASSWORD=troque-esta-senha
WINTHOR_DB_SCHEMA=WINTHOR
WINTHOR_WTA_URL=http://winthor.exemplo.local:8080
WINTHOR_USUARIO=1234
WINTHOR_SENHA=troque-esta-senha
WINTHOR_PERMITIR_ESCRITA=false
```

`WINTHOR_USUARIO` e `WINTHOR_SENHA` são a matrícula e a senha que a pessoa já
digita no WinThor desktop. Elas identificam quem está usando o servidor e é
delas que sai a permissão aplicada. Sem elas, o servidor sobe, mas não consegue
resolver a identidade — o `diagnostico` avisa.

## Conectando no cliente MCP

O servidor é stdio. A configuração é a mesma nos três clientes; muda só o
arquivo.

- **Claude Desktop** — `claude_desktop_config.json`
  (macOS: `~/Library/Application Support/Claude/`;
  Windows: `%APPDATA%\Claude\`)
- **Claude Code** — `.mcp.json` na raiz do projeto, ou
  `claude mcp add` na linha de comando
- **Cursor** — `.cursor/mcp.json` no projeto, ou `~/.cursor/mcp.json`

```json
{
  "mcpServers": {
    "winthor": {
      "command": "uvx",
      "args": ["winthor-mcp"],
      "env": {
        "WINTHOR_DB_HOST": "oracle.exemplo.local",
        "WINTHOR_DB_PORT": "1521",
        "WINTHOR_DB_SERVICE": "WINT",
        "WINTHOR_DB_USER": "consulta_mcp",
        "WINTHOR_DB_PASSWORD": "troque-esta-senha",
        "WINTHOR_WTA_URL": "http://winthor.exemplo.local:8080",
        "WINTHOR_USUARIO": "1234",
        "WINTHOR_SENHA": "troque-esta-senha"
      }
    }
  }
}
```

Com Docker, troque o comando:

```json
{
  "mcpServers": {
    "winthor": {
      "command": "docker",
      "args": ["run", "--rm", "-i", "--env-file", "/caminho/para/.env", "winthor-mcp"]
    }
  }
}
```

Depois de salvar, reinicie o cliente e chame `diagnostico` para conferir se o
Oracle responde e se o WTA foi encontrado.

## Como descobrir a URL do WTA na sua instalação

O WinThor Anywhere é uma plataforma OSGi (Karaf + Pax Web). Todos os serviços
compartilham a mesma porta HTTP, então basta descobrir `host` e `porta` uma vez.

**1. Teste as portas comuns.** Na prática, a instalação está numa destas:
`80`, `8080`, `8180`, `8181`, `8182`, `9090`.

**2. Confirme pelo portal.** Se o endereço estiver certo, o portal do WTA
responde em:

```
http://host:porta/portal
```

```bash
curl -I http://winthor.exemplo.local:8080/portal
```

**3. Se nenhuma porta responder, leia a configuração.** A porta fica no arquivo
`org.ops4j.pax.web.cfg`, na chave `org.osgi.service.http.port`.

Caminho no Windows:

```
C:\pcsist\produtos\winthor\etc\org.ops4j.pax.web.cfg
```

Caminho no Linux:

```
/opt/pcsist/produtos/winthor/etc/org.ops4j.pax.web.cfg
```

```bash
grep org.osgi.service.http.port /opt/pcsist/produtos/winthor/etc/org.ops4j.pax.web.cfg
```

O valor encontrado é a porta que vai em `WINTHOR_WTA_URL`.

## Segurança

- **A conta Oracle deve ser só de leitura.** O servidor nunca monta `INSERT` ou
  `UPDATE` contra as tabelas do ERP. Crie um usuário dedicado com `SELECT` e
  nada além disso — assim o limite não depende do código, depende do banco.
- **Escrita vem desligada.** `WINTHOR_PERMITIR_ESCRITA` é `false` por padrão.
  Quem liga é o administrador, conscientemente, sabendo que a partir dali
  execuções via WTA podem alterar dados.
- **A permissão é sempre a da pessoa.** O servidor resolve o acesso com a regra
  do próprio ERP (530 / `PCCONTRO` para desktop, 807 para web). Ele não tem
  caminho para contornar isso.
- **Senha nunca é parâmetro de ferramenta.** Nem a do Oracle, nem a do WinThor.
  As credenciais entram por variável de ambiente ou `.env` e ficam no processo;
  nenhuma ferramenta MCP as recebe, e portanto o modelo não as vê e elas não
  aparecem no histórico da conversa.
- **Não versione o `.env`.** Ele já está no `.gitignore`.
- **O servidor fica na rede do cliente.** Não exponha a máquina que o roda à
  internet: ela tem acesso simultâneo ao Oracle do ERP e ao WTA.

## Licença

MIT. Veja [LICENSE](LICENSE).

## Aviso

Este é um projeto independente e **não tem qualquer vínculo com a TOTVS**.
WinThor, WinThor Anywhere e TOTVS são marcas da TOTVS S.A., citadas aqui apenas
para identificar o sistema com o qual este servidor se comunica. O projeto não é
endossado, patrocinado nem suportado pela TOTVS.

TDQS

B3.2/5.0

Scored across 6 tools

Disambiguation5/5

Cada ferramenta tem um propósito claramente distinto: listar operações, executar operações, listar rotinas, descrever uma rotina, identificar o usuário e diagnosticar o sistema. Não há sobreposição significativa entre elas.

Naming Consistency3/5

A maioria segue o padrão verbo_substantivo (listar_operacoes_winthor, executar_operacao_winthor, descrever_rotina, listar_rotinas), mas 'diagnostico' é um substantivo solto e 'whoami' é um comando em inglês, quebrando a consistência do padrão.

Tool Count5/5

Seis ferramentas é um número adequado para um servidor de integração com ERP: descoberta, execução, consulta de rotinas, identidade e diagnóstico. Cada ferramenta é necessária e o conjunto é equilibrado.

Completeness5/5

A superfície cobre bem o domínio: permite descobrir operações, executá-las, listar e descrever rotinas, verificar o usuário e o estado da integração. Não há lacunas óbvias para o escopo proposto.

Maintenance

ActivityMaintained
ResponsivenessNo issues