Skip to main content
Glama

Llenar el CvLAC de MinCiencias es lento: un formulario por cada curso, premio o proyecto, con catálogos de instituciones y municipios que no siempre encuentran lo que buscas. cvlac-mcp le da a tu asistente de IA (Claude, por ejemplo) la capacidad de hacerlo por ti: le dices en el chat qué agregar o corregir, y él entra a CvLAC con tu cuenta, llena el formulario, lo guarda y revisa que haya quedado guardado.

Funciona en tu computador. Tus credenciales no salen de él y no pasan por ningún servidor intermedio.

Cómo se ve

Una conversación se parece a esto:

Tú: Muéstrame los reconocimientos que tengo en CvLAC.

Asistente: Tienes 6. Entre ellos, "Distinción a la labor docente" (2023) y "Mejor ponencia, Congreso Nacional de Ingeniería" (2021)…

Tú: Agrega este: "Mención de honor a la labor docente", Universidad del Norte, 2024, nacional.

Asistente: No lo guardé todavía: se parece a "Distinción a la labor docente" (2023), que ya está en tu CvLAC. ¿Es el mismo reconocimiento y quieres corregirlo, o es otro y lo creo aparte?

Tú: Es otro, créalo.

Asistente: Listo, CvLAC confirmó el guardado. Ya aparece en tu lista: "Mención de honor a la labor docente", 2024, ámbito nacional.

El asistente no borra nada ni crea duplicados sin preguntarte primero. Los nombres de este ejemplo son ficticios.

Related MCP server: Resume Generator MCP Server

Qué puede hacer y qué no

Puede leer, agregar, corregir y borrar:

En CvLAC se llama

Ejemplos

Formación académica

Pregrado, especialización, maestría, doctorado

Formación complementaria

Diplomados, cursos de extensión (ver la nota abajo)

Experiencia profesional

Vinculaciones con universidades y empresas

Cursos de corta duración

Cursos y talleres

Reconocimientos

Premios, distinciones, menciones

Proyectos

De investigación, innovación, extensión

Software

Productos de software registrados

Eventos científicos

Congresos, seminarios, talleres donde participaste

Idiomas

Con tus niveles de lectura, escritura, habla y escucha

Líneas de investigación

Activas o no, con su objetivo

Demás trabajos

Otros productos

Artículos

Artículos de revista, con ISSN o revista del catálogo

Libros

Libros con ISBN, editorial y área del catálogo

Capítulos

Capítulos vinculados a un libro y área del catálogo

Tesis dirigidas

Tesis, programa e institución

Jurados

Jurados de trabajos de grado o tesis

Producción técnica

Informes, innovaciones, productos tecnológicos, consultorías y prototipos

Perfil

El texto de presentación, las redes académicas (ORCID, Google Scholar, Scopus…) y las áreas de actuación

Todavía no puede:

  • Subir certificados desde complete_product: esa operación gestiona palabras clave, áreas, coautores, reconocimientos y estudiantes vinculados en tesis. Los certificados de libros se adjuntan mediante update_section con rutas locales; no forman parte de las listas de complete_product.

  • Crear revistas, libros, editoriales, programas o áreas que no existan en los catálogos de CvLAC. Si un catálogo devuelve varias opciones, te las muestra para que elijas.

  • Iniciar sesión con una cuenta de nacionalidad extranjera. Por ahora el inicio de sesión asume nacionalidad colombiana.

  • Tocar tus datos de identificación y direcciones, ni nada de GrupLAC.

  • Crear un programa en formación complementaria que CvLAC no tenga registrado. El buscador de CvLAC solo ofrece los que ya existen para esa institución, y la web tampoco deja crear otros.

Comparar automáticamente tu CvLAC con otra fuente (la herramienta diff) hoy solo funciona con un portafolio web que tenga una estructura concreta (detalles). Si no tienes uno, no importa: le pegas en el chat el texto de tu hoja de vida, o se lo dictas, y el asistente lee tu CvLAC y agrega lo que falte, ítem por ítem, preguntándote ante cualquier parecido.

Qué necesitas

  • Tu usuario de CvLAC: primer nombre, número de cédula y contraseña, los mismos con los que entras a la web.

  • Un computador con Windows, macOS o Linux.

  • Node.js 20 o superior, un programa gratuito que hace funcionar esta herramienta. En el paso 1 está cómo instalarlo.

  • Una app de IA que acepte servidores MCP. MCP es el estándar con el que estas apps se conectan a herramientas como esta. Si no tienes ninguna, empieza con Claude Desktop: es la más sencilla y es la que usa esta guía. También sirven Claude Code, Cursor, VS Code, Windsurf, Zed y JetBrains (cómo conectarlas).

No necesitas saber programar. Vas a copiar y pegar unos comandos en la terminal; la guía dice exactamente cuáles.

Instalación paso a paso

¿Qué es la terminal? Una ventana donde se escriben comandos. En Windows: tecla Windows, escribe PowerShell y ábrelo. En macOS: Cmd + Espacio, escribe Terminal y ábrela. Para pegar un comando: clic derecho en Windows, Cmd + V en macOS. Luego presiona Enter.

Paso 1 · Instala Node.js

Descarga la versión LTS desde nodejs.org e instálala con las opciones que vienen marcadas. Luego cierra y vuelve a abrir la terminal y comprueba:

node --version

Debe mostrar v20 o un número mayor (por ejemplo v22.11.0).

  • Windows: winget install OpenJS.NodeJS.LTS

  • macOS: brew install node@22 con Homebrew

  • Linux: nvm y luego nvm install 22

Paso 2 · Descarga el navegador que usa la herramienta

cvlac-mcp maneja CvLAC con su propia copia de Chromium, un navegador que funciona sin ventana. Se descarga una sola vez (unos 150 MB):

npx -y cvlac-mcp@1 install-browser

Al final debe decir que Chromium quedó instalado.

Un antivirus (Avast, ESET, Kaspersky…) o la red de tu universidad revisa el tráfico con su propio certificado de seguridad. Dile a Node que confíe en los certificados de tu sistema (necesita Node 22.15 o superior):

$env:NODE_OPTIONS="--use-system-ca"; npx -y cvlac-mcp@1 install-browser   # Windows (PowerShell)
NODE_OPTIONS=--use-system-ca npx -y cvlac-mcp@1 install-browser           # macOS / Linux

Con un Node anterior, exporta el certificado raíz del antivirus o de la red y apunta a él con NODE_EXTRA_CA_CERTS=/ruta/al/certificado.pem.

