Skip to main content
Glama
Jairodaniel-17

Pandapé MCP

README.md
# Pandapé MCP

Servidor MCP para gestión de reclutamiento sobre la **API oficial de Pandapé v2** (ATS de Grupo Redarbor).
Pensado para que Claude revise candidatos contra los criterios que tú le indiques.

## Estado

| | |
|---|---|
| Servidor MCP | ✅ funciona (handshake, 11 tools, errores limpios) |
| Compilación y self-check | ✅ `npm run build && npm run check` |
| Descarga de CV por cookies | ✅ probada end-to-end (incluidos los modos de fallo) |
| Llamadas reales a Pandapé | ⛔ **bloqueado: faltan credenciales OAuth2** |

Todo está implementado y probado salvo lo único que no se resuelve desde el código:
`client_id` / `client_secret`. Se piden al **Customer Success Specialist** de tu cuenta.

## La API (verificado)

La API oficial existe y está documentada, aunque no se anuncie públicamente. Hay **tres versiones**:

| Spec | Rutas | Nota |
|---|---|---|
| `/swagger/v1/swagger.json` | 60 | No permite listar candidatos de una vacante |
| **`/swagger/v2/swagger.json`** | **68** | **La que usa este proyecto** |
| `/swagger/v3/swagger.json` | 6 | Nicho (análisis de entrevistas, requisiciones) |

ATS web: `https://ats.pandape.com` (login en `login.pandape.com`) · Base de API: `https://api.pandape.com.br` · Auth: OAuth2 `client_credentials` (IdentityServer), scope `PandapeApi`.

- LATAM: `https://login.pandape.com/connect/token`
- Brasil: `https://login.pandape.com.br/connect/token`

Ambos aceptan el grant (responden `invalid_client` con credenciales falsas, no `unsupported_grant_type`).
Descripciones del spec en portugués.

> ⚠️ **Host de API y región.** Solo resuelve `api.pandape.com.br`; `api.pandape.com` **no existe** en DNS,
> aunque el token LATAM sí sale de `login.pandape.com`. Confirma con tu CS qué host corresponde a tu
> cuenta de Perú y ajusta `PANDAPE_API_URL`.

### Detalles que cuestan una tarde si no los sabes

- `PATCH /v2/matches/{idMatch}/update` (mover de etapa) exige **`multipart/form-data`**, no JSON —
  lleva un campo `Photo` binario opcional. Con JSON falla.
- `pandape_endpoints` muestra el `contentType` de cada endpoint con cuerpo; míralo antes de usar `pandape_api`.
- La API v2 **no expone el CV en PDF**. Expone algo mejor para evaluar: el CV como datos estructurados.

## Revisar candidatos con tus criterios

`pandape_revisar_candidatos` trae el pool de una vacante con el CV ya estructurado:
resumen profesional, experiencias (puesto, empresa, fechas, actividades), estudios, habilidades,
idiomas, meses de experiencia, expectativa salarial, disponibilidad, y el `Affinity` que calcula Pandapé.

Flujo típico en Claude:

```
1. "Lístame las vacantes activas"                    → pandape_listar_vacantes (estado 2)
2. "¿Qué etapas tiene la vacante 4821?"              → pandape_etapas_vacante
3. "Revisa los candidatos nuevos de la 4821 y
    clasifícalos: necesito 3+ años en nómina,
    Excel avanzado y que viva en Lima"               → pandape_revisar_candidatos
4. "Dame el contacto de los tres mejores"            → pandape_ver_candidato
5. "Mueve esos tres a Entrevista"                    → pandape_mover_candidato (requiere READONLY=0)
```

### Sesgo y minimización de datos

`pandape_revisar_candidatos` **omite deliberadamente** CPF, fecha de nacimiento, sexo, identidad de
género, orientación sexual, raza, discapacidad, estado civil, hijos, dirección y contacto. No aportan
al criterio profesional y su presencia sesgaría la evaluación. El contacto sale por
`pandape_ver_candidato` cuando ya decidiste avanzar con alguien concreto.

El self-check verifica esa exclusión (`npm run check`), así que no se rompe por accidente.

## Uso rápido (sin credenciales de API): tu cookie del navegador

Funciona hoy con tu sesión del ATS, sin esperar credenciales:

