Skip to main content
Glama
marqprochat

personaleasy-mcp-server

by marqprochat
README.md
# personaleasy-mcp-server

Servidor MCP para a API PersonalEasy | EasyDental Cloud | DentalKids.

## Tools

| Tool | Descrição | Parâmetros |
|------|-----------|------------|
| `personaleasy_get_agendamentos` | Busca agendamentos no período | `dt_inicio`, `dt_termino` (YYYY-MM-DD), `nm_unidade` (opcional) |
| `personaleasy_get_kpi_producao` | KPIs de produção para dashboard | `dt_inicio`, `dt_termino`, `nm_unidade` (opc.), `nm_prestador` (opc.) |
| `personaleasy_get_prestador_por_cpf` | ID e nome do prestador pelo CPF | `cpf` (formato 999.999.999-99) |
| `personaleasy_get_unidades` | Lista unidades de atendimento ativas | — |

Todas as tools são somente leitura (`readOnlyHint: true`).

## Instalação

```bash
npm install
npm run build
```

## Credenciais

As credenciais **nunca** ficam no código. Configure via variáveis de ambiente:

- `PERSONALEASY_API_KEY` — a api-key (header `x-api-key`)
- `PERSONALEASY_CLIENT_ID` — o ID do cliente
- `PERSONALEASY_BASE_URL` — opcional, padrão `https://prsrb.onrender.com/v1/rpc`

Para testes locais, copie `.env.example` para `.env` e preencha. O `.env` está no `.gitignore` — não o versione nem o compartilhe.

## Configuração no Claude Code

```bash
claude mcp add personaleasy --env PERSONALEASY_API_KEY=SUA_KEY --env PERSONALEASY_CLIENT_ID=SEU_CLIENT_ID -- node D:/MCPS/personaleasy-mcp-server/dist/index.js
```

## Configuração no Claude Desktop

Em `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "personaleasy": {
      "command": "node",
      "args": ["D:/MCPS/personaleasy-mcp-server/dist/index.js"],
      "env": {
        "PERSONALEASY_API_KEY": "SUA_KEY",
        "PERSONALEASY_CLIENT_ID": "SEU_CLIENT_ID"
      }
    }
  }
}
```

## Deploy no Easypanel (Docker)

O projeto tem dois modos de execução:

- **stdio** (`dist/index.js`) — uso local (Claude Code / Claude Desktop)
- **HTTP** (`dist/http.js`) — uso remoto; é o modo usado pelo Dockerfile

No Easypanel, crie um serviço do tipo **App** apontando para este repositório (build via Dockerfile) e configure as variáveis de ambiente:

| Variável | Obrigatória | Descrição |
|----------|-------------|-----------|
| `PERSONALEASY_API_KEY` | sim | api-key da API |
| `PERSONALEASY_CLIENT_ID` | sim | ID do cliente |
| `MCP_AUTH_TOKEN` | recomendada | token Bearer exigido no endpoint `/mcp` (gere um valor aleatório longo) |
| `PORT` | não | padrão 3000 |

Exponha a porta 3000 no serviço. Endpoints:

- `POST /mcp` — endpoint MCP (Streamable HTTP, stateless)
- `GET /health` — healthcheck

### Instância em produção

- **URL base:** `https://dk-projetos-mcps.nv8gf3.easypanel.host`
- **Healthcheck:** `GET https://dk-projetos-mcps.nv8gf3.easypanel.host/health` → `{"status":"ok"}`
- **Endpoint MCP:** `POST https://dk-projetos-mcps.nv8gf3.easypanel.host/mcp`

Para conectar um cliente MCP a essa instância:

```bash
claude mcp add --transport http personaleasy https://dk-projetos-mcps.nv8gf3.easypanel.host/mcp --header "Authorization: Bearer SEU_MCP_AUTH_TOKEN"
```

Substitua `SEU_MCP_AUTH_TOKEN` pelo valor configurado na variável `MCP_AUTH_TOKEN` do serviço no Easypanel.

### Uso no claude.ai (conector custom — para não-desenvolvedores)

O claude.ai não tem campo para header de autenticação em conectores custom, então o servidor também aceita o token embutido na URL:

```
https://dk-projetos-mcps.nv8gf3.easypanel.host/mcp/SEU_MCP_AUTH_TOKEN
```

Passo a passo para o usuário final:

1. Abrir [claude.ai](https://claude.ai) → **Configurações** → **Conectores**
2. Clicar em **Adicionar conector custom**
3. Colar a URL acima (já com o token) e salvar
4. Numa conversa nova, ativar o conector e pedir normalmente: *"quais os agendamentos de amanhã na unidade Campinas?"*

> Trate essa URL como uma senha: quem tiver a URL completa acessa os dados. Envie por canal seguro e, se vazar, troque o `MCP_AUTH_TOKEN` no Easypanel (isso invalida a URL antiga).

> **Importante:** sem `MCP_AUTH_TOKEN` configurado no serviço, qualquer pessoa com essa URL consegue consultar os dados da clínica. Confirme que a variável está definida em produção.

## API subjacente

Todas as chamadas vão para um único endpoint RPC:

```
POST {BASE_URL}
Headers: x-api-key
Body: { "clientId": "...", "method": "RPCGet...", "params": { ... } }
```

Métodos usados: `RPCGetAgendamentos`, `RPCGetKPIPrd`, `RPCGetPrestadorCPF`, `RPCGetUnidadeAtendimento`.

TDQS

A3.8/5.0

Scored across 4 tools

Disambiguation5/5

Each tool targets a distinct resource: appointments (agendamentos), production KPIs, provider lookup by CPF, and units. There is no overlap in purpose, and the descriptions clearly differentiate them.

Naming Consistency4/5

All tools follow the pattern `personaleasy_get_<resource>`, using the same prefix and verb. The resource names are in Portuguese, which is consistent with the domain, though the prefix adds redundancy.

Tool Count4/5

Four tools is appropriate for a focused server that provides read-only access to core entities (appointments, KPIs, providers, units). It is not too few for the apparent scope, and each tool serves a clear purpose.

Completeness3/5

The tool set covers reading key entities, but there are obvious gaps: no filtering by provider for appointments, no tool for patients or procedures, and only a CPF-based lookup for providers. Write operations (create, update, delete) are absent, limiting the surface to querying.

Maintenance

ActivitySlowing
ResponsivenessNo issues