install-browser usa el Playwright que trae este paquete. npx playwright install baja la última versión, y puede dejarte un Chromium que este servidor no sabe abrir (Executable doesn't exist).

El @1 fija la versión mayor: recibes arreglos, pero ningún cambio incompatible sin enterarte. En algunas distribuciones de Linux hace falta además npx playwright install-deps chromium.

Paso 3 · Guarda tus datos de acceso

Van en un archivo de texto aparte, dentro de tu carpeta de usuario, que solo tú puedes leer.

Windows — en PowerShell:

mkdir "$HOME\.config\cvlac-mcp" -Force
notepad "$HOME\.config\cvlac-mcp\.env"

El Bloc de notas pregunta si quieres crear el archivo: di que sí. Pega estas tres líneas, cambia lo que está entre comillas por tus datos, conserva las comillas simples y guarda con Ctrl + S:

CVLAC_NOMBRE='Tu primer nombre'
CVLAC_CEDULA='1234567890'
CVLAC_PASSWORD='tu clave'

Cierra el Bloc de notas y deja el archivo legible solo por tu usuario:

icacls "$HOME\.config\cvlac-mcp\.env" /inheritance:r /grant:r "${env:USERNAME}:(R,W)"

macOS / Linux — cambia los tres valores antes de pegar, conservando las comillas simples:

mkdir -p ~/.config/cvlac-mcp
cat > ~/.config/cvlac-mcp/.env <<'EOF'
CVLAC_NOMBRE='Tu primer nombre'
CVLAC_CEDULA='1234567890'
CVLAC_PASSWORD='tu clave'
EOF
chmod 600 ~/.config/cvlac-mcp/.env
  • CVLAC_NOMBRE es tu primer nombre tal como lo registraste en CvLAC, con tildes y ñ.

  • Las comillas simples importan: sin ellas, una clave con # se corta ahí.

  • No guardes este archivo en Escritorio ni en Documentos si esas carpetas se sincronizan con OneDrive o Google Drive. La carpeta de arriba no se sincroniza.

$contenido = @'
CVLAC_NOMBRE='Tu primer nombre'
CVLAC_CEDULA='1234567890'
CVLAC_PASSWORD='tu clave'
'@
[IO.File]::WriteAllText("$HOME\.config\cvlac-mcp\.env", $contenido)

@'...'@, con comilla simple, no toca un $ que haya en tu clave; @"..."@ sí lo cambiaría. WriteAllText guarda en UTF-8. Si el archivo te quedó en otra codificación —Out-File y > guardan en UTF-16, y Set-Content en ANSI—, cvlac-mcp lo detecta, lo lee igual y lo anota en su registro al arrancar.

Paso 4 · Conecta cvlac-mcp con Claude Desktop

  1. Abre Claude Desktop y ve a Configuración → Desarrollador → Editar configuración (en inglés: Settings → Developer → Edit Config). Se abre la carpeta con el archivo claude_desktop_config.json: ábrelo con el Bloc de notas o TextEdit.

  2. Pega el bloque de tu sistema, cambiando TU_USUARIO por tu usuario del computador. Para saber cuál es: echo $env:USERNAME en PowerShell, o whoami en la terminal de macOS.

Windows:

{
  "mcpServers": {
    "cvlac-mcp": {
      "command": "cmd",
      "args": ["/c", "npx", "-y", "cvlac-mcp@1"],
      "env": {
        "CVLAC_ENV_FILE": "C:\\Users\\TU_USUARIO\\.config\\cvlac-mcp\\.env"
      }
    }
  }
}

macOS (en Linux, la ruta empieza por /home/ en vez de /Users/):

{
  "mcpServers": {
    "cvlac-mcp": {
      "command": "npx",
      "args": ["-y", "cvlac-mcp@1"],
      "env": {
        "CVLAC_ENV_FILE": "/Users/TU_USUARIO/.config/cvlac-mcp/.env"
      }
    }
  }
}
  1. Guarda y cierra Claude Desktop del todo; no basta con cerrar la ventana. En Windows, clic derecho en su ícono junto al reloj → Salir. En macOS, Cmd + Q. Luego ábrelo de nuevo.

Detalles que suelen fallar:

  • Si el archivo ya tenía algo, no lo reemplaces: agrega "cvlac-mcp": {...} dentro del "mcpServers" que ya existe, separado con una coma.

  • En Windows las barras de la ruta van dobles (\\), porque el archivo es JSON. cmd /c va delante porque en Windows npx no es un programa sino un script.

  • CVLAC_ENV_FILE es obligatorio: le dice a cvlac-mcp dónde quedó el archivo del paso 3.

Paso 5 · Pruébalo

En un chat nuevo de Claude Desktop, escribe:

  1. "Inicia sesión en CvLAC" — debe responder que inició sesión.

  2. "Muéstrame mi formación académica en CvLAC" — debe listar lo que ya tienes.

Si las dos funcionan, quedó listo. La primera vez puede tardar unos 15 segundos en conectar, porque se descarga el paquete; si aparece desconectado, espera un momento y reinicia Claude Desktop.

¿Algo falló? → Problemas frecuentes.

Otras apps de IA

La configuración es la misma del paso 4 en todas; cambia dónde se pega.

App

Dónde va

Claude Code

Con un comando, abajo

Cursor

~/.cursor/mcp.json · Windows: %USERPROFILE%\.cursor\mcp.json

VS Code (Copilot, modo agente)

Command Palette → MCP: Open User Configuration. La clave es "servers" en vez de "mcpServers", y cada servidor lleva además "type": "stdio"

Windsurf

~/.codeium/windsurf/mcp_config.json

Zed

settings.json, bajo "context_servers", con "source": "custom"

JetBrains

Settings → Tools → AI Assistant → Model Context Protocol (MCP) → Add; acepta el mismo JSON

Claude Code:

# macOS / Linux
claude mcp add cvlac-mcp --scope user -e CVLAC_ENV_FILE=$HOME/.config/cvlac-mcp/.env -- npx -y cvlac-mcp@1

# Windows, desde Git Bash
MSYS_NO_PATHCONV=1 claude mcp add cvlac-mcp --scope user -e 'CVLAC_ENV_FILE=C:\Users\TU_USUARIO\.config\cvlac-mcp\.env' -- cmd /c npx -y cvlac-mcp@1

En Git Bash, sin MSYS_NO_PATHCONV=1, el /c se convierte en C:/ y el servidor no conecta. Desde PowerShell el comando falla con unknown option '-y', porque PowerShell se come el --: usa Git Bash, pon --% antes de los argumentos, o pega el JSON de Windows con claude mcp add-json.

Qué pedirle

Habla normal, en español. Algunas ideas:

Quieres…

Escribe algo como…

Ver lo que tienes

"Muéstrame mis cursos en CvLAC"

Ver un registro completo

"Muéstrame todos los datos guardados del proyecto X"

Agregar algo

"Agrega el curso 'Escritura científica' que tomé en 2025, 40 horas"

Corregir algo

"En mi formación, la maestría terminó en 2019, no en 2018"

Borrar algo

"Borra el evento 'Prueba'" — te pedirá confirmación antes

Preparar un artículo desde un DOI

"Busca este DOI y muéstrame los datos antes de registrarlo: 10.…"

Registrar producción

"Registra mi artículo con DOI 10.…" o "Agrega que fui jurado de una tesis de maestría en…"

Actualizar el perfil

"Reemplaza mi texto de perfil por este: …"

Agregar una red académica

"Agrega mi ORCID: https://orcid.org/0000-0000-0000-0000"

Ponerte al día con tu hoja de vida

Pega el texto de tu hoja de vida y di: "Compara esto con mi CvLAC y dime qué falta. No cambies nada todavía."

Consejos:

  • Pide primero ver, después cambiar. "Dime qué agregarías, sin guardar nada" es una buena forma de empezar.

  • Da los datos completos: fechas, institución, horas, ámbito (nacional o internacional). Si falta un dato que CvLAC exige, el asistente te avisa en vez de inventarlo.

  • Revisa en CvLAC lo que quede escrito. Lo que figura en tu hoja de vida es tu responsabilidad, y el asistente, aunque verifica cada guardado, se puede equivocar al interpretar lo que le pides.

Cómo te protege

CvLAC no tiene botón de deshacer, así que cvlac-mcp prefiere preguntar antes que equivocarse:

  • No crea duplicados sin preguntar. Si lo que vas a agregar se parece a algo que ya está, no escribe nada y te muestra los parecidos.

  • No borra a la primera. Todo borrado exige una segunda confirmación, incluido quitar una red académica o un área de actuación.

  • No elige por ti. Si el nombre de una institución coincide con varias en el catálogo de CvLAC —hay seis "Universidad de los Andes"—, te muestra las opciones.

  • No inventa datos. Si falta un dato, te avisa en vez de rellenarlo con algo que suene bien.

  • Comprueba el resultado. No da por guardado algo solo porque envió el formulario: mira cómo respondió CvLAC y, si queda duda, vuelve a leer el registro. Si CvLAC se cae a mitad de un guardado, te dice que no pudo confirmarlo, para que lo revises antes de intentarlo otra vez.

  • Dice qué falló. Si CvLAC rechaza un formulario, te dice qué campo y por qué.

  • Cuida tu cuenta. Si CvLAC rechaza tu clave, no vuelve a intentarlo, para no bloquearte. Además espacia sus visitas a CvLAC para no saturarlo.

Problemas frecuentes

El mensaje dice qué datos faltan y qué archivo buscó:

  • "no existe": la ruta de CVLAC_ENV_FILE en la configuración (paso 4) no apunta al archivo. Revisa el usuario y, en Windows, que las barras sean dobles.

  • "no encontré ninguna variable": el archivo existe pero está vacío o mal escrito. Cada línea debe ser NOMBRE='valor'.

  • "no trae esas": revisa que los nombres estén escritos exactamente como en el paso 3.

cvlac-mcp lo intentó una sola vez, para no bloquear tu cuenta. Revisa en tu archivo:

  • CVLAC_NOMBRE: tu primer nombre, con tildes, tal como lo registraste.

  • CVLAC_CEDULA: solo números, sin puntos.

  • CVLAC_PASSWORD: entre comillas simples.

Antes de volver a intentarlo, entra a mano a CvLAC con esos mismos datos.

  • ¿Cerraste Claude Desktop del todo después de editar la configuración? (paso 4, punto 3)

  • Revisa que el JSON sea válido: comas entre bloques, llaves cerradas, barras dobles en Windows.

  • La primera vez tarda en descargarse: espera un minuto y reinicia.

  • En macOS, si instalaste Node con nvm o Homebrew, Claude Desktop puede no encontrar npx. Pon la ruta completa: en la terminal, which npx te la da (por ejemplo /opt/homebrew/bin/npx), y va en "command".

Falta el navegador, o es de otra versión. Repite el paso 2: npx -y cvlac-mcp@1 install-browser. En Linux, si existe pero no arranca, faltan librerías del sistema: npx playwright install-deps chromium.

MinCiencias tiene caídas frecuentes. cvlac-mcp lo detecta, reintenta con calma y, si sigue caído, te lo dice en vez de reportar tu hoja de vida como vacía. Espera un rato y vuelve a intentarlo. Si fue en medio de un guardado, revisa en CvLAC si quedó antes de repetirlo.

¿Otra cosa? Abre un issue, pero sin tus datos ni capturas con información personal.

Seguridad y privacidad

Qué pasa con tus datos, en concreto:

  • Tus credenciales no salen de tu computador. Viven en el archivo del paso 3. cvlac-mcp las lee al arrancar y las escribe únicamente en el formulario de inicio de sesión de scienti.minciencias.gov.co.

  • No hay servidor intermedio, cuentas, telemetría ni analítica. cvlac-mcp corre como un programa en tu computador y habla directamente con tu app de IA. Solo se conecta a CvLAC, al portafolio que configures y a api.crossref.org cuando pides la consulta DOI de solo lectura.

  • Tu asistente de IA sí ve tu hoja de vida. No tus credenciales —cvlac-mcp nunca las devuelve—, pero sí lo que lee de tu CvLAC, porque eso viaja al chat. Tenlo en cuenta al elegir la app si tu hoja de vida tiene datos sensibles.

  • La sesión vale tanto como tu clave. Para no pedir la clave en cada paso, cvlac-mcp guarda la sesión en .cvlac-session.json, en tu carpeta de usuario. Mientras siga vigente, quien copie ese archivo entra a tu CvLAC y puede modificarlo sin tu clave. En macOS y Linux se crea legible solo por ti; en Windows hereda los permisos de tu carpeta de usuario. Para restringirlo a mano: chmod 600 ~/.cvlac-session.json (macOS/Linux) o icacls "$HOME\.cvlac-session.json" /inheritance:r /grant:r "${env:USERNAME}:(R,W)" (Windows).

  • Ni el archivo de datos ni la sesión en carpetas sincronizadas (OneDrive, Google Drive, Dropbox). Las rutas de esta guía no lo están.

  • Para cerrar la sesión, borra .cvlac-session.json. La próxima vez, cvlac-mcp inicia sesión de nuevo.

  • Los registros no muestran secretos. Aunque actives el modo detallado para depurar, la clave, la cédula y las cookies aparecen como ***. Si configuras CVLAC_LOG_FILE, el archivo se crea con permisos solo para tu usuario (0600).

  • Las capturas de pantalla pueden tener datos personales. Revísalas antes de compartirlas.

  • La navegación autenticada está limitada a CvLAC. inspect_form, screenshot y los enlaces internos solo aceptan HTTPS en scienti.minciencias.gov.co; se rechazan file://, otros hosts y enlaces de acción como borrar/guardar.

  • El navegador conserva el sandbox de Chromium por defecto. Solo entornos que no puedan iniciarlo así deben configurar explícitamente CVLAC_NO_SANDBOX=true, entendiendo el riesgo adicional.

  • Si sospechas que se filtró algo, cambia tu clave en CvLAC y borra el archivo de sesión.

Uso responsable

  • Esto automatiza un sitio del Estado colombiano con tu propia cuenta y tus propios datos. No evade la autenticación, no entra a hojas de vida ajenas y no usa ninguna API oculta: hace lo mismo que harías tú en el navegador, más rápido.

  • Revisa los términos de uso de ScienTI/MinCiencias y las políticas de tu institución antes de usarlo.

  • Supervisión humana siempre. Pide ver los cambios antes de aplicarlos, no lo dejes trabajando sin mirar y no lo programes para que corra solo.

  • No lo corras en paralelo sobre varias cuentas ni subas su ritmo de peticiones.

  • Lo que quede en tu hoja de vida es tu responsabilidad. Es una declaración con efectos ante convocatorias y evaluaciones: verifica en CvLAC lo que se haya escrito.

Proyecto independiente. No está afiliado a MinCiencias ni respaldado por esa entidad. No reproduce su logotipo ni su identidad visual: el símbolo de arriba es original —unas llaves { } de JSON-RPC dentro de un anillo de trazos que convergen— y las marcas «CvLAC», «ScienTI» y «MinCiencias» se nombran solo para identificar el sistema con el que habla el servidor.

Actualizar o desinstalar

  • Actualizar: no tienes que hacer nada. Con cvlac-mcp@1, cada vez que abres tu app de IA se usa la última versión 1.x. Si alguna vez sale una 2.x, cambia @1 por @2 en la configuración (lee antes qué cambió en el ROADMAP).

  • Ver qué versión tienes: npx -y cvlac-mcp@1 --version.

  • Desinstalar: quita el bloque "cvlac-mcp" de la configuración de tu app y borra la carpeta .config/cvlac-mcp y el archivo .cvlac-session.json de tu carpeta de usuario.


Para desarrolladores

Todo lo de aquí en adelante es para quien quiera auditar el código, contribuir, usar las herramientas MCP directamente o comparar el CvLAC con un portafolio web.

Servidor MCP (stdio) en TypeScript + Playwright, ESM estricto, probado con Vitest en Linux, Windows y macOS. Qué está verificado, qué falta y las limitaciones conocidas están en el ROADMAP.

Instalación desde el código fuente

Para desarrollar, contribuir o auditar el código. Si solo quieres usar el servidor, la instalación paso a paso es más corta. Sigue los pasos en orden; cada uno incluye una verificación para no avanzar con un entorno roto.

Paso 0 - Prerrequisitos (todas las plataformas)

Necesitas Node.js 20 o superior, npm 10+ y git.

Plataforma

Cómo instalar Node 20+

Linux (Debian/Ubuntu)

curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - && sudo apt-get install -y nodejs git

Linux (cualquier distro, recomendado)

Instalar nvm y luego nvm install 20 && nvm use 20

macOS

brew install node@20 git (con Homebrew) o nvm

Windows

winget install OpenJS.NodeJS.LTS y winget install Git.Git (o instalador desde nodejs.org)

Verifica (sirve igual en bash, zsh o PowerShell):

node --version   # debe mostrar v20.x o superior
npm --version    # debe mostrar 10.x o superior
git --version

Paso 1 - Clonar el repositorio

Linux / macOS (bash o zsh):

cd ~/dev            # o la carpeta que prefieras
git clone https://github.com/stivenson/cvlac-mcp.git
cd cvlac-mcp

Windows (PowerShell):

cd $HOME\dev        # crea la carpeta antes si no existe: mkdir $HOME\dev
git clone https://github.com/stivenson/cvlac-mcp.git
cd cvlac-mcp

Paso 2 - Instalar dependencias y compilar

Igual en las tres plataformas:

npm install
npm run build

Verifica: debe existir el archivo de entrada compilado dist/index.js.

# Linux / macOS
ls dist/index.js
# Windows (PowerShell)
Test-Path dist\index.js   # debe imprimir True

Paso 3 - Instalar el navegador de Playwright

El servidor automatiza CvLAC con Chromium headless. Descarga el build que corresponde a la versión de Playwright del proyecto:

node dist/index.js install-browser

En Linux, si faltan librerías del sistema, instala también las dependencias nativas:

npx playwright install-deps chromium   # requiere sudo en algunas distros

Paso 4 - Configurar variables de entorno (.env)

Copia la plantilla y edita los valores:

Linux / macOS:

cp .env.example .env

Windows (PowerShell):

Copy-Item .env.example .env

Edita .env con tus datos:

CVLAC_NOMBRE='TuNombre'
CVLAC_CEDULA='TuDocumento'
CVLAC_PASSWORD='TuPassword'
PORTFOLIO_URL='https://tu-usuario.github.io'
# Opcional: por defecto, .cvlac-session.json en tu carpeta de usuario
# CVLAC_SESSION_PATH='/ruta/a/tu/.cvlac-session.json'

Restringe los permisos del archivo (Linux/macOS):

chmod 600 .env

En Windows, el equivalente de chmod es icacls .env /inheritance:r /grant:r "${env:USERNAME}:(R,W)".

CVLAC_SESSION_PATH por plataforma (ejemplos, si quieres cambiarlo):

  • Linux: /home/TU_USUARIO/.cvlac-session.json

  • macOS: /Users/TU_USUARIO/.cvlac-session.json

  • Windows: C:\\Users\\TU_USUARIO\\.cvlac-session.json

Paso 4b - Configurar tus valores por defecto (cvlac.config.json)

Varios formularios de CvLAC exigen campos que tu portafolio no tiene (municipio, intensidad horaria, idioma). Se declaran una vez aquí:

cp cvlac.config.example.json cvlac.config.json
{
  "portfolioUrl": "https://tu-usuario.github.io",
  "defaults": {
    "municipio": { "nombre": "Bogotá", "codigoDane": "11001" },
    "institucionFallback": "Universidad Nacional de Colombia",
    "horasSemanales": 1,
    "idioma": "ES",
    "pais": "CO"
  }
}

Todo es opcional. Si un valor falta, el campo se deja vacío y la respuesta trae un warning — el servidor no inventa datos para tu hoja de vida.

Paso 4c - Curar proyectos, software y eventos (data/portfolio-extra.json)

Estas tres secciones no se pueden leer del portafolio: necesitan metadatos que solo existen en CvLAC (tipo de proyecto, código DANE, códigos de enum). Se mantienen a mano:

cp data/portfolio-extra.example.json data/portfolio-extra.json

El archivo se valida al cargarse; si un ítem está mal formado, el servidor lo reporta y sigue con las demás secciones.

Paso 5 - Registrar el MCP en tu app

Igual que en la instalación paso a paso, cambiando npx por node y la ruta a tu dist/index.js. No hace falta CVLAC_ENV_FILE: clonado, el servidor lee el .env de la raíz del repo.

{
  "mcpServers": {
    "cvlac-mcp": {
      "command": "node",
      "args": ["/home/TU_USUARIO/dev/cvlac-mcp/dist/index.js"]
    }
  }
}
  • macOS: "/Users/TU_USUARIO/dev/cvlac-mcp/dist/index.js"

  • Windows: "C:\\Users\\TU_USUARIO\\dev\\cvlac-mcp\\dist\\index.js" (barras dobles en JSON; aquí no hace falta cmd /c, porque node sí es un ejecutable)

  • Claude Code: claude mcp add cvlac-mcp --scope user -- node /ruta/a/cvlac-mcp/dist/index.js

  • Dónde va el JSON en cada app: Otras apps de IA.

Deja las credenciales solo en .env. Los archivos de configuración de las apps suelen estar sin permisos restringidos o sincronizados entre máquinas. Si aun así las pones en un bloque env, ganan sobre el .env.

Paso 6 - Verificar la instalación

  1. Build y tests en verde:

    npm run build
    npm test
  2. Arranque del servidor (sanity check; queda esperando por stdio, ciérralo con Ctrl+C):

    node dist/index.js
  3. En tu editor: reinícialo (Claude Desktop necesita cerrarse del todo) y confirma que cvlac-mcp aparece activo y lista sus tools — Settings → MCP en Cursor, claude mcp list o /mcp en Claude Code, el selector de herramientas del chat agente en VS Code.

  4. Prueba funcional mínima desde el chat de tu editor, en este orden:

    • login (debe autenticar y persistir sesión)

    • read_cvlac con section: "formacion" (debe devolver lo que ya está en CvLAC)

    • si configuraste un portafolio: read_portfolio y luego diff

Si responden sin error, el MCP quedó correctamente instalado y configurado.


Configuración avanzada

Nada de esto hace falta para usar el servidor. Instalado con npx, cada archivo se apunta con una variable en el mismo bloque env de la configuración de tu app, junto a CVLAC_ENV_FILE; clonado, se toman de la raíz del repo.

Variable

Qué apunta

Para qué

CVLAC_CONFIG_PATH

Tu cvlac.config.json

Valores por defecto que CvLAC exige y tu fuente no trae: municipio, institución de respaldo, horas semanales, idioma, país, URL del portafolio (formato)

CVLAC_PORTFOLIO_EXTRA_PATH

Tu portfolio-extra.json

Proyectos, software y eventos curados a mano, para que entren al diff (formato)

Sugerido: guárdalos junto al .env, en ~/.config/cvlac-mcp/. Si falta un valor por defecto, el campo queda vacío y la respuesta trae un warning: el servidor nunca inventa un dato para una hoja de vida.

Comparar con un portafolio (diff y sync)

diff compara el CvLAC con un portafolio web y clasifica cada ítem en cuatro grupos: faltantes, a actualizar, parecidos (algo similar ya existe: decide una persona) y al día. sync previsualiza por defecto; solo aplica los faltantes y los de actualizar cuando se llama con dry_run: false, y nunca los parecidos.

Limitación importante: read_portfolio está hecho para un sitio concreto —una app React con la ruta #/resume, pestañas Experiencia, Educación y Cursos, y una sección "Logros Destacados"— y si no encuentra esa estructura devuelve listas vacías, con un warning en el log. Proyectos, software y eventos no salen del sitio sino de portfolio-extra.json. Tampoco entran al diff: experiencia profesional (los nombres de empresa difieren demasiado), idiomas, líneas ni demás trabajos.

Separar la fuente del motor —que diff acepte un JSON normalizado de hoja de vida, venga de un PDF, de ORCID o del dictado— está en el ROADMAP.

Flujo recomendado:

  1. login

  2. sync con dry_run: true

  3. Revisar el reporte con una persona: faltantes, a actualizar, parecidos y al día

  4. Resolver los parecidos uno a uno — update sobre el existente, o add con confirm_duplicate:true

  5. Aplicar el resto: sync con dry_run: false, o update_section por ítem revisando los warnings

  6. Verificar con read_cvlac de las secciones tocadas, o read_cvlac_detail

read_portfolio ─┐
                ├─► diff ─► sync (dry_run → apply) ─► update_section (add / update / delete)
read_cvlac ─────┘

Si trabajas con Claude Code, la skill cvlac-sync del workspace cliente encapsula este flujo.

Referencia de tools MCP

Tool

Qué hace

login

Autentica en CvLAC y persiste la sesión. force:true vuelve a iniciar sesión. Un rechazo no se reintenta

read_cvlac

Lee una sección o todas (all)

read_cvlac_detail

Abre la ficha completa de un ítem (por sección y etiqueta) y devuelve sus pares campo/valor. Las listas muestran dos o tres columnas; esta es la forma de ver lo que realmente quedó guardado

read_profile

Lee lo que CvLAC guarda como registro único: el texto de perfil, la tabla de redes académicas y las áreas de actuación. Nada de eso sale en read_cvlac

update_profile

Escribe perfil, redes y/o áreas (detalles abajo)

read_portfolio

Renderiza el portafolio de PORTFOLIO_URL y lo une con portfolio-extra.json

diff

Compara CvLAC contra el portafolio: missing, toUpdate, similar, upToDate

lookup_doi

Consulta Crossref sin escribir y devuelve un borrador de artículo para revisar

complete_product

Completa la segunda fase de un producto existente: reemplaza y ordena palabras clave, áreas, coautores y reconocimientos; en tesis vincula estudiantes con su participación. dry_run:true previsualiza; retirar valores requiere confirm_delete:true

update_section

Aplica un cambio puntual: add, update o delete

sync

diff + previsualiza por defecto; dry_run:false aplica missing y toUpdate. Los similar nunca se aplican solos

screenshot

Captura la url dada, o la última lista, ficha o formulario visitado, recargado tal como está ahora. Rechaza los enlaces de acción (borrar, guardar): en CvLAC abrir uno lo ejecuta

inspect_form

Lista los campos reales (input/select/textarea) de una página segura de CvLAC, con sus opciones y cuáles son obligatorios; no abre otros hosts ni enlaces de acción

Una tool que falla devuelve isError: true. needs_confirmation y unverified no son errores: piden que una persona decida o revise.

complete_product

label encuentra un producto existente y la operación recibe una o más listas completas:

  • keywords: palabras clave ordenadas.

  • areas: áreas de conocimiento ordenadas, por nombre o código de CvLAC.

  • coauthors: nombres de coautores ordenados desde el catálogo de perfiles previamente registrados; el propietario de la hoja de vida se conserva automáticamente.

  • recognitions: títulos de reconocimientos ordenados desde los reconocimientos ya registrados en el currículo CvLAC.

  • students: solo para tesis; objetos {name, participation, person_id?}. participation acepta TUT, ASE, COT, ORI o sus etiquetas (Tutor, Asesor, Cotutor, Orientado). Si se omite, se usa ORI.

Las listas reemplazan lo almacenado. Si la operación quitaría valores existentes, primero devuelve needs_confirmation con removed; repite con confirm_delete:true. Una persona no resuelta o con varios perfiles posibles vuelve en choices y no se escribe nada.

update_section

Secciones: formacion, formacionComple, experiencia, cursos, reconocimientos, proyectos, software, eventos, idiomas, lineas, demasTrabajos, articulos, libros, capitulos, tesis, jurados, informesTecnicos, innovacionesProceso, productosTecnologicos, consultorias, prototipos. El esquema de data de cada una está en src/schemas.ts; un campo mal formado se rechaza nombrándolo, antes de abrir el navegador.

status

Significa

ok

Se guardó. Revisa los warnings de todos modos: traen los campos que no se llenaron

needs_confirmation

No se escribió nada. Tres causas: ítems parecidos en similar (repetir con confirm_duplicate:true o hacer update); una institución ambigua con candidatos en choices (repetir con data.institucionId); o un delete sin confirm_delete:true

failed

CvLAC rechazó el formulario. message trae su error, nombrando los campos

unverified

Se envió y no se pudo confirmar, típicamente porque CvLAC se cayó a mitad. No reintentar a ciegas: verificar con read_cvlac_detail

Más detalles:

  • Un update que no logre cambiar ningún campo del formulario no se envía: devuelve failed con los warnings.

  • Una institución con coincidencia exacta se resuelve sola. El catálogo tiene duplicados exactos —seis "Universidad de los Andes"—, así que el nombre no siempre basta.

  • formacionComple usa el mismo formulario que formacion, con otro catálogo de niveles (Y Otros, 8 Extensión, F Cursos de corta duración, E MBA) y startMonth. El add solo funciona con un programa académico que CvLAC ya tenga registrado para esa institución y nivel.

  • libros: certificateCLCDO y certificateCLRI son rutas locales opcionales para los dos certificados PDF del formulario real. Se valida la firma %PDF-, la extensión, que el archivo exista y el límite de 2 MiB antes de enviar. CvLAC no devuelve esos archivos como valores de formulario, así que una edición solo de certificados puede responder unverified; confirma la ficha antes de reintentar.

  • demasTrabajos: name, year, month, medio (Papel, Internet u Otro), finalidad, y opcionalmente idioma y ciudad. El formulario trae Enero y Papel preseleccionados: si faltan month o medio se guardan esos, y lo avisa.

  • idiomas: language (nombre en español o código ISO de 2 letras) y los niveles read/write/speak/listen, o un level que los fija todos: Deficiente, Aceptable o Bueno.

  • lineas: name, active (por defecto true, y lo avisa) y objective.

  • experiencia: el formulario de CvLAC no tiene campo de cargo; si el ítem trae role, se avisa que no se escribió.

update_profile

  • description reemplaza el texto de perfil. No se puede vaciar: CvLAC lo marca obligatorio (máx. 3950 caracteres).

  • networks se fusionan con lo guardado: el formulario de CvLAC reescribe la tabla entera, así que la tool la lee primero y reenvía todo. url:null quita una red y exige confirm_delete:true. Redes aceptadas: google_scholar, researchgate, ssr, ssrn, academia_edu, mendeley, linkedin, repositorios_disciplinares, repositorios_institucionales, researcher_id, scopus_author_id, orcid y otro (con su nombre en label).

  • areas es la lista completa de áreas de actuación en orden —la primera es la principal—, por nombre o por código de CvLAC (0-1B01). Reemplaza lo guardado: dejar una fuera es borrarla y exige confirm_delete:true. El catálogo tiene 267 áreas en tres niveles; un nombre ambiguo vuelve en choices en vez de adivinarse.

Variables de entorno

Se definen en el .env, o en el bloque env de la configuración de la app, que tiene prioridad.

Variable

Descripción

CVLAC_NOMBRE

Primer nombre con el que inicias sesión en CvLAC

CVLAC_CEDULA

Documento de identidad

CVLAC_PASSWORD

Contraseña de CvLAC

CVLAC_ENV_FILE

Ubicación del propio .env. Imprescindible instalado desde npm, donde el servidor corre desde la caché de npx. Va en la configuración de la app, no en el .env

CVLAC_SESSION_PATH

Dónde se guarda la sesión. Por defecto, .cvlac-session.json en la carpeta de usuario

PORTFOLIO_URL

Portafolio a comparar. También configurable como portfolioUrl en cvlac.config.json

CVLAC_CONFIG_PATH

Ubicación de cvlac.config.json

CVLAC_PORTFOLIO_EXTRA_PATH

Ubicación de portfolio-extra.json

CVLAC_HEADLESS

false abre el navegador para ver qué hace

CVLAC_NO_SANDBOX

true desactiva el sandbox de Chromium solo en entornos que no puedan iniciarlo; no recomendado

CVLAC_LOG_LEVEL

debug | info (default) | warn | error | silent. Los logs van a stderr

CVLAC_LOG_FILE

Además de stderr, agrega cada línea a este archivo

CVLAC_USER_AGENT

Reemplaza el user-agent. Por defecto se usa el del Chromium real, que coincide con el sistema

Al arrancar, el servidor escribe en stderr qué .env leyó: env file: <ruta> (found, 3 vars), o NOT FOUND, o read as utf16le / read as latin1 si no estaba en UTF-8.

Ritmo de las peticiones

CvLAC empieza a responder 5xx cuando las peticiones llegan pegadas. El servidor espacía cada navegación, reintenta con backoff y, si el sitio rechaza varias seguidas, deja de insistir hasta que pase un enfriamiento. Los valores por defecto sirven para un sync normal; súbelos si notas 503 seguidos:

Variable

Default

Descripción

CVLAC_MIN_REQUEST_GAP_MS

900

Espera mínima entre dos peticiones

CVLAC_REQUEST_JITTER_MS

700

Aleatorio que se suma a esa espera, para no tener un ritmo de máquina

CVLAC_NAV_TIMEOUT_MS

30000

Cuánto esperar a que cargue una página

CVLAC_NAV_MAX_ATTEMPTS

3

Intentos por navegación (5xx o timeout). 1 desactiva reintentos

CVLAC_BACKOFF_BASE_MS

2000

Espera tras el primer fallo; se duplica en cada intento

CVLAC_BACKOFF_CAP_MS

30000

Techo de esa espera

CVLAC_OUTAGE_THRESHOLD

3

Navegaciones fallidas seguidas antes de cortar el tráfico

CVLAC_OUTAGE_COOLDOWN_MS

120000

Cuánto se queda quieto tras cortar

Arquitectura

src/
├── index.ts                  # Entry point: subcomandos, carga del .env, stdio transport
├── cli.ts                    # install-browser, --version, --help
├── env.ts                    # Ubicación y lectura del .env (UTF-8, UTF-16 o ANSI)
├── server.ts                 # Registro de tools MCP, isError
├── types.ts                  # Tipos de portfolio/CvLAC/diff/update
├── schemas.ts                # Un schema zod por sección
├── config.ts                 # cvlac.config.json
├── logger.ts                 # Logs a stderr, con secretos ocultos
├── diff.ts                   # Motor de comparación (normalize + nameMatches)
├── browser/
│   ├── session.ts            # Login, sesión persistente, Playwright context
│   ├── navigation.ts         # URLs de listas y formularios CvLAC
│   ├── navigate.ts           # Toda navegación: ritmo, reintentos, cortes
│   ├── pacing.ts             # Espaciado de peticiones y backoff
│   ├── availability.ts       # Distingue "CvLAC caído" de un error propio
│   └── catalogue.ts          # Catálogos de CvLAC (municipios, instituciones)
├── tools/
│   ├── login.ts  read-cvlac.ts  read-cvlac-detail.ts  read-portfolio.ts  diff.ts  sync.ts
│   ├── update-section.ts     # add/update/delete por sección
│   ├── write-verdict.ts      # ¿Se guardó? saved / rejected / unverified
│   ├── profile.ts            # Perfil y redes académicas
│   ├── areas.ts              # Áreas de actuación
│   └── screenshot.ts
└── extractors/
    ├── portfolio.ts          # Renderiza el portafolio + portfolio-extra.json
    └── cvlac/                # Un extractor por sección, sobre rows.ts

Las decisiones de diseño y las trampas de CvLAC que ya costaron un bug están en CLAUDE.md, y las URLs, columnas y nombres de campos verificados en vivo, en docs/cvlac-findings.md.

Pruebas y build

npm test          # suite completa: sin red, sin credenciales, sin CvLAC
npm run build     # compila src/ a dist/, que es lo que ejecuta la app
npm run dev       # corre src/ con tsx, sin compilar
npm run test:watch

Los tests cubren extractores (contra fixtures HTML anonimizados), el motor de diff, los schemas, la carga de configuración y del .env, la redacción de secretos en logs, el reporte de sync, el borde MCP y la lectura de fichas de detalle. Los fixtures llevan datos ficticios a propósito: si capturas HTML real para uno nuevo, anonimízalo antes de commitear.

El workflow smoke corre en Linux, Windows y macOS: compila, corre los tests, instala Chromium con install-browser y ejecuta scripts/smoke.mjs, que comprueba el arranque, el protocolo MCP, las tools registradas, el mensaje sin credenciales y que el navegador abra. Otro job escribe el .env en PowerShell 5.1 y 7 de las tres formas habituales y verifica que el servidor lo lea. Lanzado a mano, prueba además el paquete tal como se instala desde npm.

Suite en vivo (opcional, escribe en tu CvLAC real)

CVLAC_E2E=1 npm run test:e2e:live                      # las secciones con lista
CVLAC_E2E=1 npm run test:e2e:live -- --sections=cursos  # solo una
CVLAC_E2E=1 npm run test:e2e:live -- --sections=perfil  # perfil y redes

Recorre el CRUD completo por sección contra tu cuenta real: lista → add → lista → read_cvlac_detail → add repetido (debe devolver needs_confirmation) → update → detalle para comprobar el cambio → delete → lista final. Cada ítem que crea lleva el prefijo ZZ PRUEBA MCP, siempre intenta borrarlo y, si algo sobrevive, lo reporta al final para que lo borres a mano. --sections=perfil toma un snapshot, escribe en una red que nadie use, la edita, la borra y restaura lo que había.

Es la única suite que toca datos reales: por eso exige CVLAC_E2E=1 y no corre con npm test. Habla con dist/index.js, así que va después de npm run build. Deja el reporte en tests/e2e/report-<fecha>.json (gitignored).

Problemas de desarrollo

  • La app usa una versión vieja del código: ejecuta npm run build tras cambiar src/. La app corre dist/index.js, no src/index.ts.

  • No aparece en la app (instalación clonada): revisa la ruta absoluta a dist/index.js en args, con barras dobles en Windows, y reinicia la app.

  • Un formulario no guarda un campo: varios campos de CvLAC son readonly y se llenan por JS. Usa inspect_form para ver los nombres reales, CVLAC_HEADLESS=false para ver el navegador y CVLAC_LOG_LEVEL=debug para el detalle de cada campo.

  • Falsos faltantes en diff: nameMatches() normaliza tildes y sufijos ((en línea), - Aprobado ...); la experiencia está fuera del diff a propósito.

Estado y roadmap

Las 11 secciones originales, el perfil, las redes académicas y las áreas de actuación se leen y escriben (add/update/delete), con CRUD verificado contra el CvLAC real. También están implementadas las secciones de artículos, libros, capítulos, tesis, jurados y producción técnica. El CRUD real se verificó completo en artículos; en informes técnicos y consultorías se verificaron altas, listado, detalle, bloqueo de duplicados y borrado. Algunos campos de edición dependen de variaciones del formulario real y quedan documentados en el roadmap. El diff y el bloqueo de duplicados también cubren las listas completas mediante paginación JMesa.

complete_product ya completa palabras clave, áreas, coautores y reconocimientos de productos existentes, y vincula estudiantes de tesis con su participación. Los libros también aceptan las rutas locales certificateCLCDO y certificateCLRI en update_section; cada PDF debe pesar como máximo 2 MiB. La operación fue verificada e2e con registros temporales.

Detalle completo, limitaciones conocidas y lo que sigue: ROADMAP.

Available Tools

13 tools
complete_productA
Destructive

Complete the post-save CvLAC phase for an existing product. It manages ordered keywords, knowledge areas, coauthors and recognitions; for theses it also links students with their participation. It reads current values, resolves catalogue names, and never removes an existing value without confirm_delete:true. Use dry_run:true to preview catalogue resolution and removals without writing.

ParametersJSON Schema
NameRequiredDescriptionDefault
areasNoComplete ordered replacement list of product knowledge areas, by code or name
labelYesExact title as shown in the section list
dry_runNoPreview without creating keywords or submitting lists
sectionYesProduct section containing the existing item
keywordsNoComplete ordered replacement list of product keywords
studentsNoComplete thesis student list; each item may use participation TUT, ASE, COT or ORI
coauthorsNoComplete ordered replacement list of coauthor names; the CvLAC owner is preserved
recognitionsNoComplete ordered replacement list of recognition titles already registered in CvLAC
confirm_deleteNoRequired when the replacement drops existing keywords, areas, coauthors or recognitions, or unlinks thesis students

TDQS

A3.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the destructiveHint=true annotation, the description discloses the concrete behavior: it reads current values, resolves catalogue names, and 'never removes an existing value without confirm_delete:true.' It also explains that dry_run previews catalogue resolution and removals without writing, which is exactly the operational detail an agent needs for a destructive tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with purpose followed by scope and safety semantics; no filler. Slightly dense but every sentence carries information about behavior.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive mutation tool with no output schema, the description covers scope, ordering semantics, the confirm_delete guard, and the dry_run preview, which is enough to call it correctly. It stops short of describing what a successful run returns, but that is a minor gap given the otherwise thorough coverage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents all nine parameters including dry_run and confirm_delete. The description reinforces the dry_run/confirm_delete semantics but adds no syntax or format detail the schema lacks, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and scope: 'Complete the post-save CvLAC phase for an existing product,' then enumerates the managed sub-resources (keywords, areas, coauthors, recognitions, thesis students). This is far more than a restatement of the name, though it never explicitly names or contrasts a sibling like update_section.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives workflow guidance ('Use dry_run:true to preview...', confirm_delete needed for removals), which tells the agent how to invoke it safely, but it never states when to reach for this tool versus read_cvlac, update_section, or sync. Usage context is implied rather than spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

diffA
Read-only

Compare CvLAC vs portfolio. Returns four buckets: missing, toUpdate, similar (close to an existing entry — a human decides) and upToDate.

ParametersJSON Schema
NameRequiredDescriptionDefault
sectionNoLimit diff to a specific section

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so safety is covered. The description adds real value beyond that by disclosing the four result buckets and flagging that 'similar' entries require human judgment, which is meaningful since no output schema exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero waste, with the core purpose front-loaded and the return structure following immediately after. Every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description must carry return-value meaning, and it does list the four buckets. However, it never states the direction of the diff (missing from which side) or what distinguishes 'missing' from 'toUpdate', leaving a real ambiguity for a comparison tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single section parameter has an exhaustive enum, so the schema fully documents the input. The description adds no semantics about the section filter, making the baseline 3 appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb (compare) and both resources (CvLAC vs portfolio), so the agent knows exactly what the tool operates on. It does not explicitly name the sibling sync or explain how this differs from it, so it falls short of full sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: comparison-before-action, with 'a human decides' hinting at decision support rather than automated sync. There is no explicit statement of when to choose this over sync or when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

inspect_formA
Read-only

Navigate to a CvLAC URL and return the HTML of all form inputs/selects/textareas for debugging field names.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesThe CvLAC URL to inspect

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, and the description usefully adds that the tool performs a network navigation and returns raw HTML of form elements. It omits auth/session requirements, which matters given a sibling 'login' tool exists, and says nothing about rate limits or fetch failures.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with the action first and the return payload second; nothing is wasted. It is appropriately sized for a one-parameter debugging tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-param tool with annotations covering the safety profile and no output schema, the description tells the agent both what it does and what it returns. Only the auth/network-side-effect details are missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There is only one parameter and schema description coverage is 100%, so the schema already documents it fully. The description reinforces that the URL must be a CvLAC URL, but adds no format or syntax detail beyond that.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb+resource: it navigates to a CvLAC URL and returns the HTML of form inputs/selects/textareas. This clearly separates it from content-reading siblings like read_cvlac or read_portfolio, though it never explicitly names those alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'for debugging field names' states a concrete use context, so an agent knows this is a diagnostics/introspection call rather than a data-retrieval one. It stops short of naming when NOT to use it or pointing at a sibling alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

loginB

Authenticate in CvLAC and persist the browser session.

ParametersJSON Schema
NameRequiredDescriptionDefault
forceNoForce re-login even if session is valid

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false and destructiveHint=false, so the agent knows this mutates state without being destructive. The description usefully adds that the session is persisted, but says nothing about where credentials come from, what happens on failed authentication, or whether re-login invalidates an existing session.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence that names the verb, the target system, and the persistence side effect with zero filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a trivial one-parameter schema, full schema coverage, and annotations covering the safety profile, the description is close to sufficient. The remaining gap is meaningful for an auth tool: it never explains credential sourcing or failure/lockout behavior, which an agent needs before invoking login.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single optional 'force' parameter is fully documented in the schema itself ('Force re-login even if session is valid'). The description adds no parameter-level meaning beyond that, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Authenticate in CvLAC') plus the side effect of persisting the browser session. No sibling tool performs authentication, so it is inherently distinct, but the description does not explicitly claim that uniqueness.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use or when-not-to-use guidance and no mention of alternatives or prerequisites relative to the read_*/update_* siblings. The mention of persisting a session only weakly implies this must precede session-dependent calls.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

lookup_doiA
Read-only

Read-only: look up a DOI in Crossref and return an article draft. Review it, then pass it to update_section with section:"articulos"; this tool does not write to CvLAC.

ParametersJSON Schema
NameRequiredDescriptionDefault
doiYesDOI, doi:... or https://doi.org/...

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, and the description reinforces this consistently ("Read-only", "does not write to CvLAC"). It adds useful context that the output is a draft requiring human/agent review before being written, though it says nothing about failure modes such as unresolvable DOIs or network limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single tight sentence that front-loads the read-only nature and the purpose, then the workflow handoff. No filler and nothing repeated from the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read tool with no output schema, the description covers the input source, the read-only guarantee, and what is returned (an article draft), plus the next step. Nothing essential for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single doi parameter already documents accepted formats (DOI, doi:..., https://doi.org/...). The description adds no additional syntax or handling detail beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (look up), resource (a DOI in Crossref) and the result (an article draft), and distinguishes itself from siblings by declaring it does not write to CvLAC and by naming update_section as the follow-up tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit workflow: review the returned draft, then pass it to update_section with section:"articulos". It also states the boundary condition (this tool does not write to CvLAC), so the agent knows exactly where this tool's role starts and stops.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_cvlacB
Read-only

Read current CvLAC sections, including articles, books, chapters, theses, juries and five kinds of technical production. Returns existing items for comparison; list results include every JMesa page.

ParametersJSON Schema
NameRequiredDescriptionDefault
sectionNoWhich section to read. Defaults to all.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safe-read profile is covered. The description adds a scope note that list results include every JMesa page and that output is suitable for comparison, but gives no pagination, volume, or failure behavior. Adding some context on top of annotations merits a 3.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two compact sentences with the resource and scope front-loaded and no filler. The trailing clause about JMesa pages is slightly cryptic but still earns its place by clarifying output scope.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read tool with full schema coverage, annotations, and no output schema, the description covers the essentials. It is adequate but leaves the key ambiguity unresolved: how it differs from read_cvlac_detail and what 'five kinds of technical production' maps to in the enum.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single section parameter is fully enumerated with a documented default, so the schema carries parameter meaning. The description's section list ('articles, books, chapters, theses, juries') maps only loosely to enum values and adds no syntax or default details. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Read) and resource (current CvLAC sections) and enumerates the content types returned (articles, books, chapters, theses, juries, technical production). It does not differentiate itself from the sibling read_cvlac_detail, so an agent must infer which read tool to pick.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Returns existing items for comparison" implies the intended workflow (fetch current state before diffing/updating), which is a useful usage hint. However, no explicit when-to-use, when-not, or named alternative (e.g., read_cvlac_detail vs read_cvlac) is given, leaving selection to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_cvlac_detailA
Read-only

Read the full record page of one CvLAC item. The list views only show a couple of columns, so this is the only way to see the fields a write actually stored (role, dates, institution, financing). Finds the row by label, case- and accent-insensitive.

ParametersJSON Schema
NameRequiredDescriptionDefault
labelYesName/title as it appears in the section list, e.g. the degree for formacion
sectionYes

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so safety is covered. The description adds matching semantics (finds the row by label, case- and accent-insensitive) and enumerates what is revealed (role, dates, institution, financing), which goes beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core purpose and the reason to prefer it over list views. No wasted filler, though the parenthetical field list is slightly list-heavy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only detail tool with no output schema, the description conveys the return content and matching behavior. The main gap is lack of documented semantics for the section enum, which the schema leaves bare.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 50%: label is described in the schema but section is only an enum. The description clarifies that section identifies the list and that label is the name/title as it appears there (e.g. degree for formacion), adding modest value but not fully compensating for the undocumented section values.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Read the full record page of one CvLAC item.' It distinguishes itself from the list views by contrast, though it doesn't name the sibling tool (read_cvlac) explicitly, leaving differentiation partly implicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear context for when to use it — to see the fields a write actually stored, since list views only show a couple of columns. No explicit when-not or named alternative, but the intended use case is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_portfolioB
Read-only

Read and parse the configured portfolio site (PORTFOLIO_URL), merged with the curated proyectos/software/eventos from data/portfolio-extra.json.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description contributes the useful disclosure that output is a merge of a remote site and a local curated file, which explains non-obvious result composition, but it says nothing about caching, network failure behavior, or return shape.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence that carries the source information with no filler. It is appropriately sized for a no-argument read tool, though the parenthetical file reference is slightly dense.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and no parameters, the description is the only place an agent could learn what comes back. It identifies the data sources but not the returned structure (parsed site fields, the proyectos/software/eventos sections), leaving a moderate gap for a read tool that merges two sources.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline of 4 applies. The description correctly signals there is nothing to configure per call, other than implying PORTFOLIO_URL is environment-level configuration.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb+resource ('Read and parse the configured portfolio site') and even names the underlying data sources (PORTFOLIO_URL, data/portfolio-extra.json). That distinguishes it from read_cvlac and read_profile, though it does not explicitly contrast itself with those siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use or when-not-to-use guidance is provided. An agent cannot tell from the text whether this should be preferred over read_profile or read_cvlac, or whether it must be preceded by login.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_profileA
Read-only

Read the two CvLAC pages that hold one record instead of a list: the researcher profile text (txt_desc_perfil), the table of academic social networks (Google Scholar, ORCID, LinkedIn, Scopus...) and the áreas de actuación. None of them appears in read_cvlac.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so safety is covered. The description adds useful scope context by naming the exact content types retrieved, but says nothing about authentication requirements, pagination, or what happens when a profile field is empty.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler; the key scoping claim ('record instead of a list') comes first. Slightly dense with the parenthetical list, but every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and no parameters, the description compensates by enumerating the returned content (profile text, social networks table, áreas de actuación). That is adequate for a parameterless read tool, though a note on behavior for missing fields would complete it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4; there is nothing for the description to disambiguate. The description correctly does not fabricate parameter guidance.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Read) and resource (CvLAC profile pages) and explicitly scopes the content to fields that are single-record rather than list-based. It also names the sibling read_cvlac as the place these fields do NOT appear, aiding disambiguation. Minor ambiguity: it says 'two pages' but then enumerates three distinct items (profile text, social networks table, áreas de actuación).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives one negative routing cue ('None of them appears in read_cvlac'), which implies when to prefer this tool, but never states a positive when-to-use condition or contrasts against other siblings like read_cvlac_detail or read_portfolio. Usage is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

screenshotA
Read-only

Capture a CvLAC page for debugging: the given url, or else the last list, record or form page a tool visited, reloaded as it is now. Action links (delete, save) are refused, because in CvLAC opening one performs it.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlNoA CvLAC list, record or form page. Defaults to the last one visited.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds real behavioral context beyond the readOnlyHint/destructiveHint annotations: action links (delete, save) are refused because merely opening them in CvLAC performs the action, and the capture reflects the page 'as it is now' (live reload, not cached). It doesn't describe the returned artifact (image vs. path) or any rate/latency concerns.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with no filler; the core action and its default are front-loaded, and the constraint clause follows logically. Every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single optional-parameter read-only tool with no output schema, the description covers action, default resolution, and the key side-effect safeguard. The only gap is what the capture actually returns, which is largely self-evident for a screenshot tool but not stated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the url parameter and its default are already documented. The description reinforces the default ('or else the last list, record or form page a tool visited') and clarifies which page types qualify, but adds no new syntax or format detail beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Capture a CvLAC page') plus intent ('for debugging'), so an agent knows this renders a page rather than reading its content. It doesn't explicitly distinguish itself from siblings like read_cvlac or inspect_form, but the differentiated 'screenshot' verb is inferable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains the default behavior (falls back to the last list/record/form page a tool visited), which is useful invocation context, but it never states when to choose this over read_cvlac, read_cvlac_detail, or inspect_form. Usage is implied rather than stated with alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