```bash
npm ci && npm run build
# exporta la cookie del ATS con la extensión Cookie-Editor (Export → Netscape)
npm run set-cookie -- /ruta/cookies.txt     # guarda en .auth/ (600) y VERIFICA la sesión
```

Luego, con el MCP registrado, el flujo es:

- `pandape_web_candidatos { idVacante }` — candidatos de una vacante (idVacante = número de la URL del proceso).
- `pandape_web_cv { idMatch }` — CV completo en texto, listo para evaluar por criterios.
- `pandape_web_descargar_cv { idMatch }` — guarda el CV imprimible (HTML → PDF desde el navegador).

La cookie caduca con tu sesión; cuando `pandape_diagnostico` avise, re-exporta y vuelve a correr `set-cookie`.
Guía completa para operarlo (incluso para otro agente) en [`CLAUDE.md`](CLAUDE.md).

## Descargar el PDF del CV

**La API oficial no expone el documento del CV en ninguna de las tres versiones.** Verificado:
`CandidateResumeModel` es solo datos, y los únicos campos de descarga que existen
(`RequestDetailDocument.DownloadUrl`, `PreCollaboratorDocumentModel.Link`) son de documentos de
requisiciones y de pre-colaboradores, no del pool de postulantes.

Así que el PDF va por **cookies de tu sesión del ATS** (`pandape_descargar_cv`). Configuración de una
sola vez:

**1. La URL de descarga.** En el ATS abre un candidato, clic derecho en el botón de descarga del CV →
*Copiar dirección del enlace*. Reemplaza el id por `{idMatch}` (o `{idCandidate}`):

```bash
PANDAPE_CV_URL="https://ats.pandape.com/Candidate/DownloadCv?idMatch={idMatch}"
```

**2. Las cookies.** DevTools → Application → Cookies, o una extensión tipo Cookie-Editor. Dos formas:

```bash
PANDAPE_COOKIE="ASPNET_SessionId=…; .AspNetCore.Cookies=…"   # cabecera cruda
PANDAPE_COOKIE_FILE="/ruta/cookies.json"                     # o un archivo
```

El archivo acepta cabecera cruda, JSON `[{name,value}]` de extensiones, o un `storageState` de
Playwright. Caducan con tu sesión: cuando expiren, el error te lo dice y las re-exportas.

Los documentos se guardan en `PANDAPE_CV_DIR` (por defecto `./cv`). El nombre se sanea siempre, así
que la tool no puede escribir fuera de ese directorio. Se verifica la firma binaria: si el ATS
devuelve el HTML del login en vez del PDF, falla con un mensaje claro en vez de guardar basura
con extensión `.pdf`.

> Para clasificar candidatos por criterios **no necesitas el PDF**: `pandape_revisar_candidatos` ya
> trae el CV como datos estructurados. Usa la descarga cuando quieras el documento original.

## Puesta en marcha

```bash
npm install
npm run spec      # descarga swagger.json (v2 por defecto)
npm run build
npm run check     # self-check sin red
```

## Configuración

| Variable | Default | Descripción |
|---|---|---|
| `PANDAPE_CLIENT_ID` | — | **Requerido.** Lo entrega tu CS. |
| `PANDAPE_CLIENT_SECRET` | — | **Requerido.** |
| `PANDAPE_API_URL` | `https://api.pandape.com.br` | Host de la API |
| `PANDAPE_TOKEN_URL` | `https://login.pandape.com/connect/token` | LATAM por defecto |
| `PANDAPE_SCOPE` | `PandapeApi` | |
| `PANDAPE_READONLY` | `1` (activo) | `0` habilita las escrituras |
| `PANDAPE_SPEC` | `./swagger.json` | Ruta del spec |
| `PANDAPE_CV_URL` | — | Plantilla de descarga del CV, con `{idMatch}`/`{idCandidate}` |
| `PANDAPE_COOKIE` | — | Cookies de sesión del ATS (cabecera cruda) |
| `PANDAPE_COOKIE_FILE` | — | …o archivo con las cookies |
| `PANDAPE_CV_DIR` | `./cv` | Dónde se guardan los PDFs |
| `PANDAPE_SPEC_URL` | spec v2 | Solo para `npm run spec` (cambia a v1/v3 si lo necesitas) |

### Registro en Claude Code / Desktop

