# Tutorial del MCP de QuizIA

Este servidor MCP expone formularios, preguntas y sesiones de entrevista de QuizIA
para que un agente (Cline y similares) los opere por chat.



## 1) Crear la agent key

1.Entrar a /profile/api-keys.
2.En "Tipo de API Key"elegir"Agente IA / MCP".
3.Poner un nombre y presionar"Generar API Key".
4.Copiar la key: se muestra UNA sola vez...

Nota: la agent key actua como su propio usuario(no otorga permisos extra).



## 2) Conectar el cliente MCP

Conectar **directo** con Streamable HTTP contra el servidor remoto **no es estable**:
la conexión se cae por inactividad/timeouts o porque el canal HTTP no se mantiene vivo
de la forma correcta. Para una conexión **estable** hay que intercalar un **proxy local de**
Node (`@modelcontextprotocol/server-http-sse`). Cline habla con ese proceso local por **stdio**
(un proceso local que no se cae por inactividad) y el proxy se encarga de **mantener vivo** el
canal **HTTP/SSE** contra el server remoto. Requiere **Node.js/npm** en la maquina local.



Config (`cline_mcp_settings.json`):

```json
{
  "mcpServers": {
    "quiz-ia": {
      "transport": {
        "type": "stdio",
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-http-sse", "https://quizia.tecsi.com.ar/mcp"],
        "env": { "Authorization": "Bearer <AGENT_KEY>" }
      }
    }
  }
}
```

El Bearer token se pasa en la sección `env` del transport para que el proxy lo inyecte en las
cabeceras HTTP de cada petición.

 Para **local**, apuntá el proxy a `http://127.0.0.1:8000/mcp`.


## 3) Tools disponibles

- `listar_formularios`: lista los formularios del usuario.
- `ver_formulario`: detalle de un formulario por slug(preguntas, tipos, dependencias).
- `generar_preguntas`: genera/refina preguntas por chat(Arquitecto). Iterativo. Devuelve las `questions` y un `resumen` de hasta 50 palabras que explica como se organizo la informacion (apto para mostrar al usuario).
- `crear_formulario`: guarda un formulario con las preguntas del ultimo chat.

- `responder_pregunta`: responde una pregunta(mismo pipeline del plugin).
- `listar_sesiones`: lista sesiones(permite recuperar id/token). El filtro `status` acepta solo los estados reales de la sesion: `active`, `completed`, `blocked`, `expired`; cualquier otro valor devuelve error.
- `resumen_sesion`: resumen de una sesion por token.

- `reporte_sesion`: auditoria de una sesion(respuestas + logs de agentes.

### Archivos adjuntos en `responder_pregunta`

En preguntas de tipo `file` podés enviar el contenido del archivo en base64:

```json
{
  "slug": "3RRE",
  "session_token": "uuid-de-sesion",
  "question_id": 168,
  "is_dynamic": false,
  "attachment_name": "foto.jpg",
  "attachment_base64": "/9j/4AAQSkZJRg...",
  "attachment_mime": "image/jpeg"
}
```

- Si no enviás `answer_value`, el nombre del archivo (`attachment_name`) pasa a
  ser el valor de la respuesta.
- Se valida la extensión contra las permitidas de la pregunta y contra el tope
  `attachments.mcp_max_kb` (2048 KB por defecto; el base64 infla ~33%).
- Códigos de error: `attachment_not_file_question`,
  `attachment_extension_not_allowed`, `attachment_too_large`,
  `attachment_invalid_base64`, `answer_value_required`.
- El archivo se guarda igual que los que sube el plugin web (una carpeta por
  sesión), se ve o se descarga desde el panel y se borra al eliminar la sesión.

### Sesiones de prueba: `es_prueba` en `responder_pregunta`

Cuando simulás una entrevista para **probar** un formulario, mandá
`es_prueba: true` en la PRIMERA llamada de la sesión:

```json
{
  "slug": "3RRE",
  "session_token": "uuid-de-sesion",
  "question_id": 12,
  "answer_value": "prueba",
  "es_prueba": true
}
```

La sesión marcada como prueba:

- **No cuenta como respuesta**: no consume el cupo de `max_respondents`
  ("Veces que puede contestar") ni bloquea la edición del formulario.
- **Sí se cobra**: el consumo de IA se descuenta del saldo igual que una
  respuesta real, con el concepto `Prueba de formulario (...)` en el libro
  mayor, para que se distinga en `/saldo` y en Gastos.
- Solo se aplica **al crear** la sesión: si mandás `es_prueba` después, la
  sesión no cambia de tipo.

Recomendado: usalo siempre que simules con un agente, así una simulación no
gasta el cupo de respuestas del cliente.

`listar_sesiones` acepta `tipo: "real" | "prueba"` para filtrar, y devuelve
`es_prueba` en cada sesión. `reporte_sesion` también lo incluye.




## 4) Flujo recomendado

1.`generar_preguntas` (iterar hasta conformar).
2.`crear_formulario` (persistir y obtener el slug).
3.`responder_pregunta` (simular/completar una entrevista.

4.`listar_sesiones` -> `resumen_sesion` / `reporte_sesion` (auditar resultados.


## 5) Troubleshooting

- 401: falta el header `Authorization: Bearer <key>`(todo `/mcp` requiere token.

- 403: la key no es de tipo agent(usar una API key"Agente IA / MCP".
- La IA no razona: la app necesita una AI provider key(OpenAI/OpenRouter) configurada;
  es distinta de la agent key. 
- La conexion cae/se pierde en remoto: usar un **proxy local stdio**
  (`@modelcontextprotocol/server-http-sse`) en lugar de conectar streamableHttp directo al servidor. 
- Si se usa HTTP directo, en algunos hosting"SSE" no streamea y conviene usar
  `"type": "streamableHttp"` (POST/JSON).