syncA
Destructive

Run a full diff and apply the unambiguous items (missing + toUpdate). Items that resemble existing CvLAC entries are never written; they are listed for a human to resolve. It previews by default; pass dry_run:false to apply changes explicitly.

ParametersJSON Schema
NameRequiredDescriptionDefault
dry_runNoPreview changes without applying them. Defaults to true; use false to write.
sectionsNoLimit sync to specific sections

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructive=true and readOnly=false, so the write profile is known. The description adds real value beyond that: preview-by-default, and the safety rule that ambiguous/duplicate-looking entries are never written but surfaced for human resolution.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with what it does, followed by the safety rule and the invocation detail. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, yet the description conveys the outcome semantics (unambiguous items written, ambiguous items listed for human review) and the default/override behavior. It does not describe any return payload structure, which is the only remaining gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema already documents dry_run's default and meaning. The description reinforces the dry_run:false invocation but adds no new syntax or constraints for 'sections', so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific action (run a full diff and apply unambiguous items) on a specific resource (CvLAC entries), and contrasts implicitly with the sibling 'diff' by emphasizing that sync applies changes. The domain terms 'missing + toUpdate' are precise. It is clear but never explicitly names the sibling it differs from.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives useful behavioral guidance (default preview, dry_run:false to apply, ambiguous items deferred to a human), which implies when to use it over 'diff'. However it never states when to prefer 'diff' or 'update_section', so the agent must infer the routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_profileA
Destructive