```json
{
  "mcpServers": {
    "pandape": {
      "command": "node",
      "args": ["/home/jairo/Documentos/pandape-mcp/dist/index.js"],
      "env": {
        "PANDAPE_CLIENT_ID": "…",
        "PANDAPE_CLIENT_SECRET": "…",
        "PANDAPE_TOKEN_URL": "https://login.pandape.com/connect/token",
        "PANDAPE_API_URL": "https://api.pandape.com.br"
      }
    }
  }
}
```

## Tools

| Tool | Qué hace |
|---|---|
| `pandape_diagnostico` | Verifica credenciales, token y una llamada real. **Empieza por aquí.** |
| `pandape_listar_vacantes` | Vacantes con filtro de estado (`2`=Published, `3`=Deactivated, `7`=Expired…) |
| `pandape_etapas_vacante` | Etapas del pipeline de una vacante |
| `pandape_revisar_candidatos` | **Pool de una vacante con el CV estructurado, listo para evaluar** |
| `pandape_ver_candidato` | Detalle completo con contacto, para un candidato concreto |
| `pandape_preguntas_eliminatorias` | Killer questions de la vacante |
| `pandape_mover_candidato` | Mueve de etapa *(escritura, multipart)* |
| `pandape_descargar_cv` | **Descarga el PDF del CV vía cookies de sesión** |
| `pandape_documentos_precolaborador` | Documentos de un pre-colaborador (el único caso con enlaces vía API) |
| `pandape_endpoints` | Explora las 68 rutas del spec |
| `pandape_api` | Llama cualquier ruta, validada contra el spec |

Las dos últimas cubren lo que no tiene tool propia (requisiciones, finalistas y sus evaluaciones,
clientes, sedes, usuarios, plantillas de vacante, diccionarios, campos personalizados) sin escribir
68 wrappers.

## Seguridad y datos personales

- **Solo lectura por defecto.** Las escrituras exigen `PANDAPE_READONLY=0` explícito.
- El `client_secret` va en la config del cliente MCP, nunca en el repo.
- Datos de candidatos = datos personales (Ley 29733 en Perú). La evaluación asistida por IA de
  personas conviene documentarla: criterios explícitos, evidencia citada y decisión humana al final.

## `legacy/`

Scaffold anterior que hablaba con la SPA vía Playwright, archivado sin borrar (está en el primer
commit de git). Se abandonó porque:

1. Asumía una SPA con API JSON en `/api/v1/*`. Pandapé es **ASP.NET Core MVC sobre IIS** con Razor y `jquery.unobtrusive-ajax`: devuelve HTML, y `/api/` da 404.
2. Sus escrituras no enviaban `__RequestVerificationToken`, así que habrían fallado con antiforgery.
3. Existiendo API oficial que cubre el caso de uso, el scraping añade riesgo legal y fragilidad sin aportar nada.

Ya no hace falta ni para el PDF: `pandape_descargar_cv` cubre ese caso con cookies y sin
dependencias de navegador. Rescátalo solo si las cookies resultan demasiado incómodas de renovar y
prefieres un login automatizado (requiere `npm i playwright`).

TDQS

A3.6/5.0

Scored across 14 tools

Disambiguation3/5

Several tools overlap in purpose, especially around CV retrieval and candidate listing. For example, pandape_descargar_cv and pandape_web_descargar_cv both fetch CV files via web sessions, and pandape_revisar_candidatos overlaps with pandape_web_cv for reviewing candidate CVs. The detailed descriptions help clarify when to use each, but the boundaries are not instantly obvious.

Naming Consistency3/5

All tools share the 'pandape_' prefix, which provides a clear brand, but the remainder mixes styles: some are verb_noun (listar_vacantes, mover_candidato), others are noun-based (diagnostico, endpoints, api), and some have awkward constructions like web_descargar_cv. This inconsistency makes it harder to predict tool names.

Tool Count4/5

14 tools is within the expected 3-15 range and the server appears to cover a broad ATS domain. However, the presence of multiple nearly redundant CV-related tools (descargar_cv vs web_descargar_cv) and the generic API fallback makes the set feel slightly less focused than it could be.

Completeness3/5

The set covers core read operations (list vacancies, stages, candidates, CV retrieval) and one write operation (move candidate). Missing are obvious lifecycle operations like create/update/delete vacancies, add candidates to vacancies, or update candidate info. The generic pandape_api endpoint helps fill these gaps but does not make the tool surface complete on its own.

Maintenance

ActivitySlowing
ResponsivenessNo issues