Write the researcher profile text and/or the academic social networks. Networks are MERGED over what CvLAC already stores — its form rewrites the whole table, so this reads it first and posts everything back. Pass url:null to remove one. A network CvLAC does not list goes in "otro" with its name in "label". Removing one needs confirm_delete:true. The profile text cannot be blanked: CvLAC marks it required. The areas list is replaced whole, so dropping one also needs confirm_delete:true.

ParametersJSON Schema
NameRequiredDescriptionDefault
areasNoThe whole list of áreas de actuación, in order — the first is the main one — by name or by CvLAC code. It replaces what is stored, so anything left out is a removal. An ambiguous name comes back in "choices" instead of being guessed.
networksNoNetworks to set or remove. Everything else stored is kept.
descriptionNoReplaces the profile text. Omit to leave it untouched.
confirm_deleteNoRequired when a network carries url:null or the areas list drops one. Without it nothing is written.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the destructiveHint=true annotation: networks are MERGED (reads existing state first and posts everything back because the form rewrites the whole table), areas are replaced whole so omissions count as removals, and confirm_delete gates all deletions. This discloses exactly what gets destroyed and the read-then-write mechanics.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, then dense but purposeful sentences on merge/removal semantics. Every sentence carries a distinct constraint; it is long but not padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with no output schema, it covers what is overwritten, deletion gating, the non-blankable profile text, and the ambiguity fallback. It omits any permission/auth requirements, which is a minor gap given the destructive nature.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% so the baseline is 3, but the description adds cross-parameter semantics the schema does not: the read-modify-write behavior behind the merge, the confirm_delete gate shared by url:null and areas removal, and the 'choices' fallback for ambiguous names. This meaningfully augments the per-field schema text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (write) and resource (researcher profile text and academic social networks), and distinguishes itself from read-oriented siblings like read_profile and read_cvlac. An agent can identify the tool's scope immediately.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains the conditions that govern use: url:null removes a network, confirm_delete:true is required for removals, and the profile text cannot be blanked. It does not explicitly contrast itself with update_section or sync, but the operational context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_sectionA
Destructive

Apply a single change to a CvLAC section. Takes a screenshot for confirmation. An "add" whose item resembles an existing entry returns status "needs_confirmation" and writes nothing; resolve it with action:"update" or repeat with confirm_duplicate:true. A "delete" also writes nothing until it is repeated with confirm_delete:true. A picker whose search matched several rows — a common university name can match close to 200 institutions in CvLAC — also returns needs_confirmation, with the candidates in "choices"; repeat with the chosen id in data.institucionId. For articles provide title, year and issn/revista; for books provide title, isbn, year, editorial and area; for chapters provide title, bookTitle, year and area; for theses provide title, tipo, year, institution and programme; for juries provide title, nivel, year, orientado, institution and programme; technical sections require title and year, with section-specific fields. Catalogue choices are answered by repeating the call with revistaId, libroId, editorialId, programaId, areaId or institucionId in data. Coauthors, keywords, recognitions and linked thesis students are completed from the CvLAC website. For books, certificateCLCDO and certificateCLRI accept local PDF paths (maximum 2 MiB each).

ParametersJSON Schema
NameRequiredDescriptionDefault
dataYesThe item data to add/update
actionYes
sectionYes
confirm_deleteNoRequired by action:"delete". Without it nothing is removed and the call returns needs_confirmation — CvLAC has no undo.
confirm_duplicateNoCreate the item even though CvLAC already holds a similar one

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Far exceeds the annotations: it discloses the needs_confirmation contract for adds, deletes and ambiguous pickers, that nothing is written until confirmed, that up to ~200 institutions can match a picker, that choices come back in 'choices', and that coauthors/keywords must be completed on the website. This is exactly the behavioral context annotations (destructiveHint) cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then confirmation flows, then section payloads – a logical order. It is dense and runs long as a single block with some very long sentences, but essentially every clause adds actionable information, so little is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, yet the description supplies the return contract (status 'needs_confirmation', 'choices'). Combined with the confirmation semantics and per-section payload rules for a 21-value section enum, an agent has enough to invoke this correctly without further probing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 60% and the key 'data' param is an unconstrained additionalProperties object, so the description carries real burden. It enumerates the per-section field requirements and the catalogue-id keys (revistaId, libroId, editorialId, programaId, areaId, institucionId) that the schema cannot express, plus the 2 MiB PDF constraint.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Apply a single change to a CvLAC section') and immediately scopes it with the screenshot confirmation behavior. An agent can tell this is the write/mutation tool versus the read siblings (read_cvlac, read_portfolio) and the higher-level sync/complete_product tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives rich when-to-use detail for each action and section (add/update/delete, plus per-section required fields), and explains how to resolve confirmation states. It never names an alternative sibling or states when NOT to use this tool (e.g., versus complete_product or sync), so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 1 tool updatev1.0.7
    • Changedupdate_profile2 fields changed
      • addedInput schema / properties / networks / items / properties / url / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / networks / items / properties / url / type
        Removed value: -[
        -  "string",
        -  "null"
        -]
  2. 13 tool updatesv1.0.6
    • First observedcomplete_product
    • First observeddiff
    • First observedinspect_form
    • First observedlogin
    • First observedlookup_doi
    • First observedread_cvlac
    • First observedread_cvlac_detail
    • First observedread_portfolio
    • First observedread_profile
    • First observedscreenshot
    • First observedsync
    • First observedupdate_profile
    • First observedupdate_section

TDQS

A3.8/5.0

Scored across 13 tools

Disambiguation4/5

Most tools target distinct purposes (list read, detail read, profile read, diff, sync, section write), and descriptions draw clear boundaries. Some potential overlap exists between update_section, complete_product, and sync (all write to CvLAC), but the descriptions distinguish their roles adequately.

Naming Consistency4/5

The dominant pattern is verb_noun (read_cvlac, read_portfolio, read_profile, update_section, update_profile, lookup_doi, complete_product, inspect_form). A few single-word verbs (login, sync, diff, screenshot) deviate, but overall it stays predictable and snake_case throughout.

Tool Count5/5

13 tools is well-scoped for a domain covering read/write/sync/lookup/debugging. Each tool earns its place with no obvious filler.

Completeness4/5

The surface covers reading (list, detail, profile), writing (section, profile, post-save completion), diff/sync lifecycle, DOI lookup, and debugging. Deletion is folded into update_section via confirm_delete rather than a dedicated tool, which is a minor but workable gap.

Related MCP Connectors

Related MCP